How do I create and instantiate a store using VueX called via cdn? - vue.js

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>

Related

VUE cannot update variable when API response

I want to update {{info}} value when the API is response.
But I don't know why there could be console log the response but cannot update the variable.
Any mistake I have make?
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue#next"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{info}}</p>
</div>
</body>
</html>
<script>
const { reactive,createApp, ref } = Vue;
const app = {
setup(){
info="waiting......";
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
.then(response => (console.log(response)));
return {info};
}
}
const myVue = Vue.createApp(app).mount("#app");
</script>
here is a working example. If you want to use the composition API you have to make info a reactive variable with ref or reactive.
in this case you have to assign the new data to your reactive variable with the .value notation: info.value = data
composition API
const { createApp, onMounted, ref } = Vue;
const app = createApp({
setup() {
let info = ref('warning...')
onMounted(() => {
fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => response.json())
.then(data => {
info.value = data
});
})
return {
info
}
}
});
app.mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<p>{{info}}</p>
</div>
options API
Vue.createApp({
data() {
return {
info: 'warning...'
}
},
mounted() {
fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => response.json())
.then(data => {
this.info = data
});
}
}).mount('#options-api')
<script src="https://unpkg.com/vue#next"></script>
<div id="options-api">
<p>{{ info }}</p>
</div>
console log the response but cannot update the variable
you have mixed the style from the composition API with the options API.
your code this.info = response will work with the options API (see my second example.) if you want to use the composition API you have to write info.value = response (see my first example).
note: I use the mounted hook only for demonstration purposes.
one of workaround, using vue 2........
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{info}}</p>
</div>
</body>
</html>
<script>
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
}
})
</script>
I think you need to declare a reactive variable via "reactive" in Vue3.
such as:
enter code hereconst app = {
setup(){
// if your request return a value. otherwise, use as below
// let info = reactive({});
let info = ref("waiting......");
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
.then(response => (console.log(response)));
return {info};
}
}
As described in the composition API documentation, you need to use ref.
I.e. your code should be
const info=ref("waiting......");
Otherwise, it is just a normal JavaScript variable, and the "reactive magic" of Vue which re-renders the view does not kick in when you change the value. Please note that in some contexts, Vue does automatically make objects reactive, e. g. for data and props when you use the normal components syntax. But for teh composition API, you have to take care of that yourself.

[Vue warn]: Failed to mount component: template or render function not defined, using Laravel 8

I'm trying to create a new project but I'm getting this error and I don't know why. I'm using Laravel 8, Vue and Inertia.js.
I'm not sure if these files are important but I'll add anyways
webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
mix.js('resources/js/app.js', 'public/js').vue({ version: 2 })
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'#': path.resolve('resources/js'),
},
},
})
.babelConfig({
plugins: ['#babel/plugin-syntax-dynamic-import'],
})
.version();
app.js
import InertiaApp from '#inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp);
const app = document.getElementById('app');
app.setAttribute(':class',"{'loaded': loaded}");
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => import(`#/Pages/${name}`).then(module => module.default),
},
data(){
return{
loaded:true
}
}
}),
}).$mount(app);
app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
#inertia
</body>
</html>
Finally the page I'm trying to show Login.vue
<template>
<div>
<h1>Login</h1>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
console.log('mounted');
}
}
</script>
I don't know why this is happening or how to fix it.
What am I doing wrong?

Vuejs Reactive propery interpolation is not working

