[toc]
### 1.$nextTick使用場景
在vue中,如果改變了dom內部綁定的值,立即獲取dom的innerHTML,會出現拿到的還是原來的值,這個時候需要用this.$nextTick方法執行回調函數
```js
<div id="app">{{a}}</div>
let vm = new Vue({
el: '#app',
data: {
a: 1
},
mounted() {
this.a = 2
console.log('dom節點內容:', app.innerHTML) // 打印出來的還是1
}
})
```
```js
mounted() {
this.a = 2
this.$nextTick(() => {
console.log('dom節點內容:', app.innerHTML) // 這樣打印出來的就是2
})
}
```
### 2.原理
$nextTick當中的操作不會立即執行,而是會等數據、和dom更新之后再執行。
如何實現?
1.$nextTick內部的方法,會被放到一個callbacks數組中
2.當vue中的數據發生更改時,會觸發set方法,set會調用dep上的notify方法,通知watcher執行update方法
3.update方法會觸發queueWatcher方法,queueWatcher會調用nextTick,并添加一個flushSchedulerQueue方法
4.最后會依次執行callbacks數組中存入的nextTick回調方法,但是這個方法會被promise.then或者Mutation.observer包裹起來,或者setTimeout(根據瀏覽器是否支持判斷),實現了一個異步的調用
```js
update () {
/* istanbul ignore else */
if (this.lazy) {
this.dirty = true
} else if (this.sync) {
this.run()
} else {
queueWatcher(this) // 異步更新邏輯
}
}
```
```js
// queueWatcher
nextTick(flushSchedulerQueue)
```
```js
function flushCallbacks () {
pending = false
const copies = callbacks.slice(0)
callbacks.length = 0
for (let i = 0; i < copies.length; i++) {
copies[i]()
}
}
```
-----
把回調函數放入callbacks等待執行
將執行函數放到微任務或者宏任務中
事件循環到了微任務或者宏任務,執行函數依次執行callbacks中的回調
但是nextTick是同步執行的,同步的把里面的值放到異步隊列里了
### 3.watcher去重
```js
this.a = 100
this.a = 200
//代碼執行了兩次,但是視圖只更新了一次
```
因為vue的watcher會去重。
數據發生變化之后,vue的dom并不一定馬上發生變化,vue將開啟一個隊列,并緩沖在同一事件循環中發生的所有數據改變,如果同一個watcher被多次觸發,只會被推入到隊列一次。
```js
addDep (dep: Dep) {
const id = dep.id
if (!this.newDepIds.has(id)) {
this.newDepIds.add(id)
this.newDeps.push(dep)
if (!this.depIds.has(id)) {
dep.addSub(this)
}
}
}
```
原理:添加dep的時候,會看這個dep的id,如果已經有了,那么就不會往里面push了
- 0. MVC和MVVM
- 1. v-model無法實時更新的解決辦法
- 1. Vue 指令
- 1. v-cloak&v-text&v-html
- 2. v-bind
- 3. v-model
- 7. v-for指令的幾種使用方式
- 8. v-if和v-show的使用
- 2. 事件修飾符
- 3. 通過屬性設置樣式
- 1. 通過屬性綁定設置元素class
- 2. 通過屬性綁定設置元素style
- 4. 自定義指令
- 11. 自定義全局指令
- 12. 自定義私有指令
- 5. 過濾器
- 6. 鍵盤指令
- 7. 生命周期
- 8. vue-resource
- 9. 動畫
- 1. 使用過渡類名實現動畫
- 2. 使用animate.css實現動畫
- 3. 鉤子函數實現小球半場動畫
- 10. 組件
- 1. 全局組件的創建方式
- 2. 私有組件的創建方式
- 3. 組件中的data和methods
- 4. component元素
- 5. 組件配合transition元素實現動畫
- 6. 父組件傳參傳方法
- 11. 路由
- 1. 什么是路由
- 2. vue-router的使用
- 3. 使用router-link&query方式傳遞參數
- 4. 使用param傳值
- 5. 使用children屬性實現路由嵌套
- 6. router-view之間獲取父級data
- 7. 實現路由跳轉的幾種方式
- 12. 設置緩存
- 13. $ref 操作DOM&獲取自定義屬性
- 14. 初始化一個項目
- 15. 使用并封裝一個axios方法
- 17. vuex
- 18. watch 監聽 data數據
- 19. keep alive 緩存路由組件
- vue效果實現
- 1. 實現頂部根據滑動漸隱漸現
- 2. 制作一個動畫包裹組件
- 20. vue 中的數據類操作
- 第三方工具&ui
- 1. vant-ui
- 1. 上拉加載更多
- 2. 使用圖片預加載
- 2. better-scroll
- 1. 實現上下滑動效果
- 2. 實現兩欄式點擊滑動跳轉
- vue3
- compositionApi
- 2. ref 和 reactive
- 4. watch
- 5. watchEffect
- 7.使用ref操作dom
- effect副作用
- 1. 新特性
- 3. 生命周期
- 6.定義props
- 實現自定義組件v-model
- vue面試題
- 1.對mvvm的理解
- 2.vue2和vue3響應式數據的理解
- 3.vue中如何檢測數組的變化
- 4.vue中如何進行依賴收集
- 5.如何理解vue中的模板編譯原理
- 6.vue生命周期以及原理
- 7.vue組件data為什么必須是個函數
- 8.vue-router原理
- 9.vue.mixin原理
- 10.$nextTick原理
- 11.computed和watch的區別
- vue SSR服務端渲染
- 1.什么是服務端渲染
- 2.快速創建服務端渲染