Watch(监视器)+(综合案例)

Watch侦听器(监视器)

作用:监视数据变化,执行一些业务逻辑或异步操作
语法:
①简单写法 → 简单类型数据,直接监视
②完整写法 → 添加额外配置项
在这里插入图片描述

①简单写法

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</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>文档翻译</span>
        </div>
        <div class="output-wrap">
            <div class="transbox">meal</div>
        </div>
    </div>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data:{
                //words:''
                obj:{
                    words:''
                }
            },
            //该方法会在数据变化时调用执行
            //newValue新值,oldValue老值(一般不用,可以删掉)
            // words(newValue,oldValue){

            // }
			watch:{
            	'obj.words' (newValue){
                	console.log('变化了',newValue)
            	}
            }
        })
    </script>
</body>
</html>

以下部分为上述代码的业务实现👇(延时器:防抖)
在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .output-wrap{
            width: 200px;
            height: 200px;
            background-color: aquamarine;
        }
    </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>文档翻译</span>
        </div>
        <div class="output-wrap">
            <div class="transbox">{{ result }}</div>
        </div>
    </div>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //接口地址:https://applet-base-apl-t.ithelma.net/api/translate
        //请求方式:get
        //请求参数:
        // 1.words:需要被翻译的文本(必传)
        // 2.lang:需要被翻译成的语言(可选)默认值-意大利
        const app = new Vue({
            el:'#app',
            data:{
                obj:{
                    words:'',
                    lang:'italy'
                },
                result:'',//翻译结果
                
            },
            watch:{
                'obj.words' (newValue){
                   clearTimeout(this.timer)
                   this.timer = setTimeout (async () => {
                    const res = await axios({
                        url:'https://applet-base-api-t.itheima.net/api/translate',
                        params:{
                            words:newValue
                        }
                    })
                    this.result = res.data.data
                    console.log(res.data.data)
                   },300)
                },     //如果每次都要写一遍这个,太麻烦了修改此方法,可以一次性全部监视

            }
        })
    </script>
</body>
</html>

②完整写法

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .output-wrap{
            width: 200px;
            height: 200px;
            background-color: aquamarine;
        }
    </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>文档翻译</span>
        </div>
        <div class="output-wrap">
            <div class="transbox">{{ result }}</div>
        </div>
    </div>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //接口地址:https://applet-base-apl-t.ithelma.net/api/translate
        //请求方式:get
        //请求参数:
        // 1.words:需要被翻译的文本(必传)
        // 2.lang:需要被翻译成的语言(可选)默认值-意大利
        const app = new Vue({
            el:'#app',
            data:{
                obj:{
                    words:'我是你爸爸',
                    lang:'italy'
                },
                result:'',//翻译结果
            },
            watch:{
            //完整写法要写成一个对象
                obj:{
                    deep:true,//深度监视:对所有都进行监视
                    immediate:true,//立刻执行,已进入页面,handler就立刻执行一次
                    handler (newValue) {//此时 handler只会在数据修改的时候触发,所以如果先设定的话,他不会自动翻译,要输入一下才能翻译 
                        //所以就要用到第二个配置项:immediate:true
                        clearTimeout(this.timer)
                        this.timer = setTimeout (async () => {
                            const res = await axios({
                                url:'https://applet-base-api-t.itheima.net/api/translate',
                                params: newValue//{
                                    //因为默认值是意大利,所以除了传words,还要传langi
                                    //words:newValue  
                                    //这里的newValue包括了words和lang,所以可以直接丢newValue
                                //}
                            })
                            this.result = res.data.data
                            console.log(res.data.data)
                        },300)
                    }
                }


                // 'obj.words' (newValue){
                //    clearTimeout(this.timer)
                //    this.timer = setTimeout (async () => {
                //     const res = await axios({
                //         url:'https://applet-base-api-t.itheima.net/api/translate',
                //         params:{
                //             words:newValue
                //         }
                //     })i
                //     this.result = res.data.datai
                //     console.log(res.data.data)
                //    },300)
                // },     如果每次都要写一遍这个,太麻烦了修改此方法,可以一次性全部监视

            }
        })
    </script>
</body>
</html>

案例:水果购物车

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

