How to use moment format in mixing? - vuejs2

In my laravel 5.7 / vuejs 2.5 app I use moment library to format datetime from db
It works in my component, but I have error when I try to wrap moment in my mixing as function with parameters.
package.json:
{
"private": true,
"devDependencies": {
"axios": "^0.18",
"vue": "^2.5.17"
...
},
"dependencies": {
"vue-moment": "^4.0.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
...
}
}
In resources/js/app.js :
import Vue from 'vue';
...
import moment from 'vue-moment'
Vue.use(moment)
In my component :
<template>
...
<hr>
<!-- THIS LINE WORKS OK-->
<span>{{ nextCategory.created_at | moment("dddd, MMMM Do YYYY") }}</span>;
<hr>
<!-- {{ momentDatetime(nextCategory.created_at,'Do MMMM, YYYY h:mm:ss A') }} -->
...
</template>
<script>
import {bus} from '../../app';
import appMixin from '../../appMixin';
export default {
name: 'list',
mixins: [appMixin],
</script>
But if to uncomment last line I got error
[Vue warn]: Error in render: "TypeError: __WEBPACK_IMPORTED_MODULE_0_vue_moment___default(...) is not a function"
and in resources/js/appMixin.js :
import moment from 'vue-moment'
export default {
methods: {
...
momentDatetime(datetime, datetime_format, default_val) {
return moment(datetime).format(datetime_format);
},
...
I found this decison with “.format” method in net, but looks like it is invalid.
Which is the right way ?
Thanks!

Maybe like the other answer, you have to use moment instead of vue-moment.
Also there's a problem with the latest version of moment and one of the solutions posted here was downgrading to moment 2.18.1, maybe vue-moment is using another version.
Check this post with the same error as your question:
https://github.com/moment/moment/issues/4229
Also they reference this other issue:
https://github.com/moment/moment/issues/4216

You are using vue-moment instead of moment, so in your package.json add moment by running in your terminal npm install moment or yarn add moment, and then in your package.json you should see moment dependency
Also change the import in the mixin to import moment from 'moment'

Related

TypeError: Cannot read properties of null (reading 'isCE') - Custom Component Library

I am having trouble building a custom component library for Vue 3 using ViteJS and NPM. I have included a basic illustration of my issue below, can someone please tell me what I am doing wrong or point me in the right direction, I have been stuck on this for 2 days :(.
My folder structure:
dist
node_modules
src
components
Paragraph.vue
paragraph.js
.gitignore
package.json
README.md
vite.config.js
package.json
{
"name": "paragraph",
"private": true,
"version": "0.0.0",
"description": "The paragraph test component.",
"main": "./dist/paragraph.umd.js",
"module": "./dist/paragraph.es.js",
"exports": {
".": {
"import": "./dist/paragraph.es.js",
"require": "./dist/paragraph.umd.js"
},
"./dist/style.css": "./dist/style.css"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.25"
},
"devDependencies": {
"#vitejs/plugin-vue": "^2.3.1",
"vite": "^2.9.5"
}
}
vite.config.js
import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: fileURLToPath(new URL('./src/paragraph.js', import.meta.url)),
name: 'Paragraph',
fileName: (format) => `paragraph.${format}.js`,
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
},
},
},
},
plugins: [vue()],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
paragraph.js
import Paragraph from './components/Paragraph.vue';
export default {
install: (app) => {
app.component('Paragraph', Paragraph);
},
};
Paragraph.vue
<script setup>
console.log('Test');
</script>
<template>
<p class="paragraph">
<slot />
</p>
</template>
<style>
.paragraph
{
color: black;
}
</style>
When I run npm run build it works successfully and creates the correct files, I then include the es file into my test Vue project as a plugin.
import { createApp } from 'vue'
import App from './App.vue'
import Paragraph from '../../paragraph/dist/paragraph.es.js'
createApp(App).use(Paragraph).mount('#app')
The component doesn't work when used liked this.
<Paragraph>Hello World 2!</Paragraph>
The following error is reported back in the console.
TypeError: Cannot read properties of null (reading 'isCE')
I have looked into the issue and it seems a lot of people have had the same issue, although I cannot find a fix for myself.
I have tried the solutions mentioned in the following links:
https://github.com/vuejs/core/issues/4344
When Importing Self Made Vue 3 Library Into Vue 3 Project: "Uncaught TypeError: Cannot read properties of null (reading 'isCE')"
Neither of the solutions mentioned here are working.
Can someone please help!!!
I have noticed if I exclude the <slot /> it works fine, but slots are vital to components.
I know it is bundling the Vue code into the build file, but how do I stop it doing so.
Thanks in advance.
I've also encountered this very frustrating issue. According to this answer, it is caused by having Vue imported from multiple packages instead of using just one singleton, as you do suspect.
Presumably, you are building your consumer application using Vite. In that case, setting the dedupe option in its vite.confg.js should solve it.
resolve: {
dedupe: [
'vue'
]
},
I've also encountered this issue :) the problem is you have two distinct copies of the Vue package being used
just read this and you will find your answer. for me, changing the workspace to yarn was the solution.
https://github.com/vuejs/core/issues/4344
Try to remove node_modules + yarn.lock
And then reinstall packages (yarn)

