Pinia Stores not running as expected on my desktop but run fine on my laptop - vuejs2

I work with a team that use Pinia for state management across a Vue ( & vuetify ) application, everything works fine on their machines and on my laptop. However, when I am using my desktop pinia doesn't seem to work and I am certain that I've set up the application the same way on both devices,I've even re-setup the env on my desktop multiple times.
When I load an application on my laptop I see 🍍 "currentUser" store installed 🆕 and I am able to access it as expected with no issues, the Pinia tab appears in my Vue devtools too.
When I load the application on my desktop I do not see a 'store installed' prompt and everything is passed as a ref __v_isRef: true but the Pinia tab still appears in my Vue devtools...
If I console.log() a value in the store I get the response I'd expect but, when I console.log() a variable in the store on my desktop I get the following:
{
value: false,
__V_isRef: true,
get value: function value(){},
set value: function value(){},
}
Now for another spanner, the code below works perfectly fine if I run it in something like codepen leading me to think its something with node / vue / vuetify, how could I check if it is?
const useCounterStore = Pinia.defineStore('counter', {
state() {
return {
value: 0
}
},
actions: {
increment(state) {
this.value++
},
}
})
Vue.use(Pinia.PiniaVuePlugin)
new Vue({
el: '#app',
vuetify: new Vuetify(),
pinia: Pinia.createPinia(),
computed: {
...Pinia.mapState(useCounterStore, ['value'])
},
methods: {
...Pinia.mapActions(useCounterStore, ['increment', 'incrementBugged'])
},
})
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>Count is: {{ value }}</v-container>
<button #click="increment">Click here, works on both my desktop and laptop</button>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script src="https://unpkg.com/#vue/composition-api"></script>
<script src="https://unpkg.com/vue-demi"></script>
<script src="https://unpkg.com/pinia"></script>
</body>
</html>
Please LMK if you need any additional information :)

Related

How do I create and instantiate a store using VueX called via cdn?