</head>
   <body>
     <div class="app-container" id="app">
       <!-- 顶部banner -->
       <div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" /></div>
       <!-- 面包屑 -->
       <div class="breadcrumb">
         <span>🏠</span>
         /
         <span>购物车</span>
       </div>
       <!-- 购物车主体 -->
       <div class="main" v-if="fruitList.length >0">
         <div class="table">
           <!-- 头部 -->
           <div class="thead">
             <div class="tr">
               <div class="th">选中</div>
               <div class="th th-pic">图片</div>
               <div class="th">单价</div>
               <div class="th num-th">个数</div>
               <div class="th">小计</div>
               <div class="th">操作</div>
             </div>
           </div>
           <!-- 身体 -->
           <div class="tbody">
             <div v-for="(item,index) in fruitList" :key="item.id" class="tr" :class="{active:item.isChecked}">
               <div class="td"><input type="checkbox" v-model="item.isChecked" /></div>
               <div class="td"><img :src="item.icon" alt="" /></div>
               <div class="td">{{ item.price }}</div>
               <div class="td">
                 <div class="my-input-number">
                   <button :disabled="item.num <=1" class="decrease" @click="sub(item.id)"> - </button>
                   <span class="my-input__inner">{{ item.num }}</span>
                   <button class="increase" @click="add(item.id)"> + </button>
                 </div>
               </div>
               <div class="td">{{ item.num * item.price }}</div>
               <div class="td"><button @click="del(item.id)">删除</button></div>
             </div>
           </div>
         </div>
         <!-- 底部 -->
         <div class="bottom">
           <!-- 全选 -->
           <label class="check-all">
             <input type="checkbox" v-model="isAll" />
             全选
           </label>
           <div class="right-box">
             <!-- 所有商品总价 -->
             <span class="price-box">总价&nbsp;&nbsp;:&nbsp;&nbsp;¥&nbsp;<span class="price">{{ totalPrice }}</span></span>
             <!-- 结算按钮 -->
             <button class="pay">结算( {{ totalCount }} )</button>
           </div>
         </div>
       </div>
       <!-- 空车 -->
       <div class="empty" v-else>🛒空空如也</div>
     </div>
     <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
     <script>
       const defaultArr = [
             {
               id: 1,
               icon: './火龙果.png',
               isChecked: true,
               num: 2,
               price: 6,
             },
             {
               id: 2,
               icon: './荔枝.png',
               isChecked: false,
               num: 7,
               price: 20,
             },
             {
               id: 3,
               icon: './榴莲.png',
               isChecked: false,
               num: 3,
               price: 40,
             },
             {
               id: 4,
               icon: './鸭梨.png',
               isChecked: true,
               num: 10,
               price: 3,
             },
             {
               id: 5,
               icon: './樱桃.png',
               isChecked: false,
               num: 20,
               price: 34,
             },
           ]
       const app = new Vue({
         el: '#app',
         data: {
           // 水果列表
           fruitList:JSON.parse(localStorage.getItem('list')) || defaultArr,
         },
         computed:{
            // isAll () {
            //     //必须所有的小选框都选中,全选按钮才选中 → every
            //     return this.fruitList.every(item => item.isChecked)//本身就是一个布尔值,所以=== true可以不写
            // }

            //完整写法=get + set
            isAll:{
                get (){
                    return this.fruitList.every(item => item.isChecked)
                },
                set (value){
                    //基于拿到的布尔值,要让所有的小选框,同步状态
                    this.fruitList.forEach(item => item.isChecked = value)//一个等号赋值
                }
            },
            //统计选中的总数 
            totalCount(){
                return this.fruitList.reduce((sum,item) => {
                    if (item.isChecked){
                        //选中,需要累加
                        return sum + item.num
                    } else{
                        //没选中,不需要累加
                        return sum
                    }
                },0)
            },
            //总计选中的总价 num* price,把这个再做累加
            totalPrice(){
                return this.fruitList.reduce((sum,item) => {
                    if (item.isChecked) {
                        return sum + item.num * item.price
                    }else {
                        return sum
                    }
                },0)
            }
         },
         methods:{
            del(id){
                this.fruitList = this.fruitList.filter(item => item.id !== id)
            },
            
            add (id){
               //1.根据id找到数组中的对应项 → find
               const fruit = this.fruitList.find(item => item.id === id)//是否和传过来的id相同,
                                                                        //如果是,那么就是它,然后操作数量
               //2.操作num数量
               fruit.num++
            },
            sub(id){
                //1.根据id找到数组中的对应项 → find
               const fruit = this.fruitList.find(item => item.id === id)//是否和传过来的id相同,
                                                                        //如果是,那么就是它,然后操作数量
               //2.操作num数量
               fruit.num--
            }
         },
         watch:{
            fruitList:{
                deep:true,
                handler( newValue){
                    // 需要将变化后的 newValue 存入本地 (转JSON)
                    localStorage.setItem('list',JSON.stringify(newValue))
                }
            }
         }
       })
     </script>
   </body>
 </html>
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/340156.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CLion调试Nodejs源码

