目錄
- 1.計算屬性:
- 1.概述:
- 2.語法特點:
- 3.案例:
- 案例1:
- 案例2:
- 案例3:
- 4.總結:
- 5.get函數什么時候執行?
- 6.注意:
- 2.監視屬性:
- 1.概述:
- 2.用法:
- 1.監視單個屬性值:
- 寫法1:在Vue實例對象時配置:
- 寫法2:Vue實例對象完成后,配置監視屬性
- 測試結果展示:
- 2.深度監視:
- 1.監視對象的一個屬性:
- 2.監視整個對象:
- 3.監視屬性的簡寫:只適用于單個屬性等簡單邏輯的監視
- 4.總結:
1.計算屬性:
1.概述:
簡單來說,計算屬性就是通過Vue實例中data中已存在的屬性,經過邏輯運算得到一個新屬性;
2.語法特點:
- 1.定義Vue實例vm
- 2.在vm中定義el和data屬性
- 3.在data屬性中定義相關屬性(數據)
- 4.在vm中定義computed計算屬性
- 5.在計算屬性中定義函數,執行對data屬性中定義相關屬性的邏輯運算
- 6.如果需要對計算屬性的值進行讀寫操作,還需要在計算屬性中定義的函數中定義get/set方法
- 7.并且通過set方法修改計算數值的值時,必須要引起參與計算屬性的變量的改變
- 8.因為get方法具有緩存機制,只有當數據改變后才會再次執行,如果通過set修改計算屬性的值時,不改變參與計算的值,那么get方法就不會執行,更新后的數據也就不會同步更新到頁面上了
3.案例:
案例1:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>全名:{{fullName}}</h2>姓:<input type="text" v-model="firstName"/><br/>名:<input type="text" v-model="laseName"/><br/>全名:<input type="text" v-model="fullName"/>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {firstName: '張',laseName: "三"}},computed: {//計算屬性fullName: {get() {//有緩存 只執行一次 如果改變了 需要二次執行console.log("執行了fullName計算")return this.firstName + "-" + this.laseName;},set(value) {console.log("改變計算屬性:", value)//在修改是 要引起 參與計算屬性的變量的改變let arr = value.split("-");this.firstName = arr[0];this.laseName = arr[1];}}}).$mount("#root");
</script>
</body>
</html>
說明:在上面案例中,我們給Vue實例添加了一個計算屬性,通過實例中data對象的firstname屬性和lastname屬性計算獲取fullname,并將計算屬性fullname展示到了頁面上。由于我們在計算屬性的函數中添加了get/set方法,并在set方法中修改fullname的值后,將新的值賦值給了實例中data對象的firstname屬性和lastname屬性,所以可以實現瀏覽器頁面上改變fullname的值時,firstname屬性和lastname屬性以及最上面的fullname的值的同步變化 ,如下圖所示;
案例2:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>全名:{{fullName}}</h2>姓:<input type="text" v-model="firstName"/><br/>名:<input type="text" v-model="laseName"/><br/>全名:<input type="text" v-model="fullName"/>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {firstName: '張',laseName: "三"}},computed: {//計算屬性fullName: {get() {//有緩存 只執行一次 如果改變了 需要二次執行console.log("執行了fullName計算")return this.firstName + "-" + this.laseName;},set(value) {console.log("改變計算屬性:", value)}}}).$mount("#root");
</script>
</body>
</html>
在案例2中,我們在set方法中只改變fullname的值后,而沒有將新的值賦值給了實例中data對象的firstname屬性和lastname屬性,那么在頁面中對應的屬性就不會同步更新,因為對于get方法來說,數據未發生改變,就不會再執行了,測試結果如下圖所示;
案例3:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>全名:{{fullName}}</h2>姓:<input type="text" v-model="firstName"/><br/>名:<input type="text" v-model="laseName"/><br/>全名:<input type="text" v-model="fullName"/>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {firstName: '張',laseName: "三"}},computed: {//簡寫 只讀fullName() {//有緩存 只執行一次 如果改變了 需要二次執行console.log("執行了fullName計算")return this.firstName + "-" + this.laseName;}}}).$mount("#root");
</script>
</body>
</html>
說明:如果對于計算屬性的結果只有讀取操作,那么就可以簡寫計算屬性中的函數了,只需在計算屬性的函數中定義執行邏輯即可,由于緩存機制,只要該值不發生改變,就可以正常展示到頁面上;因為沒有set方法,如果此時在頁面上修改計算屬性的值,就會報錯。
4.總結:
- 要用的屬性不存在,需要通過已有的屬性計算的來
- 底層借助了 Object.defineproperty() 方法 提供了set get
5.get函數什么時候執行?
- 在初次讀取時執行一次
- 當依賴屬性改變時在次執行
6.注意:
- 計算屬性最終會出現在vm上 可以直接調用
- 如果計算屬性要被修改 ,就必須寫set函數,還要引起依賴屬性的改變
- 如果不考慮 修改 可以簡寫:
2.監視屬性:
1.概述:
<font style="color:rgba(0, 0, 0, 0.85);">在 Vue 中,監視屬性(</font>`<font style="color:rgba(0, 0, 0, 0.85);">watch</font>`<font style="color:rgba(0, 0, 0, 0.85);">)用于監聽一個特定的數據屬性,并在該屬性發生變化時執行相應的回調函數。</font>
2.用法:
1.監視單個屬性值:
寫法1:在Vue實例對象時配置:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root">
<!--通過插值表達式結合計算屬性展示天氣信息 --><h2>今天的天氣:{{info}}</h2>
<!--綁定單擊鼠標事件切換天氣 --><button @click="changeWeather">點擊切換天氣</button>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {isHot: true}},//通過計算屬性的函數展示天氣信息computed: {info() {return this.isHot ? '炎熱' : '涼爽';}},//通過單擊鼠標事件的回調函數改變天氣信息methods: {changeWeather() {this.isHot = !this.isHot;}},//監視isHot屬性,當屬性的值發生改變時,將改變前和改變后的值輸出到控制臺watch: {//監視屬性isHot: {//在初始化時監視immediate:true,handler(newValue, oldValue) {console.log('新的數據:', newValue);console.log('舊的數據:', oldValue);}}}})vm.$mount("#root");
</script>
</body>
</html>
?
寫法2:Vue實例對象完成后,配置監視屬性
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root">
<!--通過插值表達式結合計算屬性展示天氣信息 --><h2>今天的天氣:{{info}}</h2>
<!--綁定單擊鼠標事件切換天氣 --><button @click="changeWeather">點擊切換天氣</button>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {isHot: true}},//通過計算屬性的函數展示天氣信息computed: {info() {return this.isHot ? '炎熱' : '涼爽';}},//通過單擊鼠標事件的回調函數改變天氣信息methods: {changeWeather() {this.isHot = !this.isHot;}}})//第二種寫法 創建實例后 配置vm.$watch('isHot', {//在初始化時監視immediate: true,handler(newValue, oldValue) {console.log('新的數據:', newValue);console.log('舊的數據:', oldValue);}})vm.$mount("#root");
</script>
</body>
</html>
說明:配置監視屬性必須要在Vum實例綁定div容器之前;
測試結果展示:
因為我們在監視屬性中配置了屬性初始化時就開始監視,所以頁面剛加載出來時,控制臺就輸出了相關信息,由于此時數據未改變,所以舊的值為unfined,表示未定義;
此時當我們單擊按鈕時,就會再次觸發事件,引起監視的屬性的改變,進而會執行監視屬性中的邏輯
2.深度監視:
1.監視對象的一個屬性:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root">
<!--通過插值表達式獲取data中numbers的屬性值 --><h3> a:的值是{{numbers.a}} </h3><h3> b:的值是{{numbers.b}} </h3>
<!--綁定單擊鼠標事件,執行numbers的屬性++操作(Vue 會自動將表達式執行的結果作為回調函數來處理,屬于回調函數的簡寫) --><button @click="numbers.a++">點擊a++</button><button @click="numbers.b++">點擊b++</button>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {numbers: {a: 1,b: 2}}},watch: {//單獨的監視對象的一個屬性'numbers.b': {handler(newValue, oldValue) {console.log(newValue,oldValue)}}}})vm.$mount("#root");
</script>
</body>
</html>
在上面案例中,我們對data屬性中的numbers對象的b屬性進行監視,當點擊對應按鈕時觸發事件,改變了b屬性的值,此時就會在監視屬性中執行相關邏輯,控制臺打印新舊數據;
2.監視整個對象:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root">
<!--通過插值表達式獲取data中numbers的屬性值 --><h3> a:的值是{{numbers.a}} </h3><h3> b:的值是{{numbers.b}} </h3>
<!--綁定單擊鼠標事件,執行numbers的屬性++操作(Vue 會自動將表達式執行的結果作為回調函數來處理,屬于回調函數的簡寫) --><button @click="numbers.a++">點擊a++</button><button @click="numbers.b++">點擊b++</button>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {numbers: {a: 1,b: 2}}},watch: {numbers: {//啟用深度監視deep: true,handler(newValue,oldValue) {console.log(newValue,oldValue)}}}})vm.$mount("#root");
</script>
</body>
</html>
在上面案例中,我們對data屬性中的numbers對象的b屬性進行監視,當點擊對應按鈕時觸發事件,改變了b屬性的值,此時就會在監視屬性中執行相關邏輯,控制臺打印新舊數據。但實際上對于numbers對象而言,雖然b屬性的值發生了改變,但numbers對象本身并沒發生變化,因此新舊數值實際上是相同的;
3.監視屬性的簡寫:只適用于單個屬性等簡單邏輯的監視
對于監視單個屬性的簡單邏輯,可以對監視屬性的寫法進行簡化,示例代碼如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--2.準備一個容器-->
<div id="root"><h2>今天的天氣:{{info}}</h2><button @click="changeWeather">點擊切換天氣</button>
</div>
<!--1.引入Vue js 文件-->
<script src="vue/vue.js"></script>
<script type="text/javascript">//3.創建Vue對象let vm = new Vue({data() {return {isHot: true}},computed: {info() {return this.isHot ? '炎熱' : '涼爽';}},methods: {changeWeather() {this.isHot = !this.isHot;}},watch: {//監視屬性'isHot'(newValue, oldValue) {console.log('新的數據:', newValue);console.log('舊的數據:', oldValue);}}})vm.$mount("#root");
</script>
</body>
</html>
注意:此種簡寫方式只適用于監視單個屬性的簡單邏輯,對于深度監視這種復雜邏輯則不適用。因為簡寫代碼中監視屬性中不再是一個對象,而是一個函數,在此函數中無法進行深度監視的配置;
4.總結:
- 1.當被監視的屬性改變時,回調函數會自動執行。
- 2.監視的屬性是必須存在
- 3.監視有兩種寫法
-
在創建Vue實例時 配置 watch
-
在創建Vue實例之后 配置監視