I'm working on a project that's php/vuejs. There's no npm nor yarn nor any tool to install packages so the team members always add the cdn link to everything they need. In this case I need to add Vuex + vuex-persistedstate but I don't get to see how to initiate it and instantiate it... litterally no idea. If somebody could show me where I can find this information or post it here as an answer I will be more than thankful.
I tried this and it didn't work:
vueInstance.js
const app = new Vue({
el: '#app',
store: store,
...
footer.php
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/vuex-persistedstate/dist/vuex-persistedstate.umd.js"></script>
<script> Vue.use(Vuex)</script>
store.js
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
i made an example how use cdn and vuex + vuex-persist (a simple counter app)
when you change the count you can see your browser localStorage for see changes
and i hope this help you :)
important note:
only use vuex-persist v2.2.0 the latest version (v3.1.3) have problem and show error message in browser.
you can see it also in codepen: https://codepen.io/Mohamadmasoudi/pen/KKaZMOo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vuex - VuexPersist example</title>
</head>
<body>
<div id="app">
count is: {{count}}
<button #click="increment">+</button>
<button #click="decrement">-</button>
</div>
<script src="https://vuejs.org/js/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex-persist#2.2.0"></script>
<script src="https://unpkg.com/vuex#3.6.2/dist/vuex.js"></script>
<script>
const vuexLocal = new window.VuexPersistence.VuexPersistence({
storage: window.localStorage,
});
const store = new Vuex.Store({
state: { count: 0 },
mutations: {
increment (state) {
state.count++
},
decrement (state) {
state.count--
}
},
actions: { },
plugins: [vuexLocal.plugin]
});
vm = new Vue({
el: "#app",
store: store,
methods: {
increment(){
store.commit('increment');
},
decrement(){
store.commit('decrement');
}
},
computed: {
count(){
return store.state.count
}
}
});
</script>
</body>
</html>

bulma-calendar not updating as Vue.js component

I am learning Vue.js and would like to implement the bulma-calendar module in my app. I came this far, but the calendar is somehow not updating, when I am selecting a new Date.
Sorry if I can't specify the problem more, as I said declarative programming is very new to me.
The template I got from the official website of bulma-calendar: https://demo.creativebulma.net/components/calendar/v6//#integration
Vue.component("comp-calendar", {
template: `
<div>
<input ref="calendarTrigger" type="date">
</div>
`,
data: function () {
return {
date: new Date(),
};
},
mounted: function () {
const options = {
type: "date",
color: "danger",
dateFormat: "DD-MM-YYYY",
startDate: this.date,
displayMode: "inline",
};
const calendar = bulmaCalendar.attach(
this.$refs.calendarTrigger,
options
)[0];
calendar.on("date:selected", (e) => (this.date = e.date));
},
});
var app = new Vue({
el: "#app",
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- import bulma -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma#0.9.1/css/bulma.min.css">
<!-- import bulma-calendar -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-calendar#6.0.9/dist/css/bulma-calendar.min.css">
</head>
<body>
<div id="app">
<comp-calendar></comp-calendar>
</div>
<!-- import bulma-calendar -->
<script src="https://cdn.jsdelivr.net/npm/bulma-calendar#6.0.9/dist/js/bulma-calendar.min.js"></script>
<!-- import https://vuejs.org -->
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
<script src="src/js/test.js"></script>
</body>
Any help? Thanks
EDIT: Did not help:
[...]
<input type="date">
[...]
const calendar = bulmaCalendar.attach('[type="date"]', options)[0];
calendar.on("select", (e) => (this.date = e.date))
Probably a bug in 6.0.9. Working with 6.0.0 (according to documentation here: https://creativebulma.net/product/calendar/demo) worked fine.
calendar.on("select", (e) => (this.date = e.date))
here this.date is incorect. this "this" is calendar object not the vue object

How can I use Vue2 old component (.vue file) with a new Vue3 project?

Vue3 version is out, but I don't see any example of using old components code with the new version. How come?
Here is my index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue 3 Example using Vue 2 component</title>
<script src="https://unpkg.com/vue#next"></script>
</head>
<body>
<div id="app">
<h1>{{ product }}</h1>
<my-old-vue-component :my-prop="'my string in here'"></my-old-vue-component>
</div>
<script src="./main.js"></script>
<script src="./myOldVueComponent.vue"></script>
<!-- Mount App -->
<script>
const mountedApp = app.mount('#app')
</script>
</body>
</html>
Here is my main.js:
const app = Vue.createApp({
data() {
return {
product: 'my product',
}
}
})
Here is my old simple Vue2 component (myOldVueComponent.vue):
<template>
<div>
{{myProp}}
</div>
</template>
<script>
export default {
name: "myOldVueComponent",
props: {
myProp: { type: String }
},
data() {
return {
},
}
</script>
I'm getting error on the import of ".vue" file:
uncaught SyntaxError:
Unexpected token '<'
(meaning the <template> tag inside my old component.
Vue2 components works in Vue3. That is not the issue in your code.
The problem is here:
<script src="./myOldVueComponent.vue"></script>
You can't import .vue files directly in a browser. You could not do it in vue 1,2 and you can't yet in vue 3. The browser is not able to understand that syntax, there needs to be a bundler that converts your code is something that can be used by the browser. The most popular bundlers are webpack, rollup ecc ecc
See: https://v3.vuejs.org/guide/single-file-component.html#for-users-new-to-module-build-systems-in-javascript
I highly recommend using the Vue cli to setup your project, especially if you are a beginner to the npm/bundlers world

Laravel Mix Vue, Lazy loading component returns error as unknown custom element when using Vue Router

I have got a fresh install of Laravel Mix and I am trying to setup lazy loading components in the project. I have got the correct setup with the babel plugin 'syntax-dynamic-import' so the import statement in app.js works as expected. The issue occurs when I attempt to use the lazy loaded component with vue-router.
My app.js file looks like this:
require('./bootstrap');
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const EC = () => import(/* webpackChunkName: "example-component" */ './components/ExampleComponent.vue');
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: EC }
]
});
const app = new Vue({
router,
el: '#app'
});
and my welcome.blade.php file looks like this:
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<base href="/" />
</head>
<body>
<div id="app">
<h1>Base title</h1>
<example-component></example-component>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
So I just trying to land on the root route and display the Example Component. The example component is included in the welcome.blade.php file.
I am receiving this error in the console:
[Vue warn]: Unknown custom element: <example-component> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
(found in <Root>)
I think I am missing something simple, any advice is appreciated.
First, i think you are mixing routes concepts with core components vue concepts...
Try loading the component directly in your vue app...
const app = new Vue({
router,
el: '#app',
components: {
'example-component': () => import('./components/ExampleComponent.vue')
}
});
Component loading is done with <component>
<component v-bind:is="currentTabComponent"></component>
Check the docs, for more info on dynamic components: https://v2.vuejs.org/v2/guide/components-dynamic-async.html
#Erubiel answer did work but it still quite wasn't the setup I wanted. As I am trying to use vue-router I needed to update the view by removing the explicit call to the component and adding the tag in the welcome.blade.php file. This now means my routes are injected into that space. The updated area is:
...
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
...
The problem is in the scss splitting in Vue and using mix.scss() both. Laravel mix when having both creates a css file with manifest js file content in it. which is definitely a bug. which the community mentions a bug from Webpack and will be resolved in webpack 5. But If you use only code splitting in Vue and have the default app.scss file imported to main Vue component like this(not in scope), so each other component will get the styling properly
// resources/js/components/app.vue
<template>
<!-- Main Vue Component -->
</template>
<script>
// Main Script
</script>
<style lang="scss">
#import '~#/sass/app.scss';
</style>
and the webpack.mix.js file will have no mix.scss function to run only a single app.js file. here is my file.
// webpack.mix.js
const mix = require('laravel-mix')
mix.babelConfig({
plugins: ['#babel/plugin-syntax-dynamic-import'] // important to install -D
})
mix.config.webpackConfig.output = {
chunkFilename: 'js/[name].bundle.js',
publicPath: '/'
}
mix
.js('resources/js/app.js', 'public/js')
.extract(['vue'])
.webpackConfig({
resolve: {
alias: {
'#': path.resolve('resources/') // just to use relative path properly
}
}
})
Hope this solves everyone's question

How can I use one of my vue instances to be loaded in a separate html page

Currently my web application is loaded like this in index.html -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>tempo</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
</head>
<body>
<div id="app"></div>
</body>
</html>
and the ID of 'app' is my main vue instance (see below)-
var spa = new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App },
})
I am trying to have a second html page (live.html) that will hold the vue instance of -
var outer = new Vue({
el: '#outer',
router,
store,
template: '<Live/>',
components: { Live },
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>tempo</title>
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
</head>
<body>
<div id="outer"></div>
</body>
</html>
Both these vue instances are located in my main.js - But only the 'App' instance is being loaded, I i change my url to 'localhost:8080/live.html' nothing appears.
If I move the id="outer" to my index.html it will load, but my aim is to have it load on a separate html file so that its components can be displayed separately, but may be able able to communicate using vuex for the rest of the SPA.
Any pointers in the right direction is greatly appreciated and if any clarification is needed, please ask.
Here's what I had in mind:
const router = new VueRouter({
routes: [
{
path: '/livedisplay',
component: Live
},
{
path: '/',
component: Main,
children: [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
},
]
},
]
})
Your menu and navigation would be within the "Main" component