Similar to this question here I'm trying to pass socket.io-client data to a Vue.js component but it's not displaying on the page -- though it writes to console.log just fine. My data is JSON (his was an array) so the solution in the link above doesn't seem to work.
The error I'm getting is:
[Vue warn]: Property or method "items" is not defined on the instance but referenced during render.
main.js
import Vue from 'vue'
import App from './App'
import io from 'socket.io-client'
Vue.config.productionTip = false
var socket = io.connect('http://localhost:3000')
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>',
data: {
items: []
},
mounted: function () {
socket.on('connect', function () {
socket.on('message', function (message) {
console.log(message)
this.items = message.content
}.bind(this))
socket.emit('subscribe', 'mu')
})
}
})
App.vue
<template>
<div id="app">
<h1>client</h1>
<div v-for="item in items" class="card">
<div class="card-block">
<h4 class="card-title">Symbol: {{ item.symbol }}</h4>
<p class="card-text">Updated: {{ item.lastUpdated }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
sample data
{
"symbol":"MU",
"lastUpdated":1520283600000
}
Any help would be greatly appreciated. Thanks.
the data attribute in your vue instance needs to be a function which returns something, your items array for instance. so instead of
data: {
items: []
},
you should re-write as
data () {
return {
items: []
}
},
Related
I have had problems where I am getting a null value from my store... sometimes, and only on some values. If anyone could point me in the right direction and explain why it is wrong... I would be really grateful. So here is the deal my store.getters.getApiKey is sometimes "" and sometimes not.
So... in the component vue below, it is not null on the first reference
{{this.$store.getters.getApiKey}}
and then within the mounted section, store.getters.getHostUrl is set, but store.getters.getApiKey keeps returning "".
Here are the details:
the Component.vue
<template>
<div class="countryCodes">
<p>ApiKey : {{this.$store.getters.getApiKey}}</p>
<p>CountryCode Data is {{ page }}</p>
<div class="CountryCodes">
<tr v-for="ccdata in content_list" v-bind:key="ccdata.guid">
<td>{{ ccdata.guid }}</td>
<td>{{ ccdata.name }}</td>
<td>{{ ccdata.code }}</td>
</tr>
</div>
</div>
</template>
import axios from "axios";
import store from "#/store";
export default {
name: 'CountryCodes',
data () {
return {
page: "",
content_list: []
}
},
mounted () {
axios({ method: "GET", "url": store.getters.getHostUrl + "
"/api/"+store.getters.getApiKey+"/countryCodes" }).then(result => {
this.page = result.data.page;
this.content_list = result.data.contents;
}, error => {
console.error(error);
});
},
methods: {
}
}
</script>
Then my store (store.js) looks like this...
import Vuex from "vuex";
import Vue from 'vue';
Vue.use(Vuex)
export default new Vuex.Store({
state: {
apiKey: "",
hostUrl:""
},
mutations: {
SET_APIKEY(state, value) { state.apiKey = value; },
SET_HOST_URL(state, value) {state.hostUrl = value; }
},
getters: {
getApiKey(state) { return state.apiKey; },
getHostUrl(state) { return state.hostUrl; }
}
})
finally in my main.js I commit the data to the store... :
import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
import store from './store.js'
new Vue({
el: '#app',
render: h => h(App),
router,
store,
mounted: function() {
console.log(this.$route.query)
store.commit('SET_APIKEY', this.$route.query.api)
store.commit("SET_HOST_URL", location.origin.toString())
}
})
I have the same problem when trying to build a http service, where the store is null for the apikey. What magic am I missing?
Usually the mounted hook of child component is called before the mounted of parent component.
From Vue Parent and Child lifecycle hooks
If you try to console.log on both mounted hook you will see the order of execution (but I'm still not sure why your store.getters.getHostUrl is set).
So you need a watcher to run your code after your store has value.
Example code:
...
computed: { // or use another getters
url () {
if (!store.getters.getHostUrl || !store.getters.getApiKey) return
return `${store.getters.getHostUrl}/api/${store.getters.getApiKey}/countryCodes`
}
},
watch: {
url (value) {
...
}
}
...
CodeSandbox
So.... there were two ways of solving this..... thank you to both comments.
Switch my mounted in the main.js to created- the diagram above explains why... as well as the nice article.
add "await store.getters.getApiKey"
I just can't find a way to pass my data from vue.js component to blade view in my Laravel project. I tried to use hidden inputfield but data binding returns [object Object].
Any help would be appreciated.
Create a variable in the root component data object and change it from the child component so assuming resources/js/components/ExampleComponent.vue like this
<template>
<div class="container">
<input v-model="field" type="text">
</div>
</template>
<script>
export default {
data() {
return {
field: ''
}
},
watch: {
field: function (val) {
this.$root.bladeValue = val;
}
}
}
</script>
and a resources/js/app.js like so
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app',
data() {
return {
bladeValue: ''
}
}
});
and a blade view like so resources/views/welcome.blade.php
<div id="app">
<example-component></example-component>
<h1>#{{ bladeValue }}</h1>
</div>
<script src="/js/app.js"></script>
Then bladeValue will be binded to field in ExampleComponent
I'm working in Laravel. What I want to do is to get the posts from the server and show them in view, however before that I wanted to set static array containing sample posts but my problem is that I can't access posts variable in app.js file when passing by data(){...} and receiving by props: ['posts']. When I even console.log(this.posts) in app.js file it returns undefined. I'm confused what the problem is:
My resources/js/app.js file:
window.Vue = require('vue');
window.App = require('./App.vue');
window.addEventListener('load', function ()
{
const app = new Vue({
el: '#app',
render: h => h(App)
});
});
My resources/js/App.vue file:
<template>
<div>
<app-head></app-head>
<app-post v-for="post in posts" :key="post.id"></app-post>
<app-foot></app-foot>
</div>
</template>
<script>
import Head from './components/Head.vue';
import Foot from './components/Foot.vue';
import Post from './components/Post.vue';
export default {
props: ['posts'],
components: {
'app-head': Head,
'app-post': Post,
'app-foot': Foot,
}
}
</script>
My resources/js/components/Post.vue file:
<template>
<div class="post">
// The post content...
</div>
</template>
<script>
export default {
data() {
return {
posts: [
{id: 1, title: 'Hello :)'}
]
}
}
}
</script>
Few alterations are required.
App.vue
<template>
<div>
<app-head></app-head>
<app-post :posts="posts"></app-post>
<app-foot></app-foot>
</div>
</template>
<script>
import Head from './components/Head.vue';
import Foot from './components/Foot.vue';
import Post from './components/Post.vue';
export default {
components: {
'app-head': Head,
'app-post': Post,
'app-foot': Foot,
},
data() {
return {
posts: [
{id: 1, title: 'Hello :)'}
]
}
}
}
</script>
If you need to prop the posts list to the component then it has to come from here. Hence, notice data is modified (or inserted).
Post.vue
<template>
<div class="post" v-for="post in posts" :key="post.id">
// The post content...
</div>
</template>
<script>
export default {
props: ['posts']
}
</script>
Notice that v-for should be in the post component.
Let me know if that works for you.
You should use props in your component(Post) the receive the data from parent component(App).
I'm trying to use vue-async-data to fetch data asynchronously before rendering my Vue component, but I'm having no success. I'm not getting any erros, but it simply doesn't work.
Here's my main.js code:
import Vue from 'vue'
import VueAsyncData from 'vue-async-data'
import router from './router'
import App from './App.vue'
Vue.use(VueAsyncData)
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
And here's my App.vue code:
<template>
<div>
{{ msg }}
<navigation wait-for="async-data"></navigation>
</div>
</template>
<script>
import Navigation from './components/Navigation.vue'
export default {
name: 'app',
components: {
Navigation
},
data: function() {
return {
msg: 'not loaded yet...'
}
},
asyncData: function (resolve, reject) {
// load data and call resolve(data)
// or call reject(reason) if something goes wrong
setTimeout(function () {
// this will call `vm.$set('msg', 'hi')` for you
resolve({
msg: 'hi'
})
}, 1000)
}
}
</script>
The msg value doesn't change at any moment, but the component is still rendered.
Am I missing somenthing?
As Bert Evans stated, vue-async-data doesn't work with Vue 2.0.
I used vue-router and the created function to achieve what I needed (as suggested in: https://router.vuejs.org/en/advanced/data-fetching.html.
<template>
<div>
<div class="loading" v-if="loading">
Loading...
</div>
<div v-if="error" class="error">
{{ error }}
</div>
<navigation v-if="currentUser"></navigation>
</div>
</template>
<script>
import Navigation from './components/Navigation.vue'
export default {
name: 'app',
components: {
Navigation
},
data: function() {
return {
loading: true,
error: false,
currentUser: null
}
},
created: function() {
this.fetchUserData()
},
methods: {
fetchUserData: function() {
this.$http.get('/Account/CurrentUserInfo').then(data => {
this.currentUser = data
this.loading = false
}, response => {
this.loading = false
this.error = true
});
}
}
}
</script>
I am using Vuejs 2 (webpack-simple template) and I would like to know how can I compile template before render it. Below my code :
App.vue
<template>
<div id="app">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
main.js
import Vue from 'vue'
import App from './App.vue'
const res = Vue.compile(App)
const vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
render: res.render,
staticRenderFns: res.staticRenderFns
})
And these is the error that I've got when I start the server: __WEBPACK_IMPORTED_MODULE_0_vue___default.a.compile is not a function
I also tried this plugin vue-template-compiler with no luck. Can you please help me to make it work ? Thanks in advance.
You will need this setting in webpack's config:
resolve: {
alias: {
'vue$': 'vue/dist/vue'
}
}
despite on this problem: http://vuejs.org/guide/installation.html#Standalone-vs-Runtime-only-Build