Vuejs: How to properly pass props to component data - javascript

i'm playing with Vue 2.0, but there is something unclear..
how can i pass the props to the internal data of a component?
Looking at the documentation it seems that i have done right.
HTML
<lista-servizi :servizi="modello"></lista-servizi>
the "modello" is a data already defined.
THE VUE COMPONENT
Vue.component('lista-servizi', {
template:
'<span class="blu">{{listaServizi.lineaGialla.descrizione}}</span>',
props: ['servizi'],
data: function(){
return{
listaServizi : this.servizi
}
basically i try to give to data listaServizi the same value as props servizi,
but in the console i have the following message:
[Vue warn]: Error in render function: "TypeError: Cannot read property 'descrizione' of undefined"
found in
---> <ListaServizi>
<Root>

You should used computed instead.
Vue.component('lista-servizi', {
//...
computed: {
listaServizi() {
return this.servizi
}
}
}

Most likely you have a problem with modello.
By defining the modello, your code works fine. Below is an example based on your code that works:
<div id="app-1">
<lista-servizi :servizi="modello"></lista-servizi>
</div>
Vue.component('lista-servizi', {
template: '<span class="blu">{{listaServizi.lineaGialla.descrizione}}</span>',
props: ['servizi'],
data: function(){
return{
listaServizi : this.servizi
}
}
})
var app1 = new Vue({
el: '#app-1',
data: {
modello: {
lineaGialla : {
descrizione : " This is a description"
}
}
}
})
Here is a link to a working bin
https://jsbin.com/qoloqoz/1/edit?html,js,output

Related

Vue.js undefined error on object value when loaded and rendered

OK. I'm not a total newbie and do have some Vue xp but this is bugging me. What really obvious thing am I missing.
I have an object loaded via an ajax call inside a mounted method:
job: {
"title": "value",
"location": {
"name":"HONG KONG"
}
}
When I call {{ job.title }} all good. When I call {{ job.location.name }} I have an undefined error but the value renders. When I call {{ job.location }} I get the json object so it is defined.
Aaargh! I'm sure it's really simple but can't possibly see why this isn't as straight forward as it should be.
// Additional
This is my entire Vue class
const router = new VueRouter({
mode: 'history',
routes: []
});
const app = new Vue( {
router,
el: '#app',
data: {
job: {}
},
mounted: function () {
var vm = this
jQuery.ajax({
url: 'https://xxx' + this.jobId,
method: 'GET',
success: function (data) {
vm.job = data;
},
error: function (error) {
console.log(error);
}
});
},
computed: {
jobId: function() {
return this.$route.query.gh_jid
}
}
})
When your component renders it tries to get value from job.location.name but location is undefined before ajax request is completed. So I guess error is kind of Cannot read property 'name' of undefined.
To fix this you can define computed property locationName and return, for example, empty string when there is no loaded job object yet:
computed:{
//...
locationName() {
return this.job.location ? this.job.location.name : '';
}
}
Or you can define computed for location and return empty object if there is no location, or you can just add empty location object to your initial data(if you are sure that your API response always has location) like job: { location: {}} all ways will fix your issue.
Also there is a way to fix it with v-if directive in your template:
<div v-if="job.location">
{{ job.location.name }}
<!-- other location related stuff -->
</div>
An ES6 solution for you:
computed: {
getJobName(){
return this.job?.location.name
}
}
Optional Chaining

How can I call method from data on vue.js?

My vue component like this :
<template>
<ul class="nav nav-tabs nav-tabs-bg">
<li v-for="tab in tabs" role="presentation" :class="setActive(tab.url)">
<a :href="baseUrl + tab.url">{{tab.title}}</a>
</li>
</ul>
</template>
<script>
export default {
props: ['shop'],
data() {
return{
tabs: [
{
title: 'product',
url: '/store/' + this.shop.id + '/' + strSlug(this.shop.name)
},
{
title: 'info',
url: '/store/' + this.shop.id + '/' + strSlug(this.shop.name) + '/info'
}
]
}
},
methods: {
setActive(pathname){
return {active: window.location.pathname == pathname}
},
strSlug: function(val) {
return _.kebabCase(val)
}
}
}
</script>
If the code run, there exist error like this :
[Vue warn]: Error in data(): "ReferenceError: strSlug is not defined"
If I console.log(window.location.pathname), the result like this :
/store/21/chelsea-hazard-store
So if it is the same as url with data in tabs, then it will active
I call the strSlug method to convert each into lowercase and convert spaces into -
Seems it can not call the method from the data
How can I solve the error?
If you have a function in data that will be used in a context of another object (like an event handler, for example), then this will not point to the Vue instance. You will have to preserve the reference in another variable from the scope of data():
methods: {
shuffle() {}
},
data() {
var self = this;
return {
onClick: function() {
self.shuffle()
}
}
}
When accessing data or methods from within the vue object, use this.thing. In your case, that would be this.strSlug(this.shop.name).
Does not work even with 'this.' because that function has not been defined at the time data is being initialized. I think you have to do it in the created() life-cycle hook.

How to use vue input mask plugin

I am trying to use this plugin in my app. I am trying to use the directive in my component like it is shown in the docs:
<input v-if="edit" type="text" v-mask="'999.999.999-99'">
But, I got:
Uncaught (in promise) TypeError: Cannot read property 'value' of
undefined
On, expecting in the console, I could see that this is where the error happens:
exports.default = {
bind: function bind(el, binding) {
var isMoney = false;
if (binding.value.length < 1) return; // this is where the error happens
var inputText = getInputText(el);
I am importing the plugin in my component like so:
import AwesomeMask from 'awesome-mask';
export default {
props: ['data'],
data () {
return {
player: this.data.data,
edit: false,
}
},
directives: {
'mask': AwesomeMask
}
}
What am I doing wrong?

Vue.js: access global value in template string

I have a very basic Vue.js app that looks like this:
index.html (just the <body> for succinctness)
<div id="root"></div>
main.js
var config = {
title: 'My App',
}
new Vue({
el: '#root',
template: '<div>{{ config.title }}</div>',
})
This gives me:
Property or method "config" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
(found in root instance)
I'm guessing it's because Vue is looking for it in the data store rather than window. Is there some way to signal that config is a global here, or a better way to do this entirely? I suppose I could pass the config object as a prop to my root Vue instance, but it seems like only components accept props. Thanks for any insights on this.
You can try to define your app as follows:
new Vue({
el: '#root',
template: '<div>{{ config.title }}</div>',
data: function() {
return {
config: window.config
}
}
})
In the above definition, your this.config within the root component points to window.config - the global variable.
If you are just trying to pass the App Name in as a hard-coded string you can do something like this:
var nameMyApp = new Vue({
el: '#root',
data: { input: 'My App' },
computed: {
whosapp: function () {
return this.input
}
}
})
With your html like this:
<div id="root">
<div v-html="whosapp"></div>
</div>
Which will pass the value of input to the whosapp div.
But, if you're looking for something more dynamic, this would be the way to go:
With the same html as above...
var nameMyApp = new Vue({
el: '#root',
data: { input: 'My App' },
The initial value is set to My App, which is what will display if not changed through a function call on the method.
methods: {
update: function(name) {
this.input = name;
}
},
Here is where we define a method that, when called, passes in the parameter to update this.input.
computed: {
whosapp: function () {
return this.input
}
}
})
nameMyApp.update("New Name");
And here is where we call the function, giving it the new parameter; making sure that the parameter is a string.
I hope this is what you're looking for.

How can I access a parent method from child component in Vue.js?

I am trying to call a parent/root level method on a child component in Vue.js, but I keep getting a message saying TypeError: this.addStatusClass is not a function.
Vue.component('spmodal', {
props: ['addStatusClass'],
created: function() {
this.getEnvironments();
},
methods: {
getEnvironments: function() {
this.addStatusClass('test');
}
}
});
new Vue({
el: '#app',
methods: {
addStatusClass(data) {
console.log(data);
}
}
});
Here is a full JSBIN example: http://jsbin.com/tomorozonu/edit?js,console,output
If I call this.$parent.addStatusClass('test'); it works fine, but based on the Vue.js documentation, this is bad practice and I should be using props which is not working.
specifying the prop does nothing on its own, you have to actually pass something to it from the parent - in this case, the function.
<spmodal :add-status-class="addStatusClass"></spmodal>

Categories

Resources