三种传值情况的实现步骤描述 :
VUE是单向数据流。父组件内的数据的作用域就是父组件,子组件或者兄弟组件都无法直接使用该数据。所以有了以下三种传值方式。
- 单向数据流:props是单向绑定的,父组件通过props向子组件传值后,子组件是不可以直接修改父组件传过来的值,这是为了防止子组件直接修改父组件的数据,导致数据不准确,实际运用中,会用到子组件需要修改父组件的数据。
在两种情况下,我们很容易忍不住想去修改 prop 中数据:
-- 1. Prop 作为初始值传入后,子组件想把它当作局部数据来用;
-- 2. Prop 作为原始数据传入,由子组件处理成其它数据输出。
对这两种情况,正确的应对方式是:
(1)定义一个局部变量,并用 prop 的值初始化它:
屏幕快照 2018-02-20 下午9.02.15.png
(2) 定义一个计算属性,处理 prop 的值并返回:
屏幕快照 2018-02-20 下午9.04.38.png
屏幕快照 2018-02-20 下午9.05.54.png
- 父组件向子组件传值:
组件实例的作用域是孤立的,不能在子组件上直接用父组件的数据。
可以在组件上使用自定义属性绑定数据,在组件中需要显示的用props声明自定义属性名。
- 子组件向父组件传值:
需要用到自定义事件,父组件用$on监听自定义事件,$emit触发父组件所关心的自定义事件。
(1)首先需要在子组件上触发事件,比如点击事件,点击后触发子组件上的一个方法fn(函数),并在这个时候传值(就是在该方法内填写参数);
(2)fn内,触发自定义事件(this.$emit('自定义事件名'),传递的参数)
(3)在子组件的标签上绑定该自定义事件,对应的自定义处理函数就是在父组件上定义的函数fn2,该函数内部写对应的处理逻辑。(注意:fn1的实参的值就是这个函数接收了的!)
- 兄弟组件传值
父==>子
<!--子组件-->
<list-my btn-value="查询" > </list-my>
props:['btnValue'],
data(){
return {
myNum : this.num
}
},
template:`
<ul>
<li >
<input type="text" :value="btnValue">
</li>
</ul> `
})
子==>父
<div id="app">
<!--子组件-->
<list-my @abc="change"></list-my>
</div>
template:`
<ul>
<li v-for="(val,index) in wolist" @click="fn1(val)">{{val}}</li>
</ul>
`,
methods:{
fn1(val){
//第二个参数是实参,这个实参就是传递给了自定义事件对应的事件处理函数
this.$emit('abc',val)
}
}
})
new Vue({
el : '#app',
methods:{
//自定义事件对应的处理函数,该参数val,就是子组件fn1方法传递过来的实参
change(val){
this.num = val
}
}
})
兄弟组件传值
案例:两个兄弟组件:仿select菜单,点击下面的li选项,会显示在上面的input上。
思路:
- 点击每一个li的时候,实际上改变的是父级的状态,进而去改变上面input显示的值(即li兄弟组件)。
- 需要在父组件上面去定义好这个状态(title)
1.父组件
//select-input和list是兄弟组件
<select-input :title='title'></select-input>
<list @title="chengTitle">
data(){
return{
//父组件定义状态
title:''
}
},
methods: {
//自定义事件对应的事件处理函数
chengTitle(val){
this.title = val;
}
}
2.子组件(list)
<li v-for="item,index in list" @click='showTitle(item.title)'>
{{item.title}}
</li>
methods:{
showTitle(title){
//触发自定义函数
this.$emit('title',title);
}
}