vue之props数据传递(单向,双向sync)
2018-07-30 本文已影响300人
world_7735
学习vue必不可少的一个环节就是数据之间的传递,下面我们详细介绍下父组件如何向子组件传递数据的。
1组件实例的作用域
组件是孤立的,简单的来说,组件和组件之间,即使有同名属性,值也不共享。案例如下:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<add></add>
<del></del>
</div>
</body>
</html>
<script>
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"};
}
}
}
});
</script>
渲染结果:
2个按钮,第一个的值是123,第二个的值是456(虽然他们都是btn)
2使用props绑定静态数据
(1)这种方法用于传递字符串,且值是写在父组件自定义元素上的。
(2)下面示例中的写法,不能传递父组件data属性中的值
(3)会覆盖模板的data属性中,同名的值。
案例如下:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<add btn="h"></add>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: '#app',
data: {
h: "hello"
},
components: {
"add": {
props: ['btn'],
template: "<button>btn:{{btn}}</button>",
data: function () {
return {btn: "123"};
}
}
}
});
</script>
渲染结果:
btn的值是h,即不是123也不是hello。
(4)驼峰写法
假如插值是驼峰式的,
而在html标签中,由于html的特性是不区分大小写(比如LI和li是一样的),因此,html标签中要传递的值要写成短横线式的(如btn-test),以区分大小写。
而在props的数组中,应该和插值保持一致,写成驼峰式的(如btnTest)。
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<add btn-test="h"></add>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: '#app',
data: {
h: "hello"
},
components: {
"add": {
props: ['btnTest'],
template: "<button>btn:{{btnTest}}</button>",
data: function () {
return {btn: "123"};
}
}
}
});
</script>
渲染结果:
btn的值是h
3利用props绑定动态数据
简单来说,就是让子组件的某个插值,和父组件的数据保持一致。
标准写法是(利用v-bind):
(1)btn使用的父组件data中 h的值;
(2)子组件的data的函数中返回值被覆盖了。
(3)也就是说,使用v-bind的是使用父组件的值(根据属性名),没有使用v-bind的是将标签里的数值当做字符串来使用。
(4)依然需要使用props,否则他会取用自己data里的btn的值
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<add v-bind:btn="h"></add>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: '#app',
data: {
h: "hello"
},
components: {
"add": {
props: ['btn'],
template: "<button>btn:{{btn}}</button>",
data: function () {
return {'btn': "123"}; //子组件同名的值被覆盖了
}
}
}
});
</script>
props的绑定类型:
(1)单向绑定
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
父组件:
<input v-model="val"><br/>
子组件:
<test v-bind:test-Val="val"></test>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: '#app',
data: {
val: 1
},
components: {
"test": {
props: ['testVal'],
template: "<input v-model='testVal'/>"
}
}
});
</script>
说明:
当父组件的值被更改后,子组件的值也随之更改;
当子组件的值被更改后,父组件的值不会变化,而假如再次修改父组件的值,子组件会再次同步。
另外需要注意的是,子组件如果要同步绑定,那么子组件的input需要是v-model,而不能是value属性(那样只能单项绑定,且修改子组件的值后会失去绑定)
(2)双向绑定:
需要使用“.sync”作为修饰词
如示例:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
父组件:
<input v-model="val"><br/>
子组件:
<test :test.sync="val"></test>
</div>
</body>
</html>
<script>
var vm = new Vue({
el: '#app',
data: {
val: 1
},
components: {
"test": {
props: ['test'],
template: '<div @click="increment">{{test}}</div>',
methods: {
increment: function() {
this.$emit('update:test', ++this.test);
}
}
}
}
});
</script>