vue watch監(jiān)聽(tīng)數(shù)據(jù)變化的案例詳解
watch的基本用法
這一次我們要添加的是watch屬性。下面我們先來(lái)眼熟一下偵聽(tīng)器的添加位置:
<script> export default { name: "app", // 數(shù)據(jù) data() { return {}; }, // 方法 methods:{}, // 偵聽(tīng)器 watch:{} }; </script>
一個(gè)簡(jiǎn)單的例子:
<template> <p>你點(diǎn)擊按鈕的次數(shù)是: {{ count }} </p> <button @click="add" v-model="count">點(diǎn)擊</button> </template> <script> export default { name: "app", data(){ return { count:0 } }, methods:{ add(){ this.count++; } }, watch:{ // 被偵聽(tīng)的變量count count(){ console.log('count 發(fā)生了變化'); } } }; </script>
偵聽(tīng)器更多的是用在異步操作中,所謂異步操作就是數(shù)據(jù)返回有所延遲的操作,比如說(shuō)我們要請(qǐng)求后端的接口,接口會(huì)返回給我們數(shù)據(jù),然后我們?cè)賹?shù)據(jù)渲染在頁(yè)面上。
從請(qǐng)求接口到返回?cái)?shù)據(jù),這中間需要一定的時(shí)間,此時(shí)我們就可以用偵聽(tīng)器來(lái)偵聽(tīng)返回的數(shù)據(jù),當(dāng)數(shù)據(jù)返回以后,我們?cè)儆|發(fā)渲染。
模擬一個(gè)偽異步操作:
<template> <input type="text" v-model="inputValue"> <p>從輸入框中獲取到的數(shù)據(jù):{{ passedInputValue }}</p> </template> <script> export default { name: "app", data(){ return { inputValue: '', passedInputValue: '' } }, watch:{ inputValue() { // 當(dāng)inputValue數(shù)據(jù)發(fā)生變化以后,延遲三秒賦值給passedInputValue setTimeout(() => { this.passedInputValue = this.inputValue; }, 3000) } } }; </script>
此時(shí)你就會(huì)發(fā)現(xiàn),當(dāng)你在input輸入框中輸入文字以后,p標(biāo)簽內(nèi)的數(shù)據(jù)不是立馬改變,而是過(guò)三秒才會(huì)去渲染
獲取前一次的值
在某些場(chǎng)景中,我們會(huì)需要上一次的數(shù)據(jù),此時(shí),偵聽(tīng)器就可以給我們兩個(gè)值,舊值和新值
在上一個(gè)案例的基礎(chǔ)上,我們只需要添加一個(gè)參數(shù),即可獲取舊值,代碼如下:
watch:{ inputValue(value,oldValue) { // 第一個(gè)參數(shù)為新值,第二個(gè)參數(shù)為舊值,不能調(diào)換順序 console.log(`新值:${value}`); console.log(`舊值:${oldValue}`); } }
handler方法和immediate屬性
前面我們已經(jīng)知道,當(dāng)我們偵聽(tīng)的值沒(méi)有發(fā)生改變的時(shí)候,是不會(huì)觸發(fā)偵聽(tīng)器的,并且,頁(yè)面第一次渲染的時(shí)候也不會(huì)觸發(fā)偵聽(tīng)器。
但是現(xiàn)在我有個(gè)需求就是要讓頁(yè)面第一次渲染的時(shí)候就去觸發(fā)偵聽(tīng)器呢?
此時(shí)就要用到一個(gè)方法和一個(gè)屬性:immediate
<template> <p>FullName: {{fullName}}</p> <p>FirstName: <input type="text" v-model="firstName"></p> </template> <script> export default { name: "app", data(){ return { firstName: 'Su', lastName: 'Junyang', fullName: '' } }, watch:{ firstName: { handler(newName, oldName) { this.fullName = newName + ' ' + this.lastName; }, // 如果設(shè)置了false,那么在頁(yè)面第一次渲染以后不會(huì)觸發(fā)偵聽(tīng)器 immediate: true } } }; </script>
deep 深度偵聽(tīng)
所謂深度偵聽(tīng)就是偵聽(tīng)對(duì)象內(nèi)部屬性的值。
我們之前用的偵聽(tīng)器都只能偵聽(tīng)一個(gè)變量的變化,(重點(diǎn)看一下代碼中的注釋)例如:
data:{ return { // 字符串發(fā)生變化,可以偵聽(tīng) firstName: 'Su', room:{ name:"大床房", // 當(dāng)房號(hào)發(fā)生變化的時(shí)候,偵聽(tīng)器并不能偵聽(tīng)到。 // 因?yàn)閭陕?tīng)器只偵聽(tīng)到room,不能偵聽(tīng)number或者name number: 302 } } },
此時(shí)我們就需要深度偵聽(tīng),深度偵聽(tīng)在代碼上并不難實(shí)現(xiàn),只需要在handler的基礎(chǔ)上添加一個(gè)deep屬性,代碼如下:
watch:{ room:{ handler(newRoom,oldRoom){ console.log("房間號(hào)發(fā)生了變化") }, deep: true } }
案例:使用偵聽(tīng)器和定時(shí)器實(shí)現(xiàn)偽模糊搜索
<template> <div class="search"> <input type="text" v-model="inputValue" /> <div class="search-block" v-for="(element, index) in results" :key="index"> {{ element }} </div> </div> </template> <script> export default { name: 'app', data() { return { results: [], mockData: [ '浙江大學(xué)', '中國(guó)人民大學(xué)', '清華大學(xué)', '清華大學(xué)附屬中學(xué)', '浙江理工大學(xué)', '浙江工業(yè)大學(xué)' ], inputValue: '' }; }, watch: { inputValue(value) { if (!!value) { setTimeout(() => { this.results = this.mockData.filter(el => { console.log(value); return el.indexOf(value) !== -1; }); }, 300); } } } }; </script>
到此這篇關(guān)于vue watch監(jiān)聽(tīng)數(shù)據(jù)變化的案例詳解的文章就介紹到這了,更多相關(guān)vue watch監(jiān)聽(tīng)數(shù)據(jù)變化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章

vue實(shí)現(xiàn).md文件預(yù)覽功能的兩種方法詳解

在iview+vue項(xiàng)目中使用自定義icon圖標(biāo)方式

vue/Element?UI實(shí)現(xiàn)Element?UI?el-dialog自由拖動(dòng)功能實(shí)現(xiàn)

vue.js實(shí)現(xiàn)條件渲染的實(shí)例代碼

查看vue版本號(hào)以及vue/cli腳手架版本號(hào)方式

淺談vue.js導(dǎo)入css庫(kù)(elementUi)的方法