# 计算属性
计算属性本质上就是一个function 函数, 它可以实时监听data 中数据的变化,并return 一个计算后的新值,供组件渲染 DOM 时使用
# 声明计算属性
计算属性需要以function 函数的形式声明到组件的computed 节点中,示例代码如下
<input type="text" v-model.number="count"> | |
<p>{count}乘以 2 的值为:{ plus } </p> | |
<script> | |
export default { | |
data(){ | |
return{ | |
count:1, | |
} | |
}, | |
computed:{ | |
plus(){ // 计算属性,监听 data 中 count 的变化,自动计算出 count * 2 之后的新值 | |
return this.count * 2 | |
} | |
} | |
} | |
</script> |
# 计算属性的使用注意点
- 计算属性必须定义在 computed 节点中
- 计算属性必须是一个 function 的函数
- 计算属性必须有 return 返回值!!
- 计算属性必须当作普通属性使用
# 计算属性 vs 方法
相对于方法来说,计算属性会缓存计算的结果,只有计算属性的依赖项发生变化时,才会重新进行运算,因此计算属性的性能更好
# 自定义事件
在封装组件时,为了让组件的使用者可以监听到组件内状态的变化,此时需要用到组件的自定义事件
# 自定义事件的 3 个使用步骤
- 在封装组件时
# 声明自定义事件
开发者为自定义组件封装的自定义事件,必须事先在emits节点中声明
export default{ | |
// 1. 声明自定义事件 | |
emits:['change'], | |
} |
# 触发自定义事件
在emits节点下声明的自定义事件,可以通过this.$emit(' 自定义事件的名称 ') 方法进行触发
<template> | |
<div> | |
<p>count的值是:<!--swig0--></p> | |
<button @click="add">+1</button> | |
</div> | |
</template> | |
<script> | |
export default{ | |
// 1. 声明自定义事件 | |
emits:['countChange'], | |
methods: { | |
add() { | |
this.count++ | |
// 2.this.$emit () 触发自定义事件 | |
this.$emit('countChange') | |
} | |
} | |
} | |
</script> |
- 在使用组件时
# 监听自定义事件
在使用自定义的组件时,可以通过v-on的形式监听自定义事件。
<Counter @countChange="getCount"></Counter> | |
methods: { | |
getCount() { | |
console.log('触发countChange事件') | |
} | |
} |
# 自定义事件传参。
在调用this.$emit()方法触发自定义事件时,可以通过第二个参数为自定义事件传参
this.$emit('countChange', this.count) // 触发自定义事件时,通过第二个参数传参 | |
====================== | |
// 外界在监听 countChange 自定义事件时候可以通过事件处理函数的形参拿到最新的 count 值 | |
getCount(val) { | |
console.log('触发countChange事件,count值为:' + val) | |
} |
# watch 监听器
watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做待定的操作。例如监视用户名的变化并发起请求,判断用户是否可用。
# watch 侦听器的基本语法
开发者需要在 watch 节点下,定义自己的侦听器,要监听那个数据项的变化,就把那个数据项的名字作为方法的名称。
形参列表中,第一个参数代表 变化后的新值 ,第二个参数是 变化之前的旧值
export default { | |
data() { | |
return { | |
username: '', | |
} | |
}, | |
watch: { | |
username(newVal, oldVal) { | |
console.log('新:' + newVal, '旧:' + oldVal) | |
}, | |
} | |
} |
# 小案例:检测用户名是否可用
监听 username 值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用
export default { | |
data() { | |
return { | |
username: '', | |
available: ' ', | |
} | |
}, | |
// 侦听器 | |
watch: { | |
async username(newVal, oldVal) { | |
const {data: res} = await axios.get(`https://www.escook.cn/api/finduser/${newVal}`) | |
this.available = res.message; | |
}, | |
} | |
} |
# immediate 选项
默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用immediate选项。
非常简单 watch 节点里加一个 immediate:true
即可
watch: { | |
async username(newVal, oldVal) { | |
const {data: res} = await axios.get(`https://www.escook.cn/api/finduser/${newVal}`) | |
this.available = res.message; | |
}, | |
// 组件加载完毕后立即调用一次当前的 watch 侦听器 | |
immediate:true | |
} |
# deep 选项
当watch 侦听的是一个对象,如果对象中属性值发生了变化,则无法被监听到。此时需要使用deep 选项
export default { | |
data() { | |
return { | |
username: '', | |
available: ' ', | |
info: { | |
username: 'zs' | |
} | |
} | |
}, | |
watch: { | |
info: { | |
//handler 属性是固定写法:当 username 发生了变化,调用 handler | |
async handle(newVal) { | |
const {data: res} = await axios.get(`https://www.escook.cn/api/finduser/` + newVal) | |
this.available = res.message; | |
}, | |
deep: true | |
}, | |
} | |
} |
# 监听对象单个属性的变化
只想监听 info.username 的属性变化,可以把这个访问列声明过来即可
export default { | |
data() { | |
return { | |
username: '', | |
available: ' ', | |
info: { | |
username: 'zs', | |
password:'' | |
} | |
} | |
}, | |
// 侦听器 | |
watch: { | |
'info.username': { // 只想监听 info.username 属性值的变化 | |
async handle(newVal) { | |
const {data: res} = await axios.get(`https://www.escook.cn/api/finduser/` + newVal) | |
this.available = res.message; | |
}, | |
deep: true | |
}, | |
} | |
} |