父子组件之间传值
- $emit()
- $on() $emit()
- this.$parent.xxx
正常的@xxx=“func” , this.$emit()方式
-
使用.sync可以给props双向绑定数据
-
由子组件自己控制何时传值
父亲组件
<template> <div> <p style="color: red;">使用.sync双向绑定</p> 父组件输入框:<input v-model="inputValue" /> 父组件值:{{ inputValue }} <hr /> <child :fatherInput.sync="inputValue"></child> </div> </template> <script> import child from "./child"; export default { components: { child, }, data() { return { inputValue: "" }; } }; </script>
儿子组件
<template> <div> 引用子组件:<input v-model="childInput" /> 父组件传递的值: {{ fatherInput }} </div> </template> <script> export default { props: { fatherInput: { type: String, default: function() { return null; } } }, data() { return { childInput: "" }; }, watch: { fatherInput: function() { // 监听父组件传递过来的值 if (this.fatherInput !== null) { // 如果父组件传递了值,我们就把值赋给子组件的输入框 this.childInput = this.fatherInput; } }, childInput: function() { // 监听子组件的输入框的值,随时传递给父组件 this.$emit("update:fatherInput", this.childInput); // 将子组件的输入框的值传递给父组件 父组件需要用.sync } } }; </script>
-
由父组件控制子组件传值
在父组件种拿到子组件的实例,直接触发子组件的方法 this.$refs[‘childcomp’].target();
//父组件:parent.vue <template> <div> <child v-on:childevent='wathChildEvent' ref="childcomp"></child> <input type="button" @click="parentEnvet" value="父组件触发" /> <div>子组件的数据为:{{msg}}</div> </div> </template> <script> import child from "./child"; export default { data(){ return{ msg:"" } }, components:{ child }, methods:{ wathChildEvent:function(vals){//直接监听 又子组件触发的事件,参数为子组件的传来的数据 console.log(vals);//这是子组件的数据,将有子组件操作触发传给父组件 this.msg = vlas; }, parentEnvet:function(){ this.$refs['childcomp'].target(); //通过refs属性获取子组件实例,又父组件操作子组件的方法触发事件$meit } } } </script> //子组件:child.vue <template> <div> <!-- dothing..... --> </div> </template> <script> export default { data(){ return { texts:'这是子组件的数据,将有子组件操作触发传给父组件' } }, methods:{ target:function(){ //又子组件的事件触发 自定义事件childevent this.$emit('childevent',this.texts);//触发一个在子组件中声明的事件 childEvnet } }, } </script>
子组件直接this.$parent.event调用父组件方法
-
this.$parent 可以访问到父组件 上所有的 data(){ 里的数据信息和生命周期方法,methods里的方法 }!
但是不推荐使用this.$parent的方式,这样直接获取父亲的上下文,降低了自组件的可复用性,不能在别的父亲里面使用
//在子组件中直接这样调用父亲的方法,aaa是定义在父亲methods里面的方法 this.$parent.aaa();
兄弟组件之间传值
发布订阅模式,this. o n ( ) , t h i s . on(), this. on(),this.emit()
每个子组件都相当与一个vue实例,需要两个实例都引用同一个实例,由这个实例作为中间桥梁,负责个两边传值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>孙三峰--博客园</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
//准备一个空的实例对象
var Event = new Vue();
var A = {
template: `
<div style="border: 1px solid red; margin-bottom: 10px; width: 300px;">
<h4>A组件</h4>
<p>{{a}}</p>
<input type="button" value="把A数据给C" @click="send" />
c组件给我的值: <p style="">{{getmsg}}</p>
</div>
`,
data() {
return {
a: '我是A里面的数据',
getmsg: ''
}
},
mounted() {
Event.$on('getc', (val) => {
this.getmsg = val
})
},
methods: {
send() { //A发送数据
Event.$emit('a-msg', this.a);
}
}
};
var B = {
template: `
<div style="border: 1px solid green; margin-bottom: 10px; width: 300px;">
<h4>B组件</h4>
<p>{{b}}</p>
<input type="button" value="把B数据给C" @click="send" />
c组件给我的值: <p style="">{{getmsg}}</p>
</div>
`,
data() {
return {
b: '我是B里面的数据',
getmsg: ''
}
},
mounted() {
Event.$on('getc', (val) => {
this.getmsg = val
})
},
methods: {
send() {
Event.$emit('b-msg', this.b);
}
}
};
var C = {
template: `
<div style="border: 1px dotted green; margin-bottom: 10px;width: 300px;">
<h4>我是C组件,我在坐等接收数据</h4>
<p>{{a}}</p>
<p>{{b}}</p>
</div>
`,
data() {
return {
a: '',
b: ''
}
},
mounted() { //两种接收的方式
var _this = this;
Event.$on('a-msg', function (a) {
_this.a = a;
});
Event.$on('b-msg', function (b) {
this.b = b;
}.bind(this))
Event.$emit('getc', 'i am c')
}
};
window.onload = function () {
new Vue({
el: '#box',
data: {
},
components: {
'com-a': A,
'com-b': B,
'com-c': C
}
})
}
</script>
</head>
<body>
<div id="box">
<com-a></com-a>
<com-b></com-b>
<com-c></com-c>
</div>
</body>
</html>
o n ( ) 和 on()和 on()和emit()也可以在父子组件中使用
-
子组件通过this.$parent获取到父亲的实例,这样父亲和儿子就不需要格外弄个中间的实例传递参数
// 父亲提前在自己的created或者别的里面定义好监听的方法 created() { this.$on("sss", val => { console.log(val); }); }, // 儿子触发父亲的定义好的方法 this.$parent.$emit("sss", "由儿子触发");