【Vue篇】數據秘語:從watch源碼看響應式宇宙的蝴蝶效應

目錄

引言

一、watch偵聽器(監視器)

1.作用:

2.語法:

3.偵聽器代碼準備

4. 配置項

?5.總結

二、翻譯案例-代碼實現

1.需求

2.代碼實現

三、綜合案例——購物車案例

1. 需求?

?2. 代碼


引言

💬 歡迎討論:關于Vue偵聽器應用、防抖優化與響應式設計,歡迎評論區交流技術細節!
👍 點贊支持:若本文助你攻克watch難題,歡迎三連助力,共享前端技術精粹!
🚀 進階指南:watch與計算屬性聯奏,演繹Vue響應式交響曲,構建數據與視圖的動態協奏。

一、watch偵聽器(監視器)

1.作用:

??監視數據變化,執行一些業務邏輯或異步操作

2.語法:

  1. watch同樣聲明在跟data同級的配置項中

  2. 簡單寫法: 簡單類型數據直接監視

  3. 完整寫法:添加額外配置項

?

3. 配置項

完整寫法 —>添加額外的配置項

  1. deep:true 對復雜類型進行深度監聽
  2. immdiate:true 初始化 立刻執行一次
data: {obj: {words: '蘋果',lang: 'italy'},
},watch: {// watch 完整寫法對象: {deep: true, // 深度監視immdiate:true,//立即執行handler函數handler (newValue) {console.log(newValue)}}
}

?4.總結

watch偵聽器的寫法有幾種?

1.簡單寫法

2.完整寫法

二、翻譯案例-代碼實現

