第九章 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>
相关推荐
bin91534 小时前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云6 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
学代码的小前端8 小时前
0基础学前端-----CSS DAY13
前端·css
engchina10 小时前
@media 的常用场景与示例
css·media
林的快手11 小时前
CSS列表属性
前端·javascript·css·ajax·firefox·html5·safari
计算机-秋大田12 小时前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
禾苗种树13 小时前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
小盼江14 小时前
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程
vue.js·spring boot·ui
初遇你时动了情15 小时前
react module.scss 避免全局冲突类似vue中scoped
vue.js·react.js·scss
烂蜻蜓16 小时前
Uniapp 设计思路全分享
前端·css·vue.js·uni-app·html