组件传值
考虑到Vue框架是MVVM模式的,因此牵涉到数据的问题是Vue中的核心,而组件传值则是其中的一大重点
组件传值分为:父子组件传值、兄弟组件之间传值
父子组件传值
Vue中把网页拆分成一个个小的组件,我们可以理解整个大网页是父组件,而这里面的每一个小的部分(头部、轮播图等)都是一个个子组件
父组件---->子组件
先举一个父子组件的简单例子:在一个todolist中,父组件为整个页面,其中一个子组件为生成的每一小项的todolist,如下
这里,每点击一次按钮,input框中的内容(父组件)就需要传入todolist并生成一条新的todolist(子组件),即父组件传值给子组件
子组件为了接收父组件的传值,需要两个操作:
1.v-bind绑定一个变量,接收父组件中传递过来的值,此处父组件传递的值在v-for中的item,这里用content属性接收这个item
2.子组件props中添加这个用来接收的属性,如下
这样一来,父组件就可以向子组件传值了,整个过程整理如下:
类型检查
props可以进行类型检查,即可以设置接收值的类型、是否必填、默认值等参数
对类型进行的限定写在type属性中,如果只允许为一种属性,则值写一个数据类型,而多种属性则把数据类型写在一个数组中
类型是否必填写在required属性中,true为必填,false为选填(默认值)
类型的默认值写在default属性中,只有当没有给该属性传值时用默认值,否则用传入的值
单向数据流
Vue里一般数据是从父组件传入子组件的,并且修改/变化的是父组件的值
如果在子组件中修改父组件的值,会造成其他使用父组件值的子组件的值也变化(例如传入的是引用类型的值),这明显是不好的
为了应对这个问题,有两种解决方法
1.在子组件中的data里接收prop传入的参数,然后修改这个data里的参数
2.在子组件中用computed来修改属性值
子组件---->父组件
还是上面的todolist,我们可以加一个功能:添加完几个todolist项后,通过点击,去除掉我们不需要的项目,但是这里点击的为子组件,而子组件的数据来自于父组件,因此产生了子组件向父组件传值的问题
对于这样的情况,处理方法如下
1.子组件的模板中绑定一个点击事件,该事件写在子组件的methods中,然后在methods中用$emit触发一个父组件的监听事件,并同时传一个参数给父组件
2.父组件的监听事件被触发,执行监听事件中的事件,该事件写在父组件的methods中
3.父组件中的事件被触发,同时接收到子组件传入的值
图片示例如下
非父子组件传值
非父子组件之间的传值不再使用props和$emit,而是直接在Vue构造函数的原型上添加一个bus属性,这个属性将在后续所有的Vue实例中出现,同时这个属性也是一个Vue实例,里面有Vue实例的一系列方法
下面这个例子实现了点击一个子组件,其他子组件的值都变成点击的这个组件的值,具体代码如下:
执行的解释如下:
1.子组件中的props接收父组件的传值,这里父组件传入两个字符串,于是这两个字符串就被丢给了content,但是这里考虑了单向数据流的问题,把父组件传入的数据丢给了selfContent这个变量
2.点击子组件,触发了handleClick事件,子组件通过$emit向父组件的bus属性(也是一个Vue实例)触发change事件,并传递selfContent这个变量的值
3.在mounted这个生命周期中,所有该组件的bus属性(Vue实例)监听到了change事件,触发函数,所有child组件中的selfContent的值都变成了之前传入的selfContent的值,并被页面渲染出来
整个执行的代码注释如下
当然非父子组件传值也可以用Vuex来实现(待补充,未完待续)