Vue.js 使用 props 将数据从父级传递给子级
例子
在Vue.js中,每个组件实例都有自己的隔离作用域,这意味着如果父组件有子组件——子组件有自己的隔离作用域,父组件也有自己的隔离作用域。
对于任何大中型应用程序,遵循最佳实践惯例可以防止在开发阶段和维护之后出现很多麻烦。要遵循的其中一件事情是避免直接从子组件引用/改变父数据。那么我们如何从子组件中引用父数据呢?
子组件中需要的任何父数据都应该props从父组件传递给子组件。
用例:假设我们有一个包含两个表users和addresses以下字段的用户数据库:
users表
addresses桌子
并且我们希望有三个组件来在我们的应用程序中的任何位置显示相应的用户信息
用户组件.js
export default{ template:``, data(){ return{ name:'', phone:'', email:'' } }, }
联系人详细信息.js
import Address from './address'; export default{ template:`Phone:`, props:['phone', 'email'], data:(){ return:{ addressType:'Office' } }, components:{Address} }Address:
//请参阅下面的骆驼案例与烤肉串案例的解释
地址.js
export default{ template:``, props:{ addressType:{ required:true, type:String, default:'Office' }, data(){ return{ block:'', street:'', city:'' } } }{{addressType}}
主文件
import Vue from 'vue'; Vue.component('user-component', require'./user-component'); Vue.component('contact-details', require'./contact-details'); new Vue({ el:'body' });
索引.html
......
我们显示phone和email数据,这些数据的特性user-component在contact-details其中没有电话或电子邮件数据。
将数据作为道具传递
所以内user-component.js的模板特性,其中包括我们的
道具-动态绑定
由于我们动态绑定props,因此父组件ie中电话或电子邮件的任何更改
道具-作为文字
但是,如果我们将phone和email的值作为字符串文字值传递,phone="(44)77700070077"email="bond@mi6.com"那么它将不会反映父组件中发生的任何数据更改。
单向绑定
默认情况下,更改方向是从上到下,即父组件中动态绑定的props的任何更改都将传播到子组件,但子组件中prop值的任何更改都不会传播到父组件。
例如:如果从内部
但是,如果我们在父组件(在我们的用例中)中将email的值从更改bond@mi6.com为jamesbond@mi6.co,那么子组件(
双向绑定
如果我们想要双向绑定,那么我们必须明确指定双向绑定as:email.sync="email"而不是:email="email"。现在,如果我们更改子组件中prop的值,更改也会反映在父组件中。
在中型到大型应用程序中,从子状态更改父状态将非常难以检测和跟踪,尤其是在调试时-小心。
Vue.js2.0中将没有任何.sync选项可用。props的双向绑定在Vue.js2.0中被弃用。
一次性绑定
也可以将显式一次性绑定定义为:email.once="email,它或多或少类似于传递文字,因为父属性值的任何后续更改都不会传播到子属性。
CAVEAT
当Object或Array作为prop传递时,它们总是通过REFERENCE传递,这意味着无论显式定义的绑定类型:email.sync="email"或:email="email"或:email.once="email",如果电子邮件是父级中的对象或数组,则无论绑定类型如何,在子组件中的prop值也会影响父组件中的值。
作为数组的道具
在contact-details.js文件中,我们定义props:['phone','email']了一个数组,如果我们不想用props进行细粒度控制,这很好。
道具作为对象
如果我们想要对props进行更细粒度的控制,比如
如果我们想定义什么类型的值可以作为prop
道具的默认值应该是什么
一个值是必须(必须)传递给prop还是可选的
然后我们需要使用对象符号来定义道具,就像我们在address.js.
如果我们正在创作可能被团队中的其他开发人员使用的可重用组件,那么将props定义为对象是一个很好的做法,以便使用该组件的任何人都清楚应该是什么类型的数据以及是否它是强制性的或可选的。
它也称为道具验证。该类型可以是以下默认构造函数中的任何一个:
细绳
数字
布尔值
大批
目的
功能
或自定义构造函数
取自http://vuejs.org/guide/components.html#Props的一些prop验证示例
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' } } }, //表明此道具需要双向绑定。将要 //如果绑定类型不匹配,则发出警告。 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) //将值转换为Object } } } });
骆驼壳vs烤肉串
HTML属性不区分大小写,这意味着它不能区分addresstype和addressType,因此当使用驼峰命名法属性名称作为属性时,我们需要使用它们的kebab-case(hyphen-delimited)等价物:
addressType应该像address-type在HTML属性中那样编写。