Vue.js每天必学之组件与组件间的通信(2)

Vue.component('child', { // camelCase in JavaScript props: ['myMessage'], template: '<span>{{ myMessage }}</span>' }) <!-- kebab-case in HTML --> <child my-message="hello!"></child>

动态 Props

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 Props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件:

<div> <input v-model="parentMsg"> <br> <child v-bind:my-message="parentMsg"></child> </div>

使用 `v-bind` 的缩写语法通常更简单:
<child :my-message="parentMsg"></child>

字面量语法 vs. 动态语法

初学者常犯的一个错误是使用字面量语法传递数值:

<!-- 传递了一个字符串 "1" -->
<comp some-prop="1"></comp>
因为它是一个字面 prop,它的值以字符串 `”1”` 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用动态语法,从而让它的值被当作 JavaScript 表达式计算:
 <!-- 传递实际的数字  -->
<comp :some-prop="1"></comp>

Prop 绑定类型

prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。不过,也可以使用 .sync 或 .once 绑定修饰符显式地强制双向或单次绑定:

比较语法:

<!-- 默认为单向绑定 --> <child :msg="parentMsg"></child> <!-- 双向绑定 --> <child :msg.sync="parentMsg"></child> <!-- 单次绑定 --> <child :msg.once="parentMsg"></child>

双向绑定会把子组件的 msg 属性同步回父组件的 parentMsg 属性。单次绑定在建立之后不会同步之后的变化。

注意如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。

Prop 验证

组件可以为 props 指定验证要求。当组件给其他人使用时这很有用,因为这些验证要求构成了组件的 API,确保其他人正确地使用组件。此时 props 的值是一个对象,包含验证要求:

Vue.component('example', { props: { // 基础类型检测 (`null` 意思是任何类型都可以) propA: Number, // 多种类型 (1.0.21+) propM: [String, Number], // 必需且是字符串 propB: { type: String, required: true }, // 数字,有默认值 propC: { type: Number, default: 100 }, // 对象/数组的默认值应当由一个函数返回 propD: { type: Object, default: function () { return { msg: 'hello' } } }, // 指定这个 prop 为双向绑定 // 如果绑定类型不对将抛出一条警告 propE: { twoWay: true }, // 自定义验证函数 propF: { validator: function (value) { return value > 10 } }, // 转换函数(1.0.12 新增) // 在设置值之前转换值 propG: { coerce: function (val) { return val + '' // 将值转换为字符串 } }, propH: { coerce: function (val) { return JSON.parse(val) // 将 JSON 字符串转换为对象 } } } })

type 可以是下面原生构造器:
 •String
 •Number
 •Boolean
 •Function
 •Object
 •Array 

type 也可以是一个自定义构造器,使用 instanceof 检测。

当 prop 验证失败了,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。

父子组件通信

父链

子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。父组件有一个数组 this.$children,包含它所有的子元素。

尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法,因为:
 1.这让父组件与子组件紧密地耦合;

2.只看父组件,很难理解父组件的状态。因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态。

自定义事件

Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。

每个 Vue 实例都是一个事件触发器:
 •使用 $on() 监听事件;

•使用 $emit() 在它上面触发事件;

•使用 $dispatch() 派发事件,事件沿着父链冒泡;

•使用 $broadcast() 广播事件,事件向下传导给所有的后代。

不同于 DOM 事件,Vue 事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回 true。

简单例子:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzfwzg.html