前言:
本期将会介绍 Vue 中的 watch 侦听器,它语法是怎么样的呢?具有怎样的功能呢?最后用模拟实现百度翻译来更进一步练习 watch 侦听器
篮球哥找工作专属IT岗位内部推荐:
专属内推链接:内推通道
1、认识翻译功能
翻译软件相信大家都不陌生,通常网页版的翻译就是,在给定的左侧文本框中输入英文,过一小会右侧的文本框就会给出中文的翻译。
实现这个翻译功能,这里先不考虑后端是如何执行翻译这个业务的,只考虑前端的设计。
设计方案:
① 可以是在用户输入 英文 后,假设 0.5s 中用户没有任何输入了,右侧文本框就会自动展示出翻译后的结果。
② 当用户输入 英文 后,需要敲回车,或者单击翻译按钮,右侧的文本框才会展示出翻译后的结果。
方案 ② 就容易实现一点,无非就是单击按钮,提交请求给后端翻译,就OK了,而方案 ① 相当于是捕捉用户的行为,自动的提交请求给后端翻译,这里就需要用到本期讲解的 Vue 中的 watch侦听器了!
2、watch侦听器(监视器)语法
首先需要先了解 watch 的作用:
监视数据变化,执行一些业务逻辑或异步操作
语法如下:
- watch同样声明在跟data同级的配置项中
- 简单写法: 简单类型数据直接监视
- 完整写法:添加额外配置项
js
data: {
words: 'hello',
obj: {
words: 'cat'
}
},
watch: {
// 该方法会在数据变化时,触发执行
words (newValue, oldValue) {
// code ... 一些业务逻辑 或 异步操作。
},
'obj.words' (newValue, oldValue) {
// code ... 一些业务逻辑 或 异步操作。
}
}
简单来说,就是在 watch 配置项中配置要监视的 数据名,或者对象,一旦监视的对象,的内容发生变化了,就会立刻执行配置项中对应的代码块。
有了上述的简单认识,后面就模拟实现一个翻译功能,来更直观的感受侦听器。
3、模拟实现翻译功能
这里直接看代码,主要关注最终的运行结果和 js 里面的代码部分。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 18px;
}
#app {
padding: 10px 20px;
}
.query {
margin: 10px 0;
}
.box {
display: flex;
}
textarea {
width: 300px;
height: 160px;
font-size: 18px;
border: 1px solid #dedede;
outline: none;
resize: none;
padding: 10px;
}
textarea:hover {
border: 1px solid #1589f5;
}
.transbox {
width: 300px;
height: 160px;
background-color: #f0f0f0;
padding: 10px;
border: none;
}
.tip-box {
width: 300px;
height: 25px;
line-height: 25px;
display: flex;
}
.tip-box span {
flex: 1;
text-align: center;
}
.query span {
font-size: 18px;
}
.input-wrap {
position: relative;
}
.input-wrap span {
position: absolute;
right: 15px;
bottom: 15px;
font-size: 12px;
}
.input-wrap i {
font-size: 20px;
font-style: normal;
}
</style>
</head>
<body>
<div id="app">
<!-- 条件选择框 -->
<div class="query">
<span>翻译成的语言:</span>
<select>
<option value="italy">意大利</option>
<option value="english">英语</option>
<option value="german">德语</option>
</select>
</div>
<!-- 翻译框 -->
<div class="box">
<div class="input-wrap">
<textarea v-model="obj.words"></textarea>
<span><i>⌨️</i>文档翻译</span>
</div>
<div class="output-wrap">
<div class="transbox">{{ result }}</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
const getRandomCharacter = () => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const randomIndex = Math.floor(Math.random() * characters.length);
return characters[randomIndex];
}
const getRandomEnglishString = (length) => {
let randomString = '';
for (let i = 0; i < length; i++) {
randomString += getRandomCharacter();
}
return randomString;
}
const app = new Vue({
el: '#app',
data: {
obj: {
words: ''
},
result: '', // 翻译结果
timer: null // 延时器
},
watch: {
// 该方法会在数据变化时调用执行
// newValue新值, oldValue老值(一般不用)
'obj.words' (newValue) {
// 防抖: 延迟执行 → 干啥事先等一等,延迟一会,一段时间内没有再次触发,才执行
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.result = getRandomEnglishString(10) // 随机生成长度为10的字符串
}, 300)
}
}
})
</script>
</body>
</html>
上述代码的功能就是,随便输入,300 毫秒未输入,就会自动更新 result 里面的只,代码层面看,就是当 obj.words 这个变量的值发生的变化,那么就会立马触发对应代码块的代码。
看到这可能有点小疑问,我难道不能直接侦听 obj 整个对象吗?当然可以,但是这里就需要用到深度监视了!
也就是后面要讲到的 watch 的完整写法。
4、watch 的深度监视
这里才是真正的 watch 的完整体。
完整写法 --->添加额外的配置项
- deep:true 对复杂类型进行深度监听
- immdiate:true 初始化 立刻执行一次
js
data: {
obj: {
words: 'hello',
lang: 'italy'
},
},
watch: {// watch 完整写法
obj: {
deep: true, // 深度监视
immdiate:true,//立即执行handler函数
handler (newValue) {
console.log(newValue)
}
}
}
深度监视,也就是 obj 这个对象中的 words 或者 lang 属性任何一个发生变化,都会立即执行里面的 handler 函数!
上面的模拟实现翻译的代码留了个小坑,当切换语言的时候,是不会触发翻译效果的,这时用上深度监听整个 obj 对象,就可以实现了,快去优化一下吧!