vue组件间通信(1-父子)
props
父传子时,我们通常使用自定义属性,props接收。
但是大家都知道,这种数据传递是单向的,只能父传子,而子组件也不能直接去操作这个数据;
# Prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,
但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
# 另外,每次父组件更新时,子组件的所有 prop,都会更新为最新值。这意味着你不应该在子组件内部改变 prop。
在两种情况下,我们很容易忍不住想去修改 prop 中数据:
#1 Prop 作为初始值传入后,子组件想把它当作局部数据来用;
#2 Prop 作为原始数据传入,由子组件处理成其它数据输出。
对这两种情况,正确的应对方式是:
定义一个局部变量,并用 prop 的值初始化它:
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
定义一个计算属性,处理 prop 的值并返回:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
$emit
子传父时,我们通常使用自定义方法,子组件调用$emit( event, […args] )执行函数,并传递参数,这样就实现了子传父
父组件
<pageHeader v-on:isBack="fun" title="个人信息"></pageHeader>
子组件中
<div @click="clickDiv">点我触发事件</div>
----------
methods: {
clickDiv () {
this.$emit('update:isBack', '参数')
}
}
.sync 修饰符
但是这样如果只是想实现传递参数,那就有点麻烦了,因为我们还需要在父组件定义函数去接收,我们希望实现一种双向数据绑定;
#在我们修改了子组件的数据时能够同步更新父组件,于是我就找到了这个方法
# Vue 1.x 中的 .sync 修饰符实现了对一个 prop 进行“双向绑定”,当一个子组件改变了一个带 .sync 的 prop 的值时,这个变化也会同步到父组件中所绑定的值。这很方便,但也会导致问题。(官网给出了较为详细的说明,因为它破坏了单向数据流,debug 复杂结构的应用时会带来很高的维护成本。
# 在 2.0 中移除 .sync ;但是在 2.0 发布之后的实际应用中,我们发现 .sync 还是有其适用之处,比如在开发可复用的组件库时。我们需要做的只是让子组件改变父组件状态的代码更容易被区分。
# 从 2.3.0 起我们重新引入了 .sync 修饰符)
下面的代码
<pageHeader :isBack.sync="parameter" title="个人信息"</pageHeader>`
会被扩展为
<pageHeader :isBack.sync="parameter" @update:isBack="val => parameter = val title="个人信息"</pageHeader>
子组件中
<div @click="clickDiv">点我触发事件</div>
methods: {
clickDiv () {
this.$emit('update:isBack', '参数')
}
}
当使用一个对象一次性设置多个属性的时候,这个 .sync 修饰符也可以和 v-bind 一起使用:
<comp v-bind.sync="{ foo: 1, bar: 2 }"></comp>
这个例子会为 foo 和 bar 同时添加用于更新的 v-on 监听器。
js数据存储原理
以上为比较正统的写法,也是比较推荐的,有的时候我们想要更加巧妙地方法实现,那么我们可以利用js中对象和数组是引用类型,指向同一个内存空间的原理。
如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
即,将需要传递的参数放到一个对象或者数组里传递,在子组件中修改对象的属性,就会联动触发父组件的视图更新了。
# 因为,他们操作的是同一个内存地址引用的对象