Vue 3 grid not working any more, what am I doing wrong?

This question was first asked on vuejs forum but didn't receive an answer (I know it's holidays seasons :)
I’m driving nuts with grids in vue3. It used to work some weeks ago but after some changes in the versions of the packages, I can’t get it working anymore (not sure it’s linked though). I created a small reproducer:
Package.json contains:
{
"name": "test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve"
},
"dependencies": {
"vue": "3.2.26",
"vue-class-component": "8.0.0-rc.1",
"vue-router": "4.0.12",
"primeflex": "^3.1.0",
"primeicons": "^5.0.0",
"primevue": "^3.9.1"
},
"devDependencies": {
"#types/node": "17.0.0",
"#vue/cli-plugin-babel": "4.5.15",
"#vue/cli-plugin-router": "4.5.15",
"#vue/cli-plugin-typescript": "4.5.15",
"#vue/cli-service": "4.5.15",
"typescript": "4.5.4"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
src/main.ts contains:
import { createApp } from "vue";
import MyApp from "./App.vue";
import PrimeVue from "primevue/config";
import "primevue/resources/themes/saga-blue/theme.css";
import "primevue/resources/primevue.min.css";
import "primeicons/primeicons.css";
import "primeflex/primeflex.min.css";
createApp(MyApp)
.use(PrimeVue)
.mount("#app");
and src/App.vue contains basically a copy of the example named “Vertical Layout with Grid” using the vuue 3 syntax with vue-class-component:
<template>
<h2>test</h2>
<div class="p-fluid p-formgrid p-grid">
<div class="p-field p-col">
<label for="firstname">Firstname</label>
<InputText id="firstname" type="text" />
</div>
<div class="p-field p-col">
<label for="lastname">Lastname</label>
<InputText id="lastname" type="text" />
</div>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import InputText from "primevue/inputtext";
#Options({
components: {
InputText,
},
})
export default class MyApp extends Vue {}
</script>
This should display something like this:
But it actually shows (using Firefox):
and I’m totally unable to get both fields side by side…
Can someone please point me in the right direction?
Thank you!
[1]: https://i.stack.imgur.com/44P2h.png
[2]: https://i.stack.imgur.com/75nZk.png
#BenSouchet Thanks for your comment, you pushed me to the right track.
Precisely, I first looked only at p-fluid which I was able to find in the CSS but after your comment I looked closer and I found I was unable to find p-formgrid, p-grid, or p-field in the page nor in the node_modules directory.
Running grep -R 'p-grid' node_modules/prime* does not return anything...
So, I looked twice at https://www.primefaces.org/primeflex/migration and discovered that with primeflex 3, all classes named p-xxx are now named xxx (eg p-formgrid becomes formgrid) so I changed the classes in the template above and it's now working fine again...
Now, the next question is why such a breaking change??? I need to pass through my whole application to fix that :/

Ionic Vue: VueJsPaginate not showing

