本篇文章是我参考官方文档整理的, 供大家参考, 高手勿喷!
prop
组件实例的作用域是孤立的。这意味着不能 (也不应该) 在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的 props 选项。
子组件要使用 props 选项声明它期待获得的数据
官方的解释非常清晰了: 两者之间需要有一个通讯工具才可以获取到对方的数据, props 就是这个通讯工具, 并且在通讯时需要说明我想得到什么数据;
先从组件之间的作用域说起
- "app" >
- var vm = new vue({
- el: '#app',
- components: {
- "add": {
- template: "<button>btn:{{btn}}</button>",
- data: function() {
- return {
- btn: "123"
- };
- }
- },
- del: {
- template: "<button>btn:{{btn}}</button>",
- data: function() {
- return {
- btn: "456"
- };
- }
- }
- }
- });
在这段代码里: 第一个的值是 123,第二个的值是 456(虽然他们都是 btn)但由于作用域不同, 所以不会互相影响
如何使用 props 绑定静态数据:
【1】这种方法用于传递字符串,且值是写在父组件自定义元素上的。
- <add btn="h">
- </add>
【2】下面示例中的写法,不能传递父组件 data 属性中的值
【3】会覆盖模板的 data 属性中,同名的值。
- var vm = new Vue({
- el: '#app',
- data: {
- name: "hello"
- },
- components: {
- "add": {
- props: ['btn'],
- template: "btn:{{btn}}",
- data: function() {
- return {
- btn: "123"
- };
- }
- }
- }
- });
这种写法下,btn 的值是 name,而不是 hello。
【4】驼峰写法
假如插值是驼峰式的,
而在 html 标签中,由于 html 的特性是不区分大小写(比如 LI 和 li 是一样的),因此,html 标签中要传递的值要写成短横线式的(如 btn-test),以区分大小写。
而在 props 的数组中,应该和插值保持一致,写成驼峰式的(如 btnTest)。
例如:
- props: ['btnTest'],
- template: "btn:{{btnTest}}",
正确的写法:
- <add btn-test="h">
- </add>
假如插值写短横线式,或者是 html 标签写成驼峰式,都不能正常生效。(除非插值不写成驼峰式——跳过大小写的限制,才可以)
利用 props 绑定动态数据:
简单来说,就是让子组件的某个插值,和父组件的数据保持一致。
标准写法是(利用 v-bind):
- <add v-bind:子组件的值="父组件的属性">
- </add>
如代码
- var vm = new Vue({
- el: '#app',
- data: {
- h: "hello"
- },
- components: {
- "add": {
- props: ['btn'],
- template: "btn:{{btn}}",
- data: function() {
- return {
- 'btn': "123"
- }; //子组件同名的值被覆盖了
- }
- }
- }
- });
说明:
【1】btn 使用的父组件 data 中 h 的值;
【2】子组件的 data 的函数中返回值被覆盖了。
【3】也就是说,使用 v-bind 的是使用父组件的值(根据属性名),没有使用 v-bind 的是将标签里的数值当做字符串来使用。
【4】依然需要使用 props,否则他会取用自己 data 里的 btn 的值
字面量和动态语法:
【1】简单来说,不加 v-bind 的,传递的是字面量,即当做字符串(例如 1 也是字符串,而不是 number 类型);
【2】加上 v-bind 的,传递的是 JS 表达式(因此才能传递父组件的值);
【3】加上 v-bind 后,如果能找到父组件的值,那么使用父组件的值;如果没有对应的,则将其看做一个 js 表达式(例如 1+2 看做 3,{a:1} 看做是一个对象);
- var vm = new Vue({
- el: '#app',
- data: {
- h: "hello"
- },
- components: {
- "add": {
- props: ['btn'],
- template: "btn:{{btn}}"
- }
- }
- });
这里的 btn 的值是 3(而不是没有加 v-bind 时,作为字符串的 1+2)
props 的绑定类型:
【1】简单来说,分为两种类型,即单向绑定(父组件能影响子组件,但相反不行)和双向绑定(子组件也能影响父组件);
【2】单向绑定示例:(默认,或使用. once)
- 父组件:
- 子组件:
- var vm = new Vue({
- el: '#app',
- data: {
- val: 1
- },
- components: {
- "test": {
- props: ['testVal'],
- template: ""
- }
- }
- });
说明:
当父组件的值被更改后,子组件的值也随之更改;
当子组件的值被更改后,父组件的值不会变化,而假如再次修改父组件的值,子组件会再次同步。
另外需要注意的是,子组件如果要同步绑定,那么子组件的 input 需要是 v-model,而不能是 value 属性(那样只能单项绑定,且修改子组件的值后会失去绑定)
【3】双向绑定:
需要使用 ".sync" 作为修饰词
如示例:
- 父组件:
- 子组件:
- var vm = new Vue({
- el: '#app',
- data: {
- val: 1
- },
- components: {
- "test": {
- props: ['test'],
- template: ""
- }
- }
- });
效果是无论你改哪一个的值,另外一个都会随之变动。
来源: http://www.cnblogs.com/Smiled/p/7250714.html