Passing data to Vue.js component - vue.js

I am creating a component and want to pass two properties (item & brokerageID) to the component. Here is the HTML code:
{{brokerageID}}
<holiday-component v-bind:item="item" v-bind:brokerageID="brokerageID" testID="45" ></holiday-component>
Here is the code for 'holiday-component'
Vue.component('holiday-component', {
props: ['item',
'brokerageID',
'testID',
],
data () {
return {
holidaysData: [],
showHolidays: false,
}
},
methods: {
getHolidays(contactID) {
....
},
template: <div> {{testID}} {{item.contactName}} {{brokerageID}}
....
The 'item' property is getting passed to the component (item.contactName is displayed correctly in the component template. However, somehow, brokerageID (property of the Vue object) is not getting passed. This property exists which is confirmed as {{brokerageID}} used above the component in HTML displays value. But, within the component template, brokerageID is not available. Also, the testID property passed to the component is not displayed.
Could someone please advise, what is wrong in my implementation that I am unable to use brokerageID in my component?

See Vue's docs about prop naming https://v2.vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case
In this instance, using v-bind:brokerage-id and v-bind:test-id should do the trick.

Related

Vue Warn: Property or method is not defined on the instance but referenced during render

I have a model name defined in my Component tag as seen below:
<b-table-column v-if="" field="columnName" v-slot="itemProps">
<SelectableAttribute
:attr-name="props2.row.fieldClass"
:attr-id="itemProps.row.id"
:model-id="props.row.id"
:model-name="NewParticipant"
>
However I receive this error:
[Vue warn]: Property or method "NewParticipant" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
I'm not quite sure how I'm meant to define a model-name, in my props I assume but where? I've attached code below.
export default {
props: {
participants:
{
type: Array,
default: null
},
},
components: {
SelectableAttribute
},
As your error tells you, NewParticipant is not defined. You need to add it to your component as a property in data(), like this:
data() {
return {
NewParticipant: [] // Array for example
}
}
Or else, if you want your prop participants to be the model-name, you need to change it to :model-name="participants".

How to watch child properties changes from parent component

I am using a date picker component library and i want to watch when a property of that component changes.
I have tried this:
watch: {
'$refs.picker.popupVisible': {
handler (new_value) {
console.log('executed')
},
deep: true
}
}
Also this:
computed: {
picker () {
console.log(this.$refs.picker.popupVisible)
return this.$refs.picker.popupVisible
}
}
I know that the solution will be a vue.js hack because this is not the right way.If i had access to child component i would emit en event to parent but unfortunately i don't have.
I had a similar problem using a library which had some limitations.
Unfortunately, your watcher will not work.You have to use the function watcher to make this to work.And you have to use it inside the mounted hook.
mounted() {
this.$watch(
"$refs.picker.popupVisible",
(new_value, old_value) => {
//execute your code here
}
);
}
I also have an example. Please take a look here
What you can do is create a data object in parent component and include the date field in that data object and pass that data object to child component as props
<child :dateObj="dateObj"></child>
data: {
dateObj: {
date: ""
}
}
And in child component you can use the date field of that dateObj props. This is possible because Vue doesn't watch the property of Objects passed as props and we can modify them without Vue complaining in console.
Thus the changed date field is reflected in parent as well.

vuejs ref property has no effect when using with createElement

I've written a custom render function for a Vue Component, but when I set the "ref" property in the data object that is passed to the createElement function, nothing shows up in the $refs of the root vm (VueComponent)
Vue.component('sm-form-row', {
render: function (createElement) {
// Create the Row Div and append the columns
return createElement('div', {
class: {
'row': true
},
ref: 'some computed value'
});
}
});
What am I missing, the class is being applied correctly but the $refs keep showing empty.
The ref is beign applied and i made a fiddle to see it that it works.
But,if you want to add a reference to sm-form-row component then you have to add the ref attribute in the parent component.For example in parent component:
<sm-form-row ref="formRow" />
And in your parent component you can access it as:
this.$refs.formRow
Also you will be able to access the methods of the child component.For example if the child component has a method called myMethod you can access it in parent component like this:
this.$refs.formRow.myMethod

Vue - instance data is not defined

I have a menu of topics (e.g. "About us", "Support") and I want to be able to tell what topic is active right now. When a topic is clicked it will become the active one. Think of it as a substitute for a router that will set an active route. This is not possible in my case since I'm working in SharePoint 2010... in a content editor. So I made the decision to have an activeTopic variable in my Vue instance.
The Vue instance
new Vue({
el: '#app',
data: {
activeTopic: '',
}
});
This is because the activeTopic has to update another component and show some data based on the active topic. Like a router showing a child route.
The topic component
Vue.component('topic', {
props: ["title"],
methods: {
setActiveTopic: function (title) {
activeTopic = title;
},
isActiveTopic: function (title) {
return activeTopic == title;
}
},
template: `
<div v-bind:class="{active: isActiveTopic(title)}" v-on:click="setActiveTopic(title)">
<p v-text="title"></p>
</div>
`
});
The setActiveTopic function works as it should when I click it; it updates the activeTopic. But the isActiveTopic function gives me this error:
Error in render: "ReferenceError: activeTopic is not defined"
What I don't understand is that I can edit the activeTopic variable but I can't make a comparison? I've tried setting a default value but it still says it is undefined.
activeTopic should be assigned to the Vue component by setting and reading this.activeTopic. As is, you have two independent activeTopic variables scoped within each of your component methods.
You'll also want to include activeTopic in the component's data block, rather than on the Vue object itself, since it's specific to the component.
(If there's a reason to put that variable on the Vue object you would either want to pass it down to the component as a prop, or else access it directly as Vue.activeTopic instead of this.activeTopic. I'm honestly not certain whether Vue would treat that last structure as a reactive value within components -- I've never had a reason to try that, and can't think of a situation where that'd be a reasonable architecture.)
Vue.component('topic', {
props: ["title"],
data() { return {
activeTopic: ''
}},
methods: {
setActiveTopic(title) {
this.activeTopic = title;
},
isActiveTopic(title) {
return this.activeTopic == title;
}
},
template: `
<div v-bind:class="{active: isActiveTopic(title)}" v-on:click="setActiveTopic(title)">
<p v-text="title"></p>
</div>
`
});
I am new to Vue, and have seen data being defined as an object in several examples.
But apparently, as per the documentation, you have to use data as a function that returns an object.
This is to ensure that all instances will have it's own version of the data object, and is not shared with all instances.
Instead of
data: {
count: 0
}
use
data: function () {
return {
count: 0
}
}
However I still don't know why in one of my component, data as an object worked, and in a child component with it's own data as an object, I got the error count is undefined;
I am assuming, the root element, (defined by new Vue({}) has to be a singleton, and is not intended to have several instances.
And since components, can have instances, the data in that needs to be defined as a function.

Vue.js: property or method is not defined on the instance, but it is

I have a Vue.js component that looks like this:
<!-- MyComponent.vue -->
<script>
export default {
render: () {
return;
},
methods: {
foo() {
alert('hi');
},
},
};
</script>
And then my HTML looks like this:
<my-component #click="foo" />
When I run this I get an error:
Property or method "foo" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
I can't seem to understand what I'm doing wrong here -- all the other SO questions about this error seem to be caused by scoping issues, but I'm just dealing with a simple component.
foo would need to be defined in the component using my-component, not in my-component itself.
Also, you'd need to do #click.native, unless you're specifically $emiting an event called click in my-component.
If you were to use #click="foo" inside of this component on an html element it would work like you expect (a #click on a component needs .native).