第九章 Vue之watch监听器

目录

一、引言

二、简单写法

三、完整写法


一、引言

作用:监视数据的变化,一旦数据发生变化则执行相应的业务逻辑或异步操作。

语法:

① 简单写法 → 简单类型数据,直接监视

② 完整写法 → 添加额外配置项

(1) deep: true 对复杂类型深度监视

(2) immediate: true 初始化立刻执行一次handler方法

二、简单写法

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="vue.js"></script>
    <script src="axios.js"></script>
    <script>
      // 接口地址:https://vuetest.wzx.net/api/translate 这是我个人后端部署的翻译服务,
      // 你们可以在本地简单部署一个能够请求的服务即可,不需要完整地编写翻译功能,具体看个人情况。
      // 请求方式:get
      // 请求参数:
      // (1)words:需要被翻译的文本(必传)
      // (2)lang: 需要被翻译成的语言(可选)默认值-意大利
      // -----------------------------------------------
      
      const app = new Vue({
        el: '#app',
        data: {
          // words: '',
          obj: {
            words: ''
          },
          // 翻译结果
          result: '',
          // 存放延迟器id
          // timer: null 跟页面渲染无关的情况下,可以注释掉,效果一样
        },
        // 具体讲解:(1) watch语法 (2) 具体业务实现
        watch: {
          // 该方法会在数据变化时调用执行
          // newValue新值, oldValue老值(一般情况用不到)
          // 以下两种写法都可以
          // 写法1
          // words (newValue, oldValue) {

          // }
          // 写法2
          // 'obj.words' (newValue, oldValue) {

          // }

          'obj.words' (newValue) {
            // 这边我们为了增强访问的稳定性做一个防抖:延迟执行,一段时间内没有再次触发更新,计时器才重新计时并执行(避免大量请求),
            // 否则会不停地清空计时器暂停请求
            clearTimeout(this.timer)
            // this.timer是把这个计时器直接挂到Vue实例上
            this.timer = setTimeout(async () => {
              const res = await axios({
                url: 'https://vuetest.wzx.net/api/translate',
                params: {
                  words: newValue
                }
              })
              // 将请求的结果更新到Vue实例的result属性中
              this.result = res.data.data
            // 设置等待300毫秒后执行  
            }, 300)
          }
        }
      })
    </script>
  </body>
</html>

三、完整写法

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 v-model="obj.lang">
          <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="vue.js"></script>
    <script src="axios.js"></script>
    <script>
      // 接口地址:https://vuetest.wzx.net/api/translate 这是我个人后端部署的翻译服务,
      // 你们可以在本地简单部署一个能够请求的服务即可,不需要完整地编写翻译功能,具体看个人情况。
      // 请求方式:get
      // 请求参数:
      // (1)words:需要被翻译的文本(必传)
      // (2)lang: 需要被翻译成的语言(可选)默认值-意大利
      // -----------------------------------------------
      
      const app = new Vue({
        el: '#app',
        data: {
          obj: {
            words: '',
            lang: 'italy'
          },
          // 翻译结果
          result: ''
        },
        // 具体讲解:(1) watch语法 (2) 具体业务实现
        watch: {
          obj: {
            deep: true,
            immediate: true,
            // 这里的newValue是obj对象
            handler (newValue) {
              clearTimeout(this.timer)
              this.timer = setTimeout(async () => {
                const res = await axios({
                  url: 'https://vuetest.wzx.net/api/translate',
                  // 将整个对象作为参数传递给后端服务接口 words=xxx&lang=italy
                  params: newValue
                })
                this.result = res.data.data
              }, 300)
            }
          }
        }
      })
    </script>
  </body>
</html>
相关推荐
荆州克莱1 小时前
微信小程序获取位置服务
spring boot·spring·spring cloud·css3·技术
热忱11281 小时前
elementUI Table组件实现表头吸顶效果
前端·vue.js·elementui
大叔_爱编程2 小时前
wx035基于springboot+vue+uniapp的校园二手交易小程序
vue.js·spring boot·小程序·uni-app·毕业设计·源码·课程设计
zhaocarbon2 小时前
VUE elTree 无子级 隐藏展开图标
前端·javascript·vue.js
匹马夕阳5 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?5 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
沈梦研12 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
刻刻帝的海角12 小时前
CSS 颜色
前端·css
轻口味12 小时前
Vue.js 组件之间的通信模式
vue.js
fmdpenny15 小时前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js