1.需求

  • 當文本框輸入的時候 右側翻譯內容要時時變化(實時翻譯
  • 當下拉框中的語言發生變化的時候 右側翻譯的內容依然要時時變化
  • 如果文本框中有默認值的話要立即翻譯

2.代碼

<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>// 需求:輸入內容,修改語言,都實時翻譯// 接口地址:https://applet-base-api-t.itheima.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) {clearTimeout(this.timer)this.timer = setTimeout(async () => {const res = await axios({url: 'https://applet-base-api-t.itheima.net/api/translate',params: newValue})this.result = res.data.dataconsole.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//       }//     })//     this.result = res.data.data//     console.log(res.data.data)//   }, 300)// }}})</script></body>
</html>

三、綜合案例——購物車案例

1. 需求?

需求說明:

  1. 渲染功能
  2. 刪除功能
  3. 修改個數
  4. 全選反選
  5. 統計 選中的 總價 和 總數量
  6. 持久化到本地

實現思路:

1.基本渲染: v-for遍歷、:class動態綁定樣式

2.刪除功能 : v-on 綁定事件,獲取當前行的id

3.修改個數 : v-on綁定事件,獲取當前行的id,進行篩選出對應的項然后增加或減少

4.全選反選

  1. 必須所有的小選框都選中,全選按鈕才選中 → every
  2. 如果全選按鈕選中,則所有小選框都選中
  3. 如果全選取消,則所有小選框都取消選中

聲明計算屬性,判斷數組中的每一個checked屬性的值,看是否需要全部選

5.統計 選中的 總價 和 總數量 :通過計算屬性來計算選中的總價和總數量

6.持久化到本地: 在數據變化時都要更新下本地存儲 watch

?2. 代碼

css?

.app-container {padding-bottom: 300px;width: 800px;margin: 0 auto;
}
@media screen and (max-width: 800px) {.app-container {width: 600px;}
}
.app-container .banner-box {border-radius: 20px;overflow: hidden;margin-bottom: 10px;
}
.app-container .banner-box img {width: 100%;
}
.app-container .nav-box {background: #ddedec;height: 60px;border-radius: 10px;padding-left: 20px;display: flex;align-items: center;
}
.app-container .nav-box .my-nav {display: inline-block;background: #5fca71;border-radius: 5px;width: 90px;height: 35px;color: white;text-align: center;line-height: 35px;margin-right: 10px;
}.breadcrumb {font-size: 16px;color: gray;
}
.table {width: 100%;text-align: left;border-radius: 2px 2px 0 0;border-collapse: separate;border-spacing: 0;
}
.th {color: rgba(0, 0, 0, 0.85);font-weight: 500;text-align: left;background: #fafafa;border-bottom: 1px solid #f0f0f0;transition: background 0.3s ease;
}
.th.num-th {flex: 1.5;
}
.th {text-align: center;
}
.th:nth-child(4),
.th:nth-child(5),
.th:nth-child(6),
.th:nth-child(7) {text-align: center;
}
.th.th-pic {flex: 1.3;
}
.th:nth-child(6) {flex: 1.3;
}.th,
.td {position: relative;padding: 16px 16px;overflow-wrap: break-word;flex: 1;
}
.pick-td {font-size: 14px;
}
.main,
.empty {border: 1px solid #f0f0f0;margin-top: 10px;
}
.tr {display: flex;cursor: pointer;border-bottom: 1px solid #ebeef5;
}
.tr.active {background-color: #f5f7fa;
}
.td {display: flex;justify-content: center;align-items: center;
}.table img {width: 100px;height: 100px;
}button {outline: 0;box-shadow: none;color: #fff;background: #d9363e;border-color: #d9363e;color: #fff;background: #d9363e;border-color: #d9363e;line-height: 1.5715;position: relative;display: inline-block;font-weight: 400;white-space: nowrap;text-align: center;background-image: none;border: 1px solid transparent;box-shadow: 0 2px 0 rgb(0 0 0 / 2%);cursor: pointer;transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;touch-action: manipulation;height: 32px;padding: 4px 15px;font-size: 14px;border-radius: 2px;
}
button.pay {background-color: #3f85ed;margin-left: 20px;
}.bottom {height: 60px;display: flex;align-items: center;justify-content: space-between;padding-right: 20px;border: 1px solid #f0f0f0;border-top: none;padding-left: 20px;
}
.right-box {display: flex;align-items: center;
}
.check-all {cursor: pointer;
}
.price {color: hotpink;font-size: 30px;font-weight: 700;
}
.price-box {display: flex;align-items: center;
}
.empty {padding: 20px;text-align: center;font-size: 30px;color: #909399;
}
.my-input-number {display: flex;
}
.my-input-number button {height: 40px;color: #333;border: 1px solid #dcdfe6;background-color: #f5f7fa;
}
.my-input-number button:disabled {cursor: not-allowed!important;
}
.my-input-number .my-input__inner {height: 40px;width: 50px;padding: 0;border: none;border-top: 1px solid #dcdfe6;border-bottom: 1px solid #dcdfe6;
}

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" /><link rel="stylesheet" href="./css/inputnumber.css" /><link rel="stylesheet" href="./css/index.css" /><title>購物車</title></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: 'http://autumnfish.cn/static/火龍果.png',isChecked: true,num: 2,price: 6,},{id: 2,icon: 'http://autumnfish.cn/static/荔枝.png',isChecked: false,num: 7,price: 20,},{id: 3,icon: 'http://autumnfish.cn/static/榴蓮.png',isChecked: false,num: 3,price: 40,},{id: 4,icon: 'http://autumnfish.cn/static/鴨梨.png',isChecked: true,num: 10,price: 3,},{id: 5,icon: 'http://autumnfish.cn/static/櫻桃.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)// }// 完整寫法 = get + setisAll: {get () {return this.fruitList.every(item => item.isChecked)},set (value) {// 基于拿到的布爾值,要讓所有的小選框 同步狀態this.fruitList.forEach(item => item.isChecked = value)}},// 統計選中的總數 reducetotalCount () {return this.fruitList.reduce((sum, item) => {if (item.isChecked) {// 選中 → 需要累加return sum + item.num} else {// 沒選中 → 不需要累加return sum}}, 0)},// 總計選中的總價 num * pricetotalPrice () {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 找到數組中的對應項 → findconst fruit = this.fruitList.find(item => item.id === id)// 2. 操作 num 數量fruit.num++},sub (id) {// 1. 根據 id 找到數組中的對應項 → findconst fruit = this.fruitList.find(item => item.id === id)// 2. 操作 num 數量fruit.num--}},watch: {fruitList: {deep: true,handler (newValue) {// 需要將變化后的 newValue 存入本地 (轉JSON)localStorage.setItem('list', JSON.stringify(newValue))}}}})</script></body>
</html>

以上就是關于【Vue篇】數據秘語:從watch源碼看響應式宇宙的蝴蝶效應? 內容啦。本文?剖析了watch的監聽機制、深度追蹤技巧,并通過翻譯防抖與購物車案例實戰,解構了數據與視圖的動態綁定邏輯。若對watch配置、計算屬性聯用或本地持久化方案存在疑問,歡迎評論區留下技術火花!💡

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/diannao/83721.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83721.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83721.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPS中代碼段的識別方法及JS宏實現

在WPS中&#xff0c;文檔的基本結構可以通過對象模型來理解&#xff1a; &#xff08;1&#xff09;Document對象&#xff1a;表示整個文檔 &#xff08;2&#xff09;Range對象&#xff1a;表示文檔中的一段連續區域&#xff0c;可以是一個字符、一個句子或整個文檔 &#…

el-tree結合el-tree-transfer實現穿梭框里展示樹形數據

參考文章&#xff1a;我把他的彈框單拉出來一個獨立文件作為組件方便使用&#xff0c;遇到一些問題記錄一下。 testComponet.vue <template><div class"per_container"><div class"per_con_left"><div class"per_con_title&q…

Go 后端中雙 token 的實現模板

下面是一個典型的 Go 后端雙 Token 認證機制 實現模板&#xff0c;使用 Gin 框架 JWT Redis&#xff0c;結構清晰、可拓展&#xff0c;適合實戰開發。 項目結構建議 /utils├── jwt.go // Access & Refresh token 的生成和解析├── claims.go // 從請求…

Typescript學習教程,從入門到精通,TypeScript 對象語法知識點及案例代碼(7)

TypeScript 對象語法知識點及案例代碼 TypeScript 是 JavaScript 的超集&#xff0c;提供了靜態類型檢查和其他增強功能。在 TypeScript 中&#xff0c;對象是面向對象編程&#xff08;OOP&#xff09;的基礎。 一、對象概述 在 TypeScript 中&#xff0c;對象是屬性的集合&a…

應用BERT-GCN跨模態情緒分析:貿易緩和與金價波動的AI歸因

本文運用AI量化分析框架&#xff0c;結合市場情緒因子、宏觀經濟指標及技術面信號&#xff0c;對黃金與美元指數的聯動關系進行解析&#xff0c;揭示本輪貴金屬回調的深層驅動因素。 周三&#xff0c;現貨黃金價格單日跌幅達2.1%&#xff0c;盤中觸及3167.94美元/盎司關鍵價位&…

命令行登錄 MySQL 報 Segmentation fault 故障解決

問題描述&#xff1a;對 mysql8.0.35 源碼進行 make&#xff0c;由于一開始因為yum源問題少安裝依賴庫 庫&#xff0c;在鏈接時遇到錯誤 undefined reference to&#xff0c;后來安裝了相關依賴庫&#xff0c;再次 make 成功。于是將 mysqld 啟動&#xff0c;再用 mysql -u roo…

Axure設計數字鄉村可視化大屏:構建鄉村數據全景圖

今天&#xff0c;讓我們一同深入了解由Axure設計的數字鄉村可視化大屏&#xff0c;看看它如何通過精心的布局和多樣化的圖表類型&#xff0c;將鄉村的各類數據以直觀、易懂的方式呈現出來&#xff0c;為鄉村管理者提供有力的數據支持。 原型效果預覽鏈接&#xff1a;Axure數字鄉…

3D個人簡歷網站 4.小島

1.模型素材 在Sketchfab上下載狐貍島模型&#xff0c;然后轉換為素材資源asset&#xff0c;嫌麻煩直接在網盤鏈接下載素材&#xff0c; Fox’s islandshttps://sketchfab.com/3d-models/foxs-islands-163b68e09fcc47618450150be7785907https://gltf.pmnd.rs/ 素材夸克網盤&a…

智能開發工具PhpStorm v2025.1——增強AI輔助編碼功能

PhpStorm是一個輕量級且便捷的PHP IDE&#xff0c;其旨在提高用戶效率&#xff0c;可深刻理解用戶的編碼&#xff0c;提供智能代碼補全&#xff0c;快速導航以及即時錯誤檢查。可隨時幫助用戶對其編碼進行調整&#xff0c;運行單元測試或者提供可視化debug功能。 立即獲取PhpS…

Spark 的運行模式(--master) 和 部署方式(--deploy-mode)

Spark 的 運行模式&#xff08;--master&#xff09; 和 部署方式&#xff08;--deploy-mode&#xff09;&#xff0c;兩者的核心區別在于 資源調度范圍 和 Driver 進程的位置。 一、核心概念對比 維度--master&#xff08;運行模式&#xff09;--deploy-mode&#xff08;部署…

sqli—labs第八關——布爾盲注

一&#xff1a;確定注入類型 按照我們之前的步驟來 輸入 ?id1 and 11-- ?id1 and 12-- 界面正常 第二行界面異常空白 所以注入類型為單引號閉合型 二&#xff1a; 布爾盲注 1.判斷是否使用條件 &#xff08;1&#xff09;&#xff1a;存在注入但不會直接顯示查詢結果 …

ARP 原理總結

&#x1f310; 一、ARP 原理總結 ARP&#xff08;Address Resolution Protocol&#xff09;是用于通過 IP 地址解析 MAC 地址的協議&#xff0c;工作在 鏈路層 與 網絡層之間&#xff08;OSI 模型的第三層與第二層之間&#xff09;。 &#x1f501; ARP通信過程&#xff1a; …

SpringCloud——EureKa

目錄 1.前言 1.微服務拆分及遠程調用 3.EureKa注冊中心 遠程調用的問題 eureka原理 搭建EureKaServer 服務注冊 服務發現 1.前言 分布式架構&#xff1a;根據業務功能對系統進行拆分&#xff0c;每個業務模塊作為獨立項目開發&#xff0c;稱為服務。 優點&#xff1a; 降…

機頂盒刷機筆記

疑難雜癥解決 hitool線刷網口不通tftp超時--》關閉防火墻cm201-2卡刷所有包提示失敗abort install--》找個卡刷包只刷fastboot分區再卡刷就能通過了&#xff08;cm201救磚包 (M8273版子&#xff09;&#xff09; 刷機工具 海兔燒錄工具HiTool-STB-5.3.12工具&#xff0c;需要…

Linux動靜態庫制作與原理

什么是庫 庫是寫好的現有的&#xff0c;成熟的&#xff0c;可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫&#xff0c;不可能每個人的代碼都從零開始&#xff0c;因此庫的存在意義非同尋常。 本質上來說庫是一種可執行代碼的二進制形式&#xff0c;可以被操作系統…

如何通過小智AI制作會說話的機器人玩具?

一、硬件準備與組裝 1. 核心硬件選擇 主控芯片&#xff1a;選擇支持無線網絡連接、音頻處理和可編程接口的嵌入式開發板 音頻模塊&#xff1a;配備拾音麥克風與小型揚聲器&#xff0c;確保語音輸入/輸出功能 顯示模塊&#xff1a;選擇適配的交互顯示屏用于可視化反饋 擴展模…

如何控制郵件發送頻率避免打擾用戶

一、用戶行為 監測用戶與郵件的互動數據&#xff0c;如打開率、點擊率下滑或退訂申請增多&#xff0c;可能是發送頻率過高的警示信號。利用郵件營銷平臺的分析工具&#xff0c;識別這些指標的變動趨勢&#xff0c;為調整提供依據。 二、行業特性與受眾差異 不同行業用戶對郵…

定積分的“偶倍奇零”性質及其使用條件

定積分的“偶倍奇零”性質是針對對稱區間上的奇偶函數積分的重要簡化方法。以下是其核心內容和應用要點&#xff1a; ?一、基本性質 ?偶函數&#xff08;偶倍&#xff09;? 若 f(x) 在 [?a,a] 上為偶函數&#xff08;即 f(?x)f(x)&#xff09;&#xff0c;則&#xff1a; …

如何在 Windows 11 或 10 上安裝 Fliqlo 時鐘屏保

了解如何在 Windows 11 或 10 上安裝 Fliqlo,為您的 PC 或筆記本電腦屏幕添加一個翻轉時鐘屏保以顯示時間。 Fliqlo 是一款適用于 Windows 和 macOS 平臺的免費時鐘屏保。它也適用于移動設備,但僅限于 iPhone 和 iPad。Fliqlo 的主要功能是在用戶不活動時在 PC 或筆記本電腦…

【C/C++】C++并發編程:std::async與std::thread深度對比

文章目錄 C并發編程&#xff1a;std::async與std::thread深度對比1 核心設計目的以及區別2 詳細對比分析3 代碼對比示例4 適用場景建議5 總結 C并發編程&#xff1a;std::async與std::thread深度對比 在 C 中&#xff0c;std::async 和 std::thread 都是用于并發編程的工具&am…