父组件的数据写在标签中,子组件利用props接收,并且可以加上传入的限制。由于:绑定是单向的,所以后续父组件修改变量,子组件中的数据也会相应改变。
<comp-a c="1" d="2"></comp-a>
<comp-b
:count="count"
:num="1"
:str2="'hello'"
:bool="true"
:a="null"
:b="undefined"
:arr="[1,2,3]"
:obj="{a:1,b:2}"
:data-id="100"
:data-option-id="200"
></comp-b>
let compB = {
props: {
// 对象的键名就是要接受的属性名 => 对应属性名接收数据
// 对象的健值就是需要接收的数据的类型 => 如果接收的数据不是指定类型会报错
num: {
type: Number, // 接收数据的类型
required: true, // 必填
},
str2: String,
bool: {
type: Boolean,
default: false, //默认值
},
a: null,
b: undefined,
arr: Array,
obj: Object,
// "data-id": Number,
dataId: Number,
dataOptionId: Number,
count: {
// type: Number,
// 自定义验证函数 => 接收数据后,或先执行验证函数,如果函数返回true -> 验证成功,false->验证失败
validator: function (value) {
console.log("value", value);
if (!value) return false; // 必填
if (typeof value == "number") {
// 类型
if (value >= 0 && value <= 100 && value % 1 == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
},
},
},
那么问题来了,如果子组件想要修改父元素的数据,如果实现呢?
子父通信
- 父组件需要提供数据count,以及自定义事件update:count,和对应的事件触发函数。如果子组件用emit触发了事件uodate:count,那么父组件就会自己执行对应的函数
<div id="app">
<p>{{count}}</p>
<button @click="count++">父控子</button>
<comp-a :count1="count" @update:count="updateCountHanlder"></comp-a>
</div>
</body>
<script>
let compA = {
props: ["count1"],
template: `<div class="compA">
<p>{{count1}}</p>
<input
type="button"
value="子控父"
@click="$emit('update:count',count1)"
/>
</div>`,
};
let app = new Vue({
el: "#app",
data: {
count: 1,
},
methods: {
updateCountHanlder(val) {
this.count = val + 1;
},
},
components: {
"comp-a": compA,
},
});
</script>
</html>
针对于子父通信,我们可以选择sync简写,这个是vue2专用的。
使用时: :参数.sync='变量'
默认绑定自定义事件: @update:参数="(v)=> 变量 = v"
简单来说,加了.sync之后,可以省略 @update:count="updateCountHanlder",因为vue会自动将自定义事件和对应的函数绑定起来,函数的内容默认是将接收的值赋值给父组件的元素,另外自定义事件的名字也是固定的,不可以乱改。
<body>
<div id="app">
<p>{{count}}</p>
<button @click="count++">父控子</button>
<comp-a :count1.sync="count"></comp-a>
</div>
</body>
<script>
let compA = {
props: ["count1"],
template: `<div class="compA">
<p>{{count1}}</p>
<input
type="button"
value="子控父"
@click="$emit('update:count1',count1+1)"
/>
</div>`,
};
let app = new Vue({
el: "#app",
data: {
count: 1,
},
methods: {
// updateCountHanlder(val) {
// this.count = val;
// },
},
components: {
"comp-a": compA,
},
});
</script>
</html>