组件传值,数据双向绑定

一、组件传值 组件间的传值方式
父子传值:props、emit、$parent、$chidren、ref
兄弟之间传值:事件总线(on、emit)、Vuex
传值实例
(1)父组件传到子组件(props)
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

// 父组件 // 子组件接收 ceshi

(2)子组件传到父组件(emit)
子组件通过emit触发事件给父组件,父组件通过on去监听数据的变化。
// 父组件 // 子组件接收 ceshi

二、prop prop类型
【组件传值,数据双向绑定】以字符串形式列出:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

通常我们都需要每个 prop 都有指定的值类型,因此通过对象的形式列出、分别标明prop的名称和类型以及默认值
props: { test: String, likes: { type: Number, default: () => [] }, isPublished: { type: Boolean, default: false } }

传递静态或动态 Prop
// 静态传值 // 动态赋予一个变量的值 // 动态赋予一个复杂表达式的值

单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
需要改变prop时,可以通过
(1)子组件内需要将prop作为本地数据进行使用,可以在data中将这个prop作为初始值
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }

(2)这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
三、自定义事件(v-model) 双向绑定v-model
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
// 子组件

在父组件使用v-model,通过该语句实现price变量与输入值双向绑定
// 等同于

执行流程:
1、子组件通过通过 prop 接收父组件的数据price
2、当input进行输入时,会触发input事件
3、通过 $emit 提交事件,将值传递给父组件
4、父组件的input事件被触发,将会更新变量price的值
5、父组件在通过props传值给子组件
v-bind 实现单向绑定
v-model 实现双向绑定
.sync修饰符
真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。因此推荐update:myPropName 的模式触发事件
vue事件名可以updata:prop去定义,用于处理prop传递的新值
组件内部将通过$emit('update:dtitle', val)触发事件,修改title的值
// 子组件 props: ['title'], updateVal(val) { this.$emit('update:dtitle', val) }

// 父组件

注意事项:
1、 .sync 修饰符的 v-bind 不能和表达式一起使用
2、组件内部需要$emit触发的事件名,格式为update:prop
同时在使用sync的时候,简化了绑定prop和绑定update:prop事件
四、动态组件&异步组件 五、代码实例

    推荐阅读