一、今日學習目標
1.指令補充
- 指令修飾符
- v-bind對樣式增強的操作
- v-model應用于其他表單元素
2.computed計算屬性
- 基礎語法
- 計算屬性vs方法
- 計算屬性的完整寫法
- 成績案例
3.watch偵聽器
- 基礎寫法
- 完整寫法
4.綜合案例 (演示)
- 渲染 / 刪除 / 修改數量 / 全選 / 反選 / 統計總價 / 持久化
二、指令修飾符
1.什么是指令修飾符?
? 所謂指令修飾符就是通過“.”指明一些指令后綴 不同的后綴封裝了不同的處理操作 —> 簡化代碼
2.按鍵修飾符
- @keyup.enter —>當點擊enter鍵的時候才觸發
代碼演示:
<div id="app"><h3>@keyup.enter → 監聽鍵盤回車事件</h3><input v-model="username" type="text"></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {username: ''},methods: {}})</script>
3.v-model修飾符
- v-model.trim —>去除首位空格
- v-model.number —>轉數字
4.事件修飾符
- @事件名.stop —> 阻止冒泡
- @事件名.prevent —>阻止默認行為
- @事件名.stop.prevent —>可以連用 即阻止事件冒泡也阻止默認行為
<style>.father {width: 200px;height: 200px;background-color: pink;margin-top: 20px;}.son {width: 100px;height: 100px;background-color: skyblue;}</style><div id="app"><h3>v-model修飾符 .trim .number</h3>姓名:<input v-model="username" type="text"><br>年紀:<input v-model="age" type="text"><br><h3>@事件名.stop → 阻止冒泡</h3><div @click="fatherFn" class="father"><div @click="sonFn" class="son">兒子</div></div><h3>@事件名.prevent → 阻止默認行為</h3><a @click href="http://www.baidu.com">阻止默認行為</a></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {username: '',age: '',},methods: {fatherFn () {alert('老父親被點擊了')},sonFn (e) {// e.stopPropagation()alert('兒子被點擊了')}}})</script>
三、v-bind對樣式控制的增強-操作class
為了方便開發者進行樣式控制, Vue 擴展了 v-bind 的語法,可以針對 class 類名 和 style 行內樣式 進行控制 。
1.語法:
<div> :class = "對象/數組">這是一個div</div>
2.對象語法
當class動態綁定的是對象時,鍵就是類名,值就是布爾值,如果值是true,就有這個類,否則沒有這個類
<div class="box" :class="{ 類名1: 布爾值, 類名2: 布爾值 }"></div>
? 適用場景:一個類名,來回切換
3.數組語法
當class動態綁定的是數組時 → 數組中所有的類,都會添加到盒子上,本質就是一個 class 列表
<div class="box" :class="[ 類名1, 類名2, 類名3 ]"></div>
使用場景:批量添加或刪除類
4.代碼練習
<style>.box {width: 200px;height: 200px;border: 3px solid #000;font-size: 30px;margin-top: 10px;}.pink {background-color: pink;}.big {width: 300px;height: 300px;}</style><div id="app"><!--綁定對象--><div class="box">黑馬程序員</div><!--綁定數組--><div class="box">黑馬程序員</div></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {}})</script>
四、京東秒殺-tab欄切換導航高亮
1.需求:
? 當我們點擊哪個tab頁簽時,哪個tab頁簽就高亮
2.準備代碼:
<style>* {margin: 0;padding: 0;}ul {display: flex;border-bottom: 2px solid #e01222;padding: 0 10px;}li {width: 100px;height: 50px;line-height: 50px;list-style: none;text-align: center;}li a {display: block;text-decoration: none;font-weight: bold;color: #333333;}li a.active {background-color: #e01222;color: #fff;}</style><div id="app"><ul><li><a class="active" href="#">京東秒殺</a></li><li><a href="#">每日特價</a></li><li><a href="#">品類秒殺</a></li></ul></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {list: [{ id: 1, name: '京東秒殺' },{ id: 2, name: '每日特價' },{ id: 3, name: '品類秒殺' }]}})</script>
3.思路:
1.基于數據,動態渲染tab(v-for)
2.準備一個下標 記錄高亮的是哪一個 tab
3.基于下標動態切換class的類名
五、v-bind對有樣式控制的增強-操作style
1.語法
<div class="box" :style="{ CSS屬性名1: CSS屬性值, CSS屬性名2: CSS屬性值 }"></div>
2.代碼練習
<style>.box {width: 200px;height: 200px;background-color: rgb(187, 150, 156);}</style><div id="app"><div class="box"></div></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {}})</script>
3.進度條案例
<style>.progress {height: 25px;width: 400px;border-radius: 15px;background-color: #272425;border: 3px solid #272425;box-sizing: border-box;margin-bottom: 30px;}.inner {width: 50%;height: 20px;border-radius: 10px;text-align: right;position: relative;background-color: #409eff;background-size: 20px 20px;box-sizing: border-box;transition: all 1s;}.inner span {position: absolute;right: -20px;bottom: -25px;}</style><div id="app"><div class="progress"><div class="inner"><span>50%</span></div></div><button>設置25%</button><button>設置50%</button><button>設置75%</button><button>設置100%</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {}})</script>
六、v-model在其他表單元素的使用
1.講解內容:
常見的表單元素都可以用 v-model 綁定關聯 → 快速 獲取 或 設置 表單元素的值
它會根據 控件類型 自動選取 正確的方法 來更新元素
輸入框 input:text ——> value
文本域 textarea ——> value
復選框 input:checkbox ——> checked
單選框 input:radio ——> checked
下拉菜單 select ——> value
...
2.代碼準備
<style>textarea {display: block;width: 240px;height: 100px;margin: 10px 0;}</style><div id="app"><h3>小黑學習網</h3>姓名:<input type="text"> <br><br>是否單身:<input type="checkbox"> <br><br><!-- 前置理解:1. name: 給單選框加上 name 屬性 可以分組 → 同一組互相會互斥2. value: 給單選框加上 value 屬性,用于提交給后臺的數據結合 Vue 使用 → v-model-->性別: <input type="radio">男<input type="radio">女<br><br><!-- 前置理解:1. option 需要設置 value 值,提交給后臺2. select 的 value 值,關聯了選中的 option 的 value 值結合 Vue 使用 → v-model-->所在城市:<select><option>北京</option><option>上海</option><option>成都</option><option>南京</option></select><br><br>自我描述:<textarea></textarea> <button>立即注冊</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {}})</script>
七、computed計算屬性
1.概念
基于現有的數據,計算出來的新屬性。 依賴的數據變化,自動重新計算。
2.語法
- 聲明在 computed 配置項中,一個計算屬性對應一個函數
- 使用起來和普通屬性一樣使用 {{ 計算屬性名}}
3.注意
- computed配置項和data配置項是同級的
- computed中的計算屬性雖然是函數的寫法,但他依然是個屬性
- computed中的計算屬性不能和data中的屬性同名
- 使用computed中的計算屬性和使用data中的屬性是一樣的用法
- computed中計算屬性內部的this依然指向的是Vue實例
4.案例
比如我們可以使用計算屬性實現下面這個業務場景
5.代碼準備
<style>table {border: 1px solid #000;text-align: center;width: 240px;}th,td {border: 1px solid #000;}h3 {position: relative;}</style><div id="app"><h3>小黑的禮物清單</h3><table><tr><th>名字</th><th>數量</th></tr><tr v-for="(item, index) in list" :key="item.id"><td>{{ item.name }}</td><td>{{ item.num }}個</td></tr></table><!-- 目標:統計求和,求得禮物總數 --><p>禮物總數:? 個</p></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {// 現有的數據list: [{ id: 1, name: '籃球', num: 1 },{ id: 2, name: '玩具', num: 2 },{ id: 3, name: '鉛筆', num: 5 },]}})</script>
八、computed計算屬性 VS methods方法
1.computed計算屬性
作用:封裝了一段對于數據的處理,求得一個結果
語法:
- 寫在computed配置項中
- 作為屬性,直接使用
- js中使用計算屬性: this.計算屬性
- 模板中使用計算屬性:{{計算屬性}}
2.methods計算屬性
作用:給Vue實例提供一個方法,調用以處理業務邏輯。
語法:
- 寫在methods配置項中
- 作為方法調用
- js中調用:this.方法名()
- 模板中調用 {{方法名()}} 或者 @事件名=“方法名”
3.計算屬性的優勢
-
緩存特性(提升性能)
計算屬性會對計算出來的結果緩存,再次使用直接讀取緩存,
依賴項變化了,會自動重新計算 → 并再次緩存
-
methods沒有緩存特性
-
通過代碼比較
<style>table {border: 1px solid #000;text-align: center;width: 300px;}th,td {border: 1px solid #000;}h3 {position: relative;}span {position: absolute;left: 145px;top: -4px;width: 16px;height: 16px;color: white;font-size: 12px;text-align: center;border-radius: 50%;background-color: #e63f32;}</style><div id="app"><h3>小黑的禮物清單🛒<span>?</span></h3><table><tr><th>名字</th><th>數量</th></tr><tr v-for="(item, index) in list" :key="item.id"><td>{{ item.name }}</td><td>{{ item.num }}個</td></tr></table><p>禮物總數:{{ totalCount }} 個</p></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {// 現有的數據list: [{ id: 1, name: '籃球', num: 3 },{ id: 2, name: '玩具', num: 2 },{ id: 3, name: '鉛筆', num: 5 },]},computed: {totalCount () {let total = this.list.reduce((sum, item) => sum + item.num, 0)return total}}})</script>
4.總結
1.computed有緩存特性,methods沒有緩存
2.當一個結果依賴其他多個值時,推薦使用計算屬性
3.當處理業務邏輯時,推薦使用methods方法,比如事件的處理函數
九、計算屬性的完整寫法
既然計算屬性也是屬性,能訪問,應該也能修改了?
- 計算屬性默認的簡寫,只能讀取訪問,不能 “修改”
- 如果要 “修改” → 需要寫計算屬性的完整寫法
完整寫法代碼演示
<div id="app">姓:<input type="text" v-model="firstName"> +名:<input type="text" v-model="lastName"> =<span></span><br><br> <button>改名卡</button></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const app = new Vue({el: '#app',data: {firstName: '劉',lastName: '備'},computed: {},methods: {}})</script>
十、綜合案例-成績案例
功能描述:
1.渲染功能
2.刪除功能
3.添加功能
4.統計總分,求平均分
思路分析:
1.渲染功能 v-for :key v-bind:動態綁定class的樣式
2.刪除功能 v-on綁定事件, 阻止a標簽的默認行為
3.v-model的修飾符 .trim、 .number、 判斷數據是否為空后 再添加、添加后清空文本框的數據
4.使用計算屬性computed 計算總分和平均分的值
十一、watch偵聽器(監視器)
1.作用:
? 監視數據變化,執行一些業務邏輯或異步操作
2.語法:
-
watch同樣聲明在跟data同級的配置項中
-
簡單寫法: 簡單類型數據直接監視
-
完整寫法:添加額外配置項
data: { words: '蘋果',obj: {words: '蘋果'} },watch: {// 該方法會在數據變化時,觸發執行數據屬性名 (newValue, oldValue) {一些業務邏輯 或 異步操作。 },'對象.屬性名' (newValue, oldValue) {一些業務邏輯 或 異步操作。 } }
3.偵聽器代碼準備
<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><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="words"></textarea><span><i>??</i>文檔翻譯</span></div><div class="output-wrap"><div class="transbox">mela</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: {words: ''},// 具體講解:(1) watch語法 (2) 具體業務實現})</script>
十二、翻譯案例-代碼實現
<script>// 接口地址:https://applet-base-api-t.itheima.net/api/translate// 請求方式:get// 請求參數:// (1)words:需要被翻譯的文本(必傳)// (2)lang: 需要被翻譯成的語言(可選)默認值-意大利// -----------------------------------------------const app = new Vue({el: '#app',data: {//words: ''obj: {words: ''},result: '', // 翻譯結果// timer: null // 延時器id},// 具體講解:(1) watch語法 (2) 具體業務實現watch: {// 該方法會在數據變化時調用執行// newValue新值, oldValue老值(一般不用)// words (newValue) {// console.log('變化了', newValue)// }'obj.words' (newValue) {// console.log('變化了', 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.dataconsole.log(res.data.data)}, 300)}}})</script>
十三、watch偵聽器
1.語法
完整寫法 —>添加額外的配置項
- deep:true 對復雜類型進行深度監聽
- immdiate:true 初始化 立刻執行一次
data: {obj: {words: '蘋果',lang: 'italy'},
},watch: {// watch 完整寫法對象: {deep: true, // 深度監視immdiate:true,//立即執行handler函數handler (newValue) {console.log(newValue)}}
}
2.需求
- 當文本框輸入的時候 右側翻譯內容要時時變化
- 當下拉框中的語言發生變化的時候 右側翻譯的內容依然要時時變化
- 如果文本框中有默認值的話要立即翻譯
3.代碼實現
<script> 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)}} }})</script>
4.總結
watch偵聽器的寫法有幾種?
1.簡單寫法
watch: {數據屬性名 (newValue, oldValue) {一些業務邏輯 或 異步操作。 },'對象.屬性名' (newValue, oldValue) {一些業務邏輯 或 異步操作。 }
}
2.完整寫法
watch: {// watch 完整寫法數據屬性名: {deep: true, // 深度監視(針對復雜類型)immediate: true, // 是否立刻執行一次handlerhandler (newValue) {console.log(newValue)}}
}
十四、綜合案例
購物車案例
需求說明:
- 渲染功能
- 刪除功能
- 修改個數
- 全選反選
- 統計 選中的 總價 和 總數量
- 持久化到本地