【环境】 macOS node-v20.11.0源码 CLion 2023.3.2 【1】下载源码 https://nodejs.org/en/download/ 【2】编译源码 解压后的目录如下 进入解压后的目录进行编译 ./configure --debug make -C out BUILDTYPEDebug -j 4需要好久… 编译成功之后在node-v20.11.0目录下会有一个…

DALL·E 3功能:开启创意无限的新纪元

在人工智能的黄金时代&#xff0c;MidTool以其DALLE 3功能引领了一个全新的创意革命。这项技术不仅仅是一个简单的图像生成工具&#xff0c;它是一种将想象力转化为视觉现实的魔法。在这篇文章中&#xff0c;我们将深入探讨MidTool的DALLE 3功能&#xff0c;并揭示它如何成为艺…

三、MySQL之创建和管理表

一、基础知识 1.1 一条数据存储的过程 存储数据是处理数据的第一步 。只有正确地把数据存储起来,我们才能进行有效的处理和分析。否则,只 能是一团乱麻,无从下手。 在 MySQL 中, 一个完整的数据存储过程总共有 4 步,分别是创建数据库、确认字段、创建数据表、插入数据。 …

EasyDarwin计划新增将各种流协议(RTSP、RTMP、HTTP、TCP、UDP)、文件转推RTMP到其他视频直播平台,支持转码H.264、文件直播推送

之前我们尝试做过EasyRTSPLive&#xff08;将RTSP流转推RTMP&#xff09;和EasyRTMPLive&#xff08;将各种RTSP/RTMP/HTTP/UDP流转推RTMP&#xff0c;这两个服务在市场上都得到了比较多的好评&#xff0c;其中&#xff1a; 1、EasyRTSPLive用的是EasyRTSPClient取流&#xff…

技术浪潮下的程序员职业困境:一对谷歌工程师夫妻的悲剧启示

目录 前言1 裁员潮下的程序员1.1 技术变革带来的裁员潮1.2 程序员职业危机&#xff1a;技能匮乏成为致命伤 2 一对谷歌工程师夫妻的悲剧2.1 事件经过2.2 心理压力和职业困境的交织 3 技术浪潮下的程序员职业适应策略3.1 持续学习与技能更新3.2 多元化技能与职业规划3.3 职业心理…

EasyExcelFactory 导入导出功能的实战使用

EasyExcelFactory 导入导出功能的实战使用分享&#xff1a; 1、jar包引入 <!-- 阿里巴巴Excel处理--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.6</version></dependen…

2.机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解

2️⃣机器学习-K最近邻&#xff08;k-Nearest Neighbor&#xff0c;KNN&#xff09;分类算法原理讲解 个人简介一算法概述二算法思想2.1 KNN的优缺点 三实例演示3.1电影分类3.2使用KNN算法预测 鸢(yuan)尾花 的种类3.3 预测年收入是否大于50K美元 个人简介 &#x1f3d8;️&…

华为欧拉操作系统结合内网穿透实现固定公网地址SSH远程连接

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

多线程实例练习题~

本篇文章主要是用来巩固多线程的简单应用&#xff0c;如果你已经学习了多线程的有关知识&#xff0c;想要巩固&#xff0c;那不妨拿下面几道题来考验一下自己吧&#xff01; 案例1&#xff1a;电影院售票(难度指数&#xff1a;一颗星) 题目&#xff1a;一共有1000张电影票&…

8.3 Springboot整合Redis 之Jedis方式

