单向数据流
数据只能通过父组件传递给子组件 而不能从子组件传递给父组件 子组件也不能直接修改父组件的数据
- 当父组件的数据发生改变之后,子组件的收到的数据也会跟着变化
- 子组件想修改父组件的数据,只能通知父组件,让父组件修改数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<son :msg="pmsg"></son>
</div>
<script src="vue.js"></script>
<script>
let son = {
data() {
return {
hello: 'xxxx'
}
},
props: ['msg', 'changePMSG'],
template: '<span>{{msg}} <button @click="fn">dddd</button></span>',
methods: {
fn() {
this.msg = 1233; // props 中的数据也会代理到子组件的实例身上,可以直接通过 this 访问
}
}
};
let vm = new Vue({
el: '#app',
data: {
pmsg: 'msg from parent'
},
methods: {
changeMsg() {
this.pmsg = 123445
}
},
components: {
son
}
});
// 1. 子组件中的数据不能全是写死的,而是有一部分从父组件传递过来的
// 2. 为了把父组件的数据传递给子组件,子组件在标签上动态绑定一个属性,这个属性绑定父组件的数据,并且在子组件的props中注册这个属性
// 3. 子组件如果想使用父组件的数据,就使用对应的 props 就可以(父传子用props)
</script>
</body>
</html>
子传父
- 子组件传给父组件通过事件机制 通知父组件 让父组件修改数据
- 父组件中使用子组件时 要监听一个自定义的事件事件名不能写驼峰 如@change-msg=modify
- 子组件若想修改某个数据时 调用 this.$emit(事件名,数据)
- 子组件
emit的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<son :pmsg="msg" @change-msg="modify"></son>
</div>
<script src="vue.js"></script>
<script>
let son = {
data() {
return {
msg: '123'
}
},
template: `<div>{{pmsg}} <button @click="fn">修改</button></div>`,
props: ['pmsg'],
methods: {
fn() {
this.$emit('change-msg', '12345上山打老虎');
}
}
};
let vm = new Vue({
el: '#app',
data: {
msg: 'msg from parent'
},
methods: {
modify(val) {
// console.log(val);
this.msg = val;
}
},
components: {
son
}
});
</script>
</body>
</html>
props验证
props属性除了设置为一个数组还可以设置一个对象 key 是props名 值 是一个对象 在这个对象中可以设置默认值 以及对这个props的校验规则
常见的校验
- type:Number //校验类型 要求必须是某种类型 若类型不对会抛出警告
- required:true //必传校验 若不传会引发警告
- default:111 //设置默认值
- validator(val){} //验证器函数 若有问题可以抛出异常 没问题要return true
sync修饰符 和事件简写
sync修饰符 为了简化子传父
sync 使用
- 父组件在使用子组件时 在prop后面增加.sync修饰符 取消监听事件
- 子组件触发事件时 事件名写update:prop 属性名 父子组件都有mounted 先执行子组件的mounted 再执行父组件的mounted
动态组件 不同组件之间的动态切换
需要使用内置的component组件 组件上有一个is属性 动态绑定该属性 当被绑定的值发生变化时 Vue会渲染is嘴子女的值对应的组件
keep-alive 解决在组件切换时 原来的组件会销毁 数据会丢失
包裹动态组件时 会缓存不活动的组件实例 而不是销毁它们
事件总线 EventBus
每个组件都是一个Vue实例 相互之间不能互通数据 要修改数据一定要通知 因此找一个第三方监听事件 在事件触发时执行对应的修改数据的操作 这个第三方就是事件总线
用法
- 创建一个空的Vue实例 let EventBus = new Vue()
- eventBus.$on(自定义事件名,事件函数) 监听事件
- eventBus.$emit(事件名) 触发事件
插槽 slot
使用插槽机制 可以向组件的标签中嵌入内容 这些内容可以嵌入到子组件中
使用
- 在创建子组件时 需要声明一个slot标签占位
- 在组件标签中嵌入内容
具名slot
在声明时 不写name 属性 嵌入在组件标签中没有写slot属性的标签都会放在匿名的slot中
匿名slot
在声明时 要写上name属性 嵌入在组件标签中的内容需要指定slot= “slot的名字”