I am developing an app which has a list of objects that I want to paginate. I found vuejs-paginate plugin but I can't make it work in my view.
After installing it via npm and importing in the view, its tag is in fact in the HTML skeleton of the page, but it shows nothing. No error is displayed in the console either, only this Vue warning:
[Vue warn]: Failed to resolve component: paginate
Might it be a problem with the import? Could you help me?
I attach part of my code so you can see how I've declared it.
<template>
<ion-page>
<ion-content>
<paginate
:pageCount="10"
:containerClass="'pagination'"
:clickHandler="clickCallback"
>
</paginate>
</ion-content>
</ion-page>
</template>
<script>
import {
IonContent,
IonPage,
} from "#ionic/vue";
import { defineComponent } from "vue";
import { VuejsPaginate } from "vuejs-paginate";
export default defineComponent({
name: "Gestion",
components: {
'paginate': VuejsPaginate,
},
methods: {
clickCallback: function(page) {
console.log(page)
},
});
</script>
This has also happened to me when trying to import other "external" components. Could it be a problem related to Ionic?
Thank you in advance!

Loading mermaid in a vue component (webpack)

I am migrating a vue project that uses mermaid from CDN to webpack. I'm total new with it. I did npm install save mermaid on project folder.
If i load mermaid cdn as static js (in /public/index.html), it crashes for some graphs (shows bomb icon, says syntax error)
If in webpack, it shows nothing as mermaid graphs, but seems to load empty (inspecting generated html with browser tools). No console errors
<svg id="mermaidChart0" width="100%" xmlns="http://www.w3.org/2000/svg"><g><g class="output"><g class="clusters"></g><g class="edgePaths"></g><g class="edgeLabels"></g><g class="nodes"></g></g></g></svg>
Tried:
//package.json
...
"dependencies": {
"axios": "^0.21.0",
"core-js": "^3.6.5",
"mermaid": "^8.8.2",
and in the component.vue
<template>
...
<div class="mermaid m-5">
graph LR
B(dsfgdsfgsd <br>) --> Bo(gdfshfghfdh <br>)
...
<script>
import mermaid from 'mermaid'
export default {
data: function() {
return {}
},
mounted() {
this.init();
},
methods: {
init: function() {
mermaid.initialize({
theme: 'forest',
htmlLabels: true,
//startOnLoad: true
});
console.log(mermaid);
mermaid.init(undefined, document.querySelectorAll('.mermaid'));
}
}
}
If you want a ready-to-use solution, you can use my component vue-mermaid-string. It does the internal work for you.
Install it via NPM, then add it to your project via CDN script or by adding the component, then use it like so:
<template>
<vue-mermaid-string :value="diagram" />
</template>
<script>
export default {
computed: {
diagram: () => 'graph TD\n A --> B',
},
}
</script>

Failed to mount component: template or render function not defined. (Vue using plugins)

I'm trying to use this countdown-timer / on-github inside one of my single-file-components.
Even though I'm importing it like mentioned in the example, I'm getting this error:
21:27:20.553 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <CircularCountDownTimer>
<Visualization> at src/views/Visualization.vue
<App> at src/App.vue
<Root> vue.runtime.esm.js:619
VueJS 17
run es6.promise.js:75
notify es6.promise.js:92
flush _microtask.js:18
Looking up the warning I've found the following pages:
vue-router-problem1
vue-router-problem2
What I've gathered/attempted from that:
Change vue-cli config to use runtime compiler (No change)
22:02:49.722 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <CircularCountDownTimer>
<Visualization> at src/views/Visualization.vue
<App> at src/App.vue
<Root> vue.esm.js:628
VueJS 18
run es6.promise.js:75
notify es6.promise.js:92
flush _microtask.js:18
Import in Main.js with Vue.use(Plugin) (Same error)
Import it in the router component (Same error)
EDIT:
I've also looked at this question nested-components in vuejs
And changed the component registration like so:
beforeCreate() {
this.$options.components.CircularCountDownTimer = require('vue-circular-count-down-timer')
},
None of the above made this plugin work for me and I don't really understand why.
Here is my code:
main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import CircularCountDownTimer from "vue-circular-count-down-timer";
Vue.use(CircularCountDownTimer)
Vue.config.productionTip = false;
export const eventBus = new Vue();
new Vue({
router,
render: h => h(App)
}).$mount("#app");
component (Visualization.vue):
<template>
<div id="content">
<circular-count-down-timer
v-for="counter in counters" :key="counter.id"
:initial-value="counter.seconds"
:show-minute="false"
:show-hour="false"
:show-negatives="false"
:second-label="counter.name"
:steps="1"
/>
</div>
</template>
<script>
import CircularCountDownTimer from "vue-circular-count-down-timer";
export default {
name: "Visualization",
components: {
CircularCountDownTimer
},
data() {
return {
counters: []
}
},
mounted() {
if (localStorage.getItem("delays")) {
try {
this.counters = JSON.parse(localStorage.getItem("delays"));
} catch (e) {
console.debug(e);
localStorage.removeItem("delays");
}
}
}
};
</script>
Also this is the data when reading from localStorage:
[{"id":1,"seconds":"60","name":"asdf"}]
Dependencies in package.json:
"dependencies": {
"#babel/preset-env": "^7.5.4",
"core-js": "^2.6.5",
"vue": "^2.6.10",
"vue-awesome-countdown": "^1.0.16",
"vue-circular-count-down-timer": "^1.0.4",
"vue-grid-layout": "^2.3.4",
"vue-router": "^3.0.3"
}
vue-circular-count-down-timer is a plugin, so this bit of the code seems to be correct:
import CircularCountDownTimer from "vue-circular-count-down-timer";
Vue.use(CircularCountDownTimer)
If you take a look at the source code for the plugin you'll see that all it does is register a component globally called circular-count-down-timer:
https://github.com/noorzaie/vue-circular-count-down-timer/blob/master/src/components/index.js
The problem occurs when you do this:
import CircularCountDownTimer from "vue-circular-count-down-timer";
export default {
name: "Visualization",
components: {
CircularCountDownTimer
},
You're just importing the plugin again and then trying to use it as a component. But it isn't a component, it's a plugin. Vue doesn't know this, it just sees an object without a template or render function.
Get rid of the local component import and it should just use the globally registered component instead.