watch侦听器
方式一
1.默认有两个参数 newValue与oldValue
2.如果是对象类型那么拿到的是代理对象
如果要进行深度监听 需要加上
deep : true
如果想要第一次渲染直接执行一次监听器
immediate : true
Vue.toRaw 获取原始对象
watch: {
message(newValue, oldValue) {
console.log("message数据发生变化", newValue, oldValue);
},
info(newValue, oldValue) {
console.log(Vue.toRaw(newValue));
},
方式二
使用this.$watch进行监听
1.第一个参数是要侦听的源
2.第二个参数是侦听的回调函数
3.第三个参数是额外的其他选项 如deep immediate
created() {
console.log("created");
this.$watch(
"message",
(newValue, oldValue) => {
console.log("message数据变化", newValue, oldValue);
},
{ deep: true }
);
},
组件间的通信
父子组件间的通信方式
父组件传递给子组件 通过props
子组件传递给父组件 通过$emit触发
什么是props
props是你可以在组件上注册一些自定义的attribute
父组件给这些attribute赋值 子组件通过attribute的名称获取到对应的值
props 有两种常见的用法
方式一:字符串数组 数组中的字符串就是attribute的名称
方式二:对象类型 对象类型我们可以在指定attribute名称的同时 指定它需要传递的类型 是否是必须的 默认值等
props数组语法
弊端:1.不能进行类型检测 2.没有默认值
props: ["name", 'age', 'height']
props对象语法
对象类型的默认值要是函数
props: {
name: {
type: String,
default: '我是默认的name'
},
age: {
type: Number,
required: true,
default: 0
},
height: {
type: Number,
default: 2
},
friend: {
type: Object,
default: () => ({ name: 'james' })
type的类型
String
Number
Boolean
Array
Object
Date
Function
Symbol
Props的大小写命名
HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符;
这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名)
命名;
对于非Prop的Attribute
什么是非Prop的Attribute
当我们传递给一个组件某个属性 当时该属性并没有定义对应的props或者emits时 就称为非Props的Attribute
常见的包括class style id属性等
如果当组件有单个根节点时 并且当前的属性是一个非props的attribute 那么该属性会默认添加到子组件的根元素上
如果我们不希望组件的根元素继承attribute 可以在组件中设置inheritAttrs:false
export default {
inheritAttrs: false
}
禁用attribute继承的常见情况是需要将attribute应用于根元素之外的其他元素
我们可以通过$attrs来访问所有的非props的attribute
<div>
非Prop的Attribute
<h2 :class="$attrs.class"></h2>
</div>
多个根节点的attribute
多个根节点的attribute如果没有显示的绑定 那么会报警告 我们必须手动的指定要绑定到哪一个属性上
<template>
<div :class="$sttrs.class">非Prop的Attribute1</div>
<div>非Prop的Attribute2</div>
</template>
子组件传递给父组件
什么情况下子组件需要传递内容给父组件的?
1.当子组件有一些事件发生的时候 比如在组件中发生了点击 父组件需要切换内容
2.子组件有一些内容想要传递给父组件的时候
如何完成上述操作
1.在子组件中定义好在某些情况下触发的事件名称
2.在父组件中以v-on的方式传入要监听的事件的名称 并且绑定到对应的方法中
3.在子组件中发生某个事件的时候 根据事件名称触发对应的事件
emits数组写法
emits:['add']
emits的对象写法 对传递的参数进行验证 很少用
emits:{
add:function(count){
if(count <= 10){
return true
}
return false
}
}
自定义事件的时候 我们也可以传递一些参数给父组件
第一个参数 自定义的事件名称
第二个参数 传递的参数
btnClick(count) {
this.$emit('add', count)
}
在vue3中我们可以对传递的参数进行验证
emits:{
addOne:null;
addTen:function(playload){
if(playload === 10){
return true
}
return false
}
}
综合案例 点击按钮数字加加
<template>
<div class="app">
<h2>当前计数 :{{counter}}</h2>
<!-- 自定义add-counter 并监听内部add事件 -->
<add-counter @add="addBtnClick"></add-counter>
</div>
</template>
<script>
import AddCounter from './AddCounter.vue'
import SubCounter from './SubCounter.vue'
export default {
data() {
return {
counter: 0
}
},
components: {
AddCounter,
SubCounter,
},
methods: {
addBtnClick(count) {
this.counter += count
},
subBtnClick(count) {
this.counter += count
}
}
}
</script>
<template>
<div class="add">
<button @click="btnClick(1)">+1</button>
<button @click="btnClick(5)">+5</button>
<button @click="btnClick(10)">+10</button>
</div>
</template>
<script>
export default {
emits: {
add: function (count) {
if (count <= 10) {
return true
}
return false
}
},
methods: {
btnClick(count) {
this.$emit('add', count)
}
}
}
</script>