背景
Vue.js 在前端貌似很火的样子,虽然年初玩过 Angular.js ,同为前端框架,使用体验很类似,但是 Angular.js 的知识已经淡忘了。
十一月份敲过一天 Vue 的 demo ,加入它跟 Java 的 OOP 很相似,分为属性和方法,通过行为改变属性。直接以面向对象的方式访问数据就可以了,不需要用 jQuery 操作 DOM 树,使用相对简单。所以根据短期之内,Vue 忘记的可能性不大。
本文就来整理一下组件通信的几种方式,尤其是涉计到弹框组件的通信过程。
常见的通信场景
element 提供了 el-dialog
组件,它的本质是通过 v-show
属性控制一个弹框组件的显示和隐藏的。传统的开发过程中,比较常见的一种场景是:
第一步,弹出一个新的配置页面
第二步,在配置页面上输入表单数据
第三步,点击 “确定” 按钮,将用户在弹出页面的配置信息回显到主页面上
比如,添加收货地址的弹出框:
点击 “确定” 后,需要将弹框页面上的数据回显在父页面上。
此外,非弹框子组件和父组件双向通信的场景:
1、子组件需要父组件传递初始化数据,比如,弹出编辑页面;
2、父组件需要收集子组件修改后的数据,比如,编辑保存操作。
props
和 emit
props
和 emit
基本上能够满足非弹框子组件和父组件双向通信的场景。
但是 props
的局限在于它是父子组件传递数据的方式,是由父组件单向控制子组件属性的,所以不能在子组件中直接修改自己的 props 属性,否则 vue 会报错【示例错误信息】:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten
whenever the parent component re-renders.
Instead, use a data or computed property based on the prop's value.
Prop being mutated: "coo1"
而 emit
需要父组件提供监听事件,才能触发。
中和二者,得到的使用经验是:
第一,子组件只需要父组件传递初始数据,然后自己维护 props 数据时,最好使用 props
接收初始值,然后再在 data
函数中以 props
数据为复本来初始化自己的真实数据。
props: ['myMessage'],
data () {
return {
message: myMessage // 以父组件传入的属性的复本作为初始值
}
}
第二,父组件如果需要使用子组件的数据,可以直接在自己的方法中使用 $refs
访问子组件的数据。
最简单的 $refs
父组件引用子组件时,指定它的 ref 属性标识子组件的引用名词,然后就能直接通过自己的 $refs
属性访问到子组件,使用子组件的数据了。
介绍一个简单的实例,一个计数子组件的数据要能被父组件直接使用,父组件定义:
<template>
<div class="app-container">
<counter v-show="false" ref="counter"></counter>
<button @click="onShow">提交</button>
<p>counter 当前的计数值为 {{myCount}}</p>
</div>
</template>
//按钮事件中,直接访问子组件的数据值
onShow(){
let counter = this.$refs.counter
console.log('$ref is'+counter)
this.myCount = counter.count;
}
计数子组件定义:
<template>
<button v-on:click="count++">点击计算点击次数:{{count}}次</button>
</template>
<script>
export default {
data() {
return {
count: 10,
}
},
}
</script>
启示录
就组件通信的各种方式来看,事件触发是比较繁琐一点的。$refs
和 props
两种通信方式学会之后,对解决前面几类通信场景来说,就够用了。