I've run into an issue where i'm creating components that are then being applied to the root App - after creating a dynamic child w/ vanilla JS. When i look at the Vue object in the console, message is not present, which i expect it to be - Can anyone tell me why?
Create the App
Dynamically add new DOM element w/ createElement with a {{ message }} property (ex: <div id="test">{{message}}</div>)
Create a custom component using Vue.Component (ex: <custom-component><custom-component> w/ pre-populated {{ messsage }} value test message
Render the Vue w/ the component w/ update props values for {{ message }}
Below is the actual code tested:
import Vue from 'vue/dist/vue.js';
export default {
name: 'app',
components:
{
HelloWorld
},
data()
{
return this;
},
mounted()
{
// #2 Create an Html Target that contains the component's name 'custom-element'
var v = document.createElement('div');
v.setAttribute('id', 'test');
v.innerHTML = '<custom-element></custom-element>';
var $element = this.$el.prepend(v);
// #1 Create a component
var MyComponent = Vue.component(
'custom-element',
{
template: '<div v-bind:id="UID">{{message}}</div>',
prop: ['UUID', 'message'],
data() {
return {
UID: '',
message: 'test message',
}
},
}
);
// #3 Append the component to the Html Target
window.vm = new Vue({
el: '#test',
components: {
'custom-component': MyComponent,
},
beforeCreate() {
return {
UID: 'x7x7x',
message: 'test message update...'
}
},
})
window.console.log(MyComponent);
window.console.log(this);
}
}`
Here's the main index.html:
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>hello-world</title>
</head>
<body>
<noscript>
<strong>We're sorry but hello-world doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>'
Here's the main.js
'use strict'
import Vue from 'vue'
import App from './App.vue'
import Reaktr from './js/reaktr.js'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
data: {
Reaktr: new Reaktr(),
},
mounted() {
}
}).$mount('#app')
Here's the Helloworld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>

Vue - Import components in a multi-page environment

I wish to use Vue.js in a multi-page environment. For this project I can't use webpack or the vue.cli. I have to use basic ways of importing the various libraries and then using them. I'm nearly there but I can't figure out how I can import components. I'm assuming I need to use require.js but I don't know enough to proceed.
This is the main component (index.html):
<!DOCTYPE html>
<html lang='en' class=''>
<head>
<meta charset='UTF-8'><meta name="robots" content="noindex">
<title>Hello</title>
</head><body>
<div id="app">
<p>Hello this is the {{results}} app</p>
<br /><br />
<p>Now it's time for a component to be shown:</p>
<app-my-accordion></app-my-accordion>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js'></script>
<script src='require.js'></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
import MyAccordion from 'components/my-accordion.html'; // <--Problem here
new Vue({
el: '#app',
components: {
'app-my-accordion': MyAccordion
},
data() {
return {
results: null
}
},
mounted() {
axios.get("http://myApi")
.then(response => { this.results = response.data.name; console.log(response.data.name); })
}
});
</script>
</body></html>
And then in my my-accordion.html
<template>
<div>And my child's component name is: {{results}}</div>
</template>
<script>
export default {
data() {
return {
results: null
}
},
mounted: function () {
axios.get("http://myOtherApi")
.then(response => { this.results = response.data.name; console.log(response.data.name); })
}
}
</script>
</body></html>

Vue.js component issue

js i'm starting to catch up on it but i'm stuck on components would appreciate your help thanks
//here is my js
Vue.component('thatsCool', {
template: document.querySelector('#myOwnTemplate'),
data: function() {
return {
helloWorld: 'thats cool',
};
},
});
new Vue({
el: 'body',
});
//and this is my html
<! DOCTYPE html>
<html>
<head>
<title>playing with Vue components</title>
</head>
<body>
<thatsCool></thatsCool>
<script id="myOwnTemplate" type="x/template">
<p v-text="helloWorld"></p>
</script>
<script src="vue.js"></script>
<script src="component.js"></script>
</body>
</html>
There are a couple of errors in your code. Use dash-separated convention for your components and simple handlebar notation for string output. Try with this code:
HTML
<thats-cool></thats-cool>
<script id="myOwnTemplate" type="x-template">
<p>{{ helloWorld }}</p>
</script>
JS
Vue.component('thats-cool', {
template: '#myOwnTemplate',
replace : true,
data: function() {
return {
helloWorld: 'thats cool',
};
}
});
Note that the option 'replace : true' replaces the original template's content of el instead of appending to it.