一、prop 校验
使用带校验的 props,props 的值不再是数组而是一个对象,对象的属性名就是注册的 prop,属性值是一个对象,这个对象中包含了校验规则,如果不符合规则会引发警告;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<child :msg="pmsg"></child>
</div>
<script src="vue.js"></script>
<script>
let child = {
template: `<div>{{msg}}</div>`,
data() {
return {}
},
props: {
msg: {
type: Number, // 校验类型
required: true, // 如果为 true 必传,不传就会报错
// default: 200, // 默认值
default() {
// 如果默认值是一个对象或者数组,default 要写成一个函数,在函数中 return 这个对象或者数组
return {
name: '马宾',
age: 18
}
},
validator(val) {
// validator 是自定义的校验函数
// val 就是这个 prop 收到的值
// 自定义校验规则,如果校验通过 return true,否则抛出异常或者 return false
if (val >= 250) {
// throw new Error('你真是个250');
console.error('你真是250');
return false;
} else {
return true
}
}
}
}
};
let vm = new Vue({
el: '#app',
data: {
pmsg: 250
},
components: {
child
}
})
</script>
</body>
</html>
二、sync 修饰符和事件简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--使用 sync 修饰符可以简化子组件向父组件传递数据的过程;-->
<!--1. 在父组件使用子组件时,prop 后面跟一个 .sync ,然后取消显式声明的事件监听-->
<!--2. 子组件触发事件:this.$emit('update:prop 名字', 新数据)-->
<child :msg.sync="pmsg"></child>
</div>
<script src="vue.js"></script>
<script type="module">
import child from './2-child.js';
let vm = new Vue({
el: '#app',
data() {
return {
pmsg: 'hello from parent'
}
},
methods: {
},
components: {
child
}
})
</script>
</body>
</html>
child.js
export default {
template: `<div>{{msg}} <button @click="changeMsg">修改msg</button></div>`,
props: {
msg: {
type: [String, Number] // 类型校验有多个类型可以用一个数组
}
},
methods: {
changeMsg() {
// 把 msg 修改成 呵呵
// 配合 sync 修饰符,简化事件写法 :this.$emit('update:prop名', 数据)
this.$emit('update:msg', '呵呵')
}
}
}
三、父子组件 mounted
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
margin: 0;
padding: 0;
}
.modal {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, .5);
}
.modal .content {
width: 400px;
height: 300px;
padding: 15px;
background: #00b38a;
}
</style>
</head>
<body>
<div id="app">
<button @click="openModal">打开</button>
<modal :open.sync="flag" ref="theModal"></modal>
</div>
<script src="vue.js"></script>
<script type="module">
import modal from './3-modal.js';
let vm = new Vue({
el: '#app',
data() {
return {
flag: true
}
},
methods: {
openModal() {
this.flag = true;
}
},
components: {
modal
},
mounted() {
console.log('y');
// 当父子组件都有 mounted 时,子组件的 mounted 先执行;
// 每个组件都是一个 Vue 的实例,子组件的 mounted 先执行,方便父组件获取子组件的实例;
console.log(this.$refs.theModal); // ref 如果加在原生的 DOM 元素上,通过 ref 获取的是原生的 DOM 对象;如果加在组件上,获取的是这个组件实例的一个引用;拿到这个实例后可以
// 访问上面的数据、调用组件的方法
// debugger;
// this.$refs.theModal.closeModal(); // 调用子组件上的closeModal
}
})
</script>
</body>
</html>
四、动态组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
<label>HOME: <input type="radio"
v-model="title"
value="home"></label>
<label>LIST: <input type="radio"
value="list"
v-model="title"></label>
<!--条件渲染-->
<!--<home v-show="title == 'home'"></home>
<list v-show="title == 'list'"></list>-->
<!--动态组件-->
<component :is="title"></component>
<!--动态组件是实现在多个组件间来回切换,用法;-->
<!--1. 写一个内置的 component 组件-->
<!--2. 给 component 动态绑定 is 属性,当 is 属性绑定的值发生变化时,Vue 会按照 is 绑
定的最新的值自动渲染对应的组件-->
<!--失活的组件会被销毁,存在实例中的数据都被销毁了-->
</div>
</div>
<script src="vue.js"></script>
<script>
// 动态组件:
let home = {
template: '<div>HOME:<input type="text" v-model="home"></div>',
data() {
return {
home: ''
}
},
beforeDestroy() {
console.log('HOME 要销毁了');
},
destroyed() {
console.log('HOME 真的被销毁了');
}
};
let list = {
template: '<div>LIST:<input type="text" v-model="list"></div>',
data() {
return {
list: ''
}
},
beforeDestroy() {
console.log('LIST 要销毁了');
},
destroyed() {
console.log('LIST 真的被销毁了');
}
};
let vm = new Vue({
el: '#app',
data() {
return {
title: 'home'
}
},
components: {
// home: home,
// list: list
home,
list
}
})
</script>
</body>
</html>
五、动态组件-keep-alive
<body>
<div id="app">
<div>
<label>HOME: <input type="radio"
v-model="title"
value="home"></label>
<label>LIST: <input type="radio"
value="list"
v-model="title"></label>
<keep-alive>
<component :is="title"></component>
</keep-alive>
<!--keep-alive 也是内置的组件,它可以让失活的组件不销毁,所以保存在组件实例中的数据也不会销毁-->
<!--动态组件常和 keep-alive 一起使用-->
</div>
</div>
<script src="vue.js"></script>
<script>
// 动态组件:
let home = {
template: '<div>HOME:<input type="text" v-model="home"></div>',
data() {
return {
home: ''
}
},
beforeDestroy() {
console.log('HOME 要销毁了');
},
destroyed() {
console.log('HOME 真的被销毁了');
}
};
let list = {
template: '<div>LIST:<input type="text" v-model="list"></div>',
data() {
return {
list: ''
}
},
beforeDestroy() {
console.log('LIST 要销毁了');
},
destroyed() {
console.log('LIST 真的被销毁了');
}
};
let vm = new Vue({
el: '#app',
data() {
return {
title: 'home'
}
},
components: {
// home: home,
// list: list
home,
list
}
})
</script>