组件实例的做用域是相互独立的,父、子组件之间没法进行数据的共享。
若是想在子组件模板中使用父组件的数据,能够经过Prop将父组件的数据下发到子组件。子组件用props
选项声明它预期的数据。javascript
为了传递数据,父组件必须先在子组件自定义标签的特性上绑定数据,绑定的值分两种状况解析:html
prop="value"
v-bind:prop="expression"
v-bind="Object"
new Vue({ el: '#app-1', data: { parentMsg: 'root\'s dynamic data', parentObj: { text:'hello vue!', isShow: true }, }, components: { 'component-1': { props: ['expectMsg','expectDynamicMsg','expectObj','text','isShow'], template: '\ <div>\ <p>{{expectMsg}}</p>\ <p>{{expectDynamicMsg}}</p>\ <p v-show="expectObj.isShow">{{expectObj.text}}</p>\ <p v-show="isShow">{{text}}</p>\ </div>' }
<div id="app-1"> <!-- 字面量绑定、动态绑定、动态绑定一个对象、动态绑定特例 --> <component-1 expect-msg="static data" v-bind:expect-dynamic-msg="parentMsg" v-bind:expect-obj="parentObj" v-bind="parentObj"> </component-1> </div>
这里分别做了几种绑定的示例:vue
"static data"
绑定到子组件的props
的expectMsg
上parentMsg
动态绑定到子组件的expectDynamicMsg
特性上parentObj
动态绑定到子组件的expectObj
特性上parentObj
对象的属性text、isShow
绑定到子组件的text
和isShow
特性上注意:要下发一个数字给子组件不能使用字面量绑定,字面量下发的都是字符串。所以须要动态绑定java
<component v-bind:some-number="1">
当要对下发数据作验证或在无数据时设置默认值,子组件选项props
就须要使用一个对象替换数组。
简单的状况:express
props:{ someProp:String }
下发数据必须是一个字符串数组
复杂点能够设置默认值与验证器,如:app
new Vue({ el: '#app-2', data:{ message:{ title:'prop验证', text:'父组件数据' } }, components: { 'component-2': { props: { propObj:{ type:Object, //下发对象的title属性必须是个字符串 validator:function(value){ return typeof value.title === "string" }, //下发数据为一个数组或对象,设置的默认值必须由一个函数返回 default:function(){ return {title:'prop验证',text:'数组/对象的默认值应当由一个工厂函数返回'} } } }, template: '<div><h5>{{propObj.title}}</h5><p>{{propObj.text}}</p></div>' } } })
<div id="app-2"> <component-2 v-bind:prop-obj="message"></component-2> </div>
type属性也能够是一个函数,使用instanceof
验证。验证在子组件实例建立以前进行,所以验证里的任何函数都没法使用子组件实例属性。ide
更多类型验证 Prop验证函数
下发数据实际上就是完成一个数据绑定的过程,把组件间的特定数据绑定在一块儿,默认状况下为单向绑定,子组件的数据对于父组件是透明的,而父组件的数据变化则会引起子组件数据的变化。ui
new Vue({ el: '#app-3', data: { content: "please input..." }, components: { 'component-3': { props:['txt'], template:'<div><input v-model="txt"></div>' } } })
<div id="app-3"> <input v-model="content"> <br/> <component-3 v-bind:txt="content"></component-3> </div>
父组件经过Prop
下发数据,将父组件属性content
和子组件特性txt
绑定在一块儿,在第一文本框输入值改变content
的内容,子组件的txt
会跟随变化,显示在第二个文本框中。
若是在子模板第二个文本框输入,修改txt
的值时,父组件控制的第一个文本框内容不会改变。
并在控制台给出警告,说不要修改props
选项中的值,做为代替,可让prop
的值赋予data
或者computed
属性使用。所以能够像下面这样用data
替代prop
做为一个局部变量。
'component-3': { props:['txt'], template:'<div><input v-model="txtData"></div>', data:function(){ return {txtData:this.txt} } }
若只考虑输出不考虑输入,也可使用计算属性替代
'component-3': { props: ['txt'], template: '<div><input v-model="txtComputed"></div>', computed: { txtComputed:function() { return this.txt } } }
组件的做者却并不总能预见到组件被使用的场景。因此,组件能够接收任意传入的特性,这些特性都会被添加到组件的根元素上,而不须要定义响应的props
。
var vm = new Vue({ el: '#app-4', components: { "component-4": { template: "<button class='btn-sm'>hello vue!</button>" } } });
<div id="app-4"> <component-4 data-title="learn vue" class="btn-info"></component-4> </div>
渲染结果
<button class="btn-sm btn btn-info" data-title="learn vue">hello vue!</button>
其中data-title
、class
就是非Prop特性。
由于没有在组件中定义props
,所以也没法去引用它们,做用目前不明显。
从渲染结果还能够发现,class
特性的值由子组件模板和父模板定义的特性合并而成,对于class
和style
是这样合并结果。但对于多数组件来讲,传递给组件的值会覆盖组件自己设定的值。