文章目录 前言一、Maven依赖二、新增子Module:tg-book-redis三、Jedis配置类3.1 Jedis连接池核心配置说明四、Jedis 工具类五、新增controller测试前言 Jedis是Redis官方推荐的Java客户端连接工具,用法非常简单,Jedis的API与Redis的API可以说是一模一样,所以非常有利于熟悉…

深入掌握 OSS,最完美的 OSS 上传方案!

文件上传是常见需求&#xff0c;一般我们不会把文件直接上传到应用服务器&#xff0c;因为单台服务器存储空间是有限的&#xff0c;不好扩展。 我们会用单独的 OSS &#xff08;Object Storage Service&#xff09;对象存储服务来上传下载文件。 比如一般会买阿里云的 OSS 服…

M1 MacOS下安卓虚拟化的最佳方案

categories: [VM] tags: MacOS VM 写在前面 一直想在桌面环境虚拟化安卓app, 但是看网上的推荐一直感觉不合胃口, 不是要花钱就是有广告, 想着找找开源的实现, 后来发现还是 Google 自家的产品用着舒服. 安装与配置 brew install android-studio然后随便开一个项目, 选默认…

【window】Windows11:该文件没有与之关联的应用来执行该操作

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能 之前win10升级win11后&#xff0c;受不了桌面软件图标的的小箭头&#xff0c;所以弄掉了&#xff0c;但是随之而来产…

python实现带刷新的文本进度条

进度条已执行的部分使用“**”&#xff0c;未执行的部分使用“--”&#xff0c;用print&#xff08;&#xff09;来完成 使用到的函数&#xff1a; time.sleep(),作用是在程序执行过程中暂停一段时间&#xff0c;即会使程序暂停指定的秒数&#xff0c;然后再继续执行后面的代…

c/c++的指针函数与函数指针

函数 定义&#xff1a; 函数是数学中的一个概念&#xff0c;它是定义在某个数集上的一个特殊的映射关系。函数将输入值&#xff08;或自变量&#xff09;映射到输出值&#xff08;或因变量&#xff09;。函数的输入和输出可以是任何类型的数据&#xff0c;如数字、字符串、数组…

伪原创文章生成器软件免费使用的方法

写文章不仅消耗时间&#xff0c;而且还容易出现写不出内容的问题&#xff0c;随着技术的发展&#xff0c;越来越多的人开始不再亲历亲为的去写文章了&#xff0c;而是用起了伪原创文章生成器软件&#xff0c;对于还不了解自动生成文章软件的人&#xff0c;可不要小瞧这个它了&a…

世微 AP5199S 降压恒流IC 车灯景观灯舞台灯 过EMC认证线路图

说明 AP5199S 是一款电路简单的多功能平均电流 型 LED 恒流驱动器&#xff0c;适用于宽电压范围的非隔离式 大功率恒流 LED 驱动领域。 芯片 PWM 端口支持超小占空比的 PWM 调光&#xff0c; 可响应 60ns 脉宽。芯片采用我司算法&#xff0c;为客 户提供解决方案&#xff0c;限…

MarkDown学习笔记 直观全面详细

前言 为什么我们要学习Markdown呢&#xff1f;因为Markdown简单易学易上手&#xff0c;可以以纯文本格式编写文档&#xff0c;然后转换成有效的HTML文档&#xff0c;并且以导出 HTML 、Word、图像、PDF、Epub 等多种格式的文档&#xff0c;许多网站平台的文章、博客、论文均可…

【Java并发】聊聊活锁

在并发编程中&#xff0c;为了保证数据安全性&#xff0c;所以使用锁机制&#xff0c;syn lock cas 等方式保证&#xff0c;但是也从一定程度降低了性能。而除了这个方面&#xff0c;还引入了锁竞争&#xff0c;比如死锁、活锁。 【Java并发】聊聊死锁 避免死锁&#xff1a;避…

vue项目编译非常慢,经常卡在某个百分点

1、注册插件 2、在项目根目录下的 babel.config.js 文件中加入下方配置 3、将import导入方式改为require导入方式&#xff0c;返回promise 4、如果动态加载组件import引入组件找不到组件&#xff08;Error: Cannot find module&#xff09; 使用 webpack 的 require.ensure() …