Vue - non parent child communication - javascript

When reading Vue document
Non parent-child communication
For practice, I tried to build an example to see if it works, below is my code:
I build two component and tried to use Vue instance bus to transport message from dudi-station to dudo-station while on-click, but it's not working.
Can anyone help? Thanks!
Vue.component('dudi-station', {
template: '<div #click="sentMsg">{{dudiMsg}}</div>',
data: function() {
return {
dudiMsg: 'Dudi!!',
}
},
methods: {
sentMsg: function() {
bus.$emit('callout', this.dudiMsg);
},
}
});
Vue.component('dudo-station', {
template: '<div>{{dudoMsg}}</div>',
data: function() {
return {
dudoMsg:'',
}
},
created: function() {
bus.$on('callout', function(value) {
this.dudoMsg = value;
console.log(value);
});
}
});
var bus = new Vue();
new Vue({
el: '#app',
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<dudi-station></dudi-station>
<dudo-station></dudo-station>
</div>

Use arrow function as event handler when receiving message in component from another component. It will help you with "this" keyword scope.
bus.$on('callout', function(value) {
this.dudoMsg = value;
console.log(value);
});
instead of this use it as below
bus.$on('callout', (value) => {
this.dudoMsg = value;
console.log(value);
});

Because in this statement:
bus.$on('callout', function(value) {
this.dudoMsg = value;
this this is not mean your vue instance.
You need to use arrow function to make sure that 'this' means the vue instance.
Like below:
Vue.component('dudi-station', {
template: '<div #click="sentMsg">{{dudiMsg}}</div>',
data: function() {
return {
dudiMsg: 'Dudi!!',
}
},
methods: {
sentMsg: function() {
bus.$emit('callout', this.dudiMsg);
},
}
});
Vue.component('dudo-station', {
template: '<div>{{dudoMsg}}</div>',
data: function() {
return {
dudoMsg:'',
}
},
created: function() {
bus.$on('callout',value => {
this.dudoMsg = value;
console.log(value);
});
}
});
var bus = new Vue();
new Vue({
el: '#app',
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<dudi-station></dudi-station>
<dudo-station></dudo-station>
</div>

Related

How do I call a Vue.js function from an external JavaScript file?

I have to call a Vue.js function from an external JavaScript file, but it's not working. Below I have given the code that I have tried.
// external js file
import vm from './vue.js';
function callingVuejsFunction(data) {
this.vm.displayData()
}
// Vuejs file
var vm = new Vue({
el: '#app',
data: {
firstname : '' ,
lastname : ''
},
methods:{
displayData: function( ) {
alert()
}
}
})
You can use vm.$options.methods.displayData():
var vm = new Vue({
el: '#app',
data: {
firstname: '',
lastname: ''
},
methods: {
displayData: function(msg) {
alert(msg)
}
}
})
vm.$options.methods.displayData('I was called externally!')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
export default {
methods:{
my_function(){
alert('vue function trigger!!!')
}
},
created () {
let _this = this
window.addEventListener('ready', function() {
_this.my_function()
})
}
}
Here is the perfect example of calling a vue method from javascript.

Vue data variable to methods and then to provide

I have issue to get some values from methods and want to parse to provide.
How I can solve the problem?
methods: {
onClickCategory: (value) => {
return (this.catId = value);
},
},
provide() {
return {
categoryId: this.value,
};
},
I get always categoryId:undefined
I found solution:
methods: {
onClickCategory(value) {
this.categoryId.value = value;
},
},
provide() {
this.catID = this.categoryId;
return {
catId: this.catID,
};
},
As Vue Guide highlights,
Note: the provide and inject bindings are NOT reactive. This is
intentional. However, if you pass down an observed object, properties
on that object do remain reactive.
So one solution is wrap your value into one observed object, like test2.value in below example:
Vue.config.productionTip = false
Vue.component('v-parent', {template: `
<div>
<h4>Example</h4>
<p>Not Working: <input v-model="test1"></p>
<p>Working: <input v-model="test2.value"></p>
<v-child></v-child>
</div>
`,
data () {
return {
test1: 'blabla1',
test2: {value: 'blabla2'}
}
},
provide () {
return {parent1: this.test1, parent2: this.test2}
}
}),
Vue.component('v-child', {
template: `<div><pre>{{parent1}}</pre><pre>{{parent2.value}}</pre></div>`,
inject: ['parent1', 'parent2']
})
new Vue({
el: '#app',
data() {
return {
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<v-parent/>
</div>
</div>

Custom vue events not working

I am trying to catch vue.js custom event within one component, but it's not catching. What's the problem?
myEventFunc: function() {
this.myEvent = true;
},
clickedFunc: function() {
this.clicked = true;
this.$emit('myevent');
}
JSFiddle Example: https://jsfiddle.net/ucean0rh/1/
I'm not sure if this is a Vue way of dealing with it, but it works in my JSFiddle. Simply call myEventFunc() from within clickedFunc:
new Vue({
el: "#app",
data: {
myEvent: false,
clicked: false,
},
methods: {
myEventFunc: function() {
this.myEvent = true;
},
clickedFunc: function() {
this.clicked = true;
this.myEventFunc();
this.$emit('myevent');
}
}
})

How to call methods in App.vue from the vue components

I have a vue component and a vue element declaration as given below
Vue.component('todo-item', {
template: '<li>This is a todo</li>'
methods: {
test: function() {
// I am getting an error here
app.aNewFunction();
}
}
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
aNewFunction: function() {
alert("inside");
}
}
})
How to call a method in vue app from the vue component?
You can execute root instance method like this: this.$root.methodName()
Vue.component('todo-item', {
template: '<li>This is a todo</li>',
methods: {
test: function() {
this.$root.aNewFunction();
}
},
mounted() {
this.test();
}
})
new Vue({
el: '#app',
template: '<todo-item></todo-item>',
methods: {
aNewFunction: function() {
alert("inside");
}
}
})
Another solution which I think it's more accorded with Vuejs architecture, it's to use events listener & emitter between child-component and its parent to make communications.
Check this simple fiddle as a vision
Vue.component('todo-item', {
template: '<li>This is a todo</li>',
methods: {
test: function() {
console.log('Emmit this Event.');
this.$emit('yourevent');
}
},
created() {
this.test();
}
});
new Vue({
el: '#vue-app',
data: {
'message': '',
},
methods: {
aNewFunction(event) {
console.log('yourevent Is Triggered!');
this.message = 'Do Stuff...';
},
}
});

Add custom property to vuejs component

How do I set a custom property inside a vue component?
var myComponent = Vue.extend({
data: function() {
return {
item: {}
}
},
created: function() {
// This does not seem to work
this.item.customProperty = 'customProperty';
}
});
You can use Vue.set to add reactivity:
var myComponent = Vue.extend({
data: function() {
return {
item: {}
}
},
created: function() {
Vue.set(this.item, 'customProperty', 'customProperty');
}
});
It seems that you should use Object.assign:
var myComponent = Vue.extend({
data: function() {
return {
item: {}
}
},
created: function() {
// This does not seem to work
this.item = Object.assign(this.item, {customProperty:'customProperty'});
}
});

Categories