Vue的响应式及相关问题
目錄
1.概念
2.頁(yè)面何時(shí)渲染
3.vm.$nextTick 和?Vue.nextTick
4.不發(fā)生重新渲染的情況
5. 響應(yīng)式更新數(shù)組和對(duì)象
1.概念
Vue響應(yīng)式指當(dāng)數(shù)據(jù)變化時(shí),頁(yè)面會(huì)重新渲染,如下例
<body><div id="app">{{ sentence}}</div> </body> <script src="./vue.js"></script> <script>const vm = new Vue({el: '#app',data: {sentence: '自由就是不再尋求認(rèn)可'}}) </script>【結(jié)果】改變 sentence 的值,頁(yè)面重新渲染
【注】當(dāng)創(chuàng)建vue實(shí)例時(shí),vue會(huì)將data中的成員代理給vue實(shí)例,目的是為了實(shí)現(xiàn)響應(yīng)式,監(jiān)控?cái)?shù)據(jù)變化,執(zhí)行某個(gè)監(jiān)聽(tīng)函數(shù)?
2.頁(yè)面何時(shí)渲染
Vue更新DOM的操作是異步執(zhí)行的,只要偵聽(tīng)到數(shù)據(jù)變化,將開啟一個(gè)異步隊(duì)列,如果一個(gè)數(shù)據(jù)被多次變更,那么只會(huì)被推入到隊(duì)列中一次,這樣可以避免不必要的計(jì)算和DOM操作
<div id="app">{{ bookList }} </div> const vm = new Vue({el: '#app',data: {bookList: ['被討厭的勇氣', '沒(méi)有兇手的殺人夜', '親密關(guān)系']} }) vm.bookList[1] = 'JavaScript高級(jí)程序設(shè)計(jì)'; console.log(vm.bookList[1]); // 此時(shí)數(shù)據(jù)已經(jīng)更改 console.log(vm.$el.innerHTML); //但是頁(yè)面內(nèi)容還沒(méi)有更改【結(jié)果】
3.vm.$nextTick 和?Vue.nextTick
1)在DOM更新后,會(huì)立刻執(zhí)行 vm.$nextTick 和 Vue.nextTick,所以可以利用它們看到數(shù)據(jù)更改后,立刻看到渲染后頁(yè)面的值
<div id="app">{{ bookName }} </div> const vm = new Vue({el: '#app',data: {bookName: '被討厭的勇氣'} }) vm.bookName = 'JavaScript高級(jí)程序設(shè)計(jì)'; console.log(vm.bookName); // 此時(shí)數(shù)據(jù)已經(jīng)更改 console.log(vm.$el.innerHTML); vm.$nextTick(()=>{console.log(vm.$el.innerHTML); })?【結(jié)果】
?2)vm.$nextTick 和 Vue.nextTick 可以當(dāng)作Promise使用
const vm = new Vue({el: '#app',data: {bookName: '被討厭的勇氣'} }) vm.bookName = 'JavaScript高級(jí)程序設(shè)計(jì)'; console.log(vm.bookName); // 此時(shí)數(shù)據(jù)已經(jīng)更改 vm.$nextTick().then(()=>{console.log(vm.$el.innerHTML); }) Vue.nextTick().then(()=>{console.log(vm.$el.innerHTML); })【結(jié)果】?
?3)vm.$nextTick 和 Vue.nextTick 的區(qū)別
vm.$nextTick 內(nèi)部函數(shù)的 this 指向 Vue 實(shí)例對(duì)象,Vue.nextTick 內(nèi)部函數(shù)的 this 指向 window
4)nextTick 的實(shí)現(xiàn)
異步任務(wù)分為宏任務(wù)(macro)和微任務(wù)(micro),微任務(wù)執(zhí)行在前,宏任務(wù)執(zhí)行在后,在 nextTick 的實(shí)現(xiàn)源碼中,會(huì)先判斷是否支持微任務(wù),不支持后才會(huì)執(zhí)行宏任務(wù)
if(typeof Promise !== 'undefined') {// 微任務(wù)// 首先看一下瀏覽器中有沒(méi)有promise// 因?yàn)镮E瀏覽器中不能執(zhí)行Promiseconst p = Promise.resolve();} else if(typeof MutationObserver !== 'undefined') {// 微任務(wù)// 突變觀察// 監(jiān)聽(tīng)文檔中文字的變化,如果文字有變化,就會(huì)執(zhí)行回調(diào)// vue的具體做法是:創(chuàng)建一個(gè)假節(jié)點(diǎn),然后讓這個(gè)假節(jié)點(diǎn)稍微改動(dòng)一下,就會(huì)執(zhí)行對(duì)應(yīng)的函數(shù)} else if(typeof setImmediate !== 'undefined') {// 宏任務(wù)// 只在IE下有} else {// 宏任務(wù)// 如果上面都不能執(zhí)行,那么則會(huì)調(diào)用setTimeout}4.不發(fā)生重新渲染的情況
1)更改的數(shù)據(jù)必須是存在的數(shù)據(jù),否則不能重新渲染頁(yè)面【例1】;
【例1】不會(huì)報(bào)錯(cuò),但是也不會(huì)渲染頁(yè)面,因?yàn)楸O(jiān)聽(tīng)不到這個(gè)值
<div id="app">{{ book.sentence }} </div> const vm = new Vue({el: '#app',data: {book: {name: '被討厭的勇氣',writer: '岸見(jiàn)一朗',}} }) vm.book.setence="觸手可及但互不干擾"2)更改的數(shù)據(jù)必須是已渲染過(guò)的數(shù)據(jù),否則從性能角度考慮,不會(huì)重新渲染【例2】;
【例2】
<div id="app">{{ book.writer }} </div> const vm = new Vue({el: '#app',data: {book: {name: '被討厭的勇氣',writer: '岸見(jiàn)一朗',}} }) vm.book.name="JavaScript高級(jí)程序設(shè)計(jì)"3)利用索引直接設(shè)置一個(gè)數(shù)組項(xiàng)時(shí)不會(huì)重新渲染【例3】;
【例3】
<div id="app">{{ bookList }} </div> const vm = new Vue({el: '#app',data: {bookList:['被討厭的勇氣','沒(méi)有兇手的殺人夜','親密關(guān)系']} }) vm.bookList[3]="JavaScript高級(jí)程序設(shè)計(jì)"4)修改數(shù)組長(zhǎng)度時(shí)不會(huì)重新渲染【例4】;
【例4】
<div id="app">{{ bookList }} </div> const vm = new Vue({el: '#app',data: {bookList: ['被討厭的勇氣', '沒(méi)有兇手的殺人夜', '親密關(guān)系']} }) vm.bookList.length = 0;5)添加或刪除對(duì)象時(shí)不會(huì)重新渲染【例5】;
<div id="app">{{ bookList }} </div> const vm = new Vue({el: '#app',data: {bookList: ['被討厭的勇氣', '沒(méi)有兇手的殺人夜', '親密關(guān)系']} }) vm.bookList[3] = 'JavaScript高級(jí)程序設(shè)計(jì)'; delete vm.bookList[2];5. 響應(yīng)式更新數(shù)組和對(duì)象
(1)數(shù)組
1)利用數(shù)組方法 pop、pop、shift、unshift、splice、sort、reverse
2)利用vm.$set 或 Vue.set 實(shí)例方法,vm.$set(object, propertyName, value)
3)利用vm.$delete或 Vue.delete刪除數(shù)組中的某一項(xiàng)
<div id="app">{{ bookList }} </div> const vm = new Vue({el: '#app',data: {bookList: ['被討厭的勇氣', '沒(méi)有兇手的殺人夜', '親密關(guān)系']} }) vm.bookList.push('為奴十二年'); vm.$delete(vm.bookList, 2) vm.$set(vm.bookList, 3, '小王子')【結(jié)果】
(2)對(duì)象
1)添加利用 vm.$set 或 Vue.set 實(shí)例方法
2) 刪除利用vm.$delete或 Vue.delete
總結(jié)
以上是生活随笔為你收集整理的Vue的响应式及相关问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 原理_JS引擎对未声明变量的处理
- 下一篇: H5新增API_geoLocation