Vue.watche 原始碼實現
watch
vm.$watch(expOrFn,callback,[options])
功能
觀察Vue例項變化的一個表示式或計算屬性函式。回撥函式得到的引數為新值和舊值。表示式值接收監督的鍵路徑
引數
- exOrFn:要監視的$data 中的屬性,可以說表示式或函式
- callback:資料變化後執行的函式
函式:回撥函式
物件:具有handler屬性(字串或者函式),如果該屬性為字串則methods中相應的定義 - options:可選的選項
deep: 布林型別,深度監聽
immediate: 布林型別,是否立即執行一次回撥函式
示例
const vm = new Vue({
el:"#app",
data:{
user:{
fisrtName: 'aaaa',
lastName: 'bbbbb'
}
}
})
vm.$watch('user',function(newValue,oldValue){
this.user.firstName = newValue.firstName + " " + newValue.lastName
},{
immediate: true,
deep: true
})
三種型別的Watcher物件
- 沒有靜態方法,因為$watch方法中要是用Vue的例項
- Watcher分三種:計算屬性Watcher,使用者Watcher(偵聽器)、渲染Watcher
建立順序:計算屬性Watcher,用於Watcher,渲染Watcher - vm.$watch()
src/core/instance/state.js
部分程式碼
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props) // 初始化props,並且通過defineReactive函式將值轉換為set,get
if (opts.methods) initMethods(vm, opts.methods) // 將選項中的methods注入到vue例項,
if (opts.data) {
initData(vm) //
} else {
observe(vm._data = {}, true /* asRootData */) //轉換成響應式資料
}
if (opts.computed) initComputed(vm, opts.computed) // 初始化computed
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch) // 初始化watch
}
}
function initWatch (vm: Component, watch: Object) {
for (const key in watch) {
const handler = watch[key]
if (Array.isArray(handler)) {
for (let i = 0; i < handler.length; i++) {
createWatcher(vm, key, handler[i])
}
} else {
createWatcher(vm, key, handler)
}
}
}
function createWatcher (
vm: Component,
expOrFn: string | Function,
handler: any,
options?: Object
) {
if (isPlainObject(handler)) { // hundler是回撥函式,就是對應傳入方法
options = handler
handler = handler.handler
}
if (typeof handler === 'string') {
handler = vm[handler]
}
return vm.$watch(expOrFn, handler, options)
}
export function stateMixin (Vue: Class<Component>) {
// flow somehow has problems with directly declared definition object
// when using Object.defineProperty, so we have to procedurally build up
// the object here.
const dataDef = {}
dataDef.get = function () { return this._data }
const propsDef = {}
propsDef.get = function () { return this._props }
if (process.env.NODE_ENV !== 'production') {
dataDef.set = function () {
warn(
'Avoid replacing instance root $data. ' +
'Use nested data properties instead.',
this
)
}
propsDef.set = function () {
warn(`$props is readonly.`, this)
}
}
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
// 獲取 Vue 例項的this
const vm: Component = this
if (isPlainObject(cb)) {
// 判斷如果 cb 是物件執行createWatcher
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {}
// 標記為使用者 watcher
options.user = true
// 建立使用者 watcher 物件
const watcher = new Watcher(vm, expOrFn, cb, options)
// 判斷 immediate 物件
if (options.immediate) {
// 立即執行一次cb回撥,並把當前值傳入
try {
cb.call(vm, watcher.value)
} catch (error) {
handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)
}
}
// 返回取消監聽的方法
return function unwatchFn () {
watcher.teardown()
}
}
}
相關文章
- Promise原始碼實現Promise原始碼
- HashMap原始碼實現分析HashMap原始碼
- webpack Hmr 原始碼實現Web原始碼
- 仿Express原始碼實現(-)Express原始碼
- PostgreSQL MVCC 原始碼實現SQLMVC原始碼
- Axios 原始碼解讀 —— 原始碼實現篇iOS原始碼
- Vue.js 原始碼實現Vue.js原始碼
- Promise實現原理(附原始碼)Promise原始碼
- 紅黑樹原始碼實現原始碼
- 70行實現Promise核心原始碼Promise原始碼
- 深入原始碼解析 tapable 實現原理原始碼
- 原始碼|ThreadLocal的實現原理原始碼thread
- HashMap 實現原理與原始碼分析HashMap原始碼
- HashMap實現原理及原始碼分析HashMap原始碼
- RTree原始碼——C語言實現原始碼C語言
- spring原始碼解析 (七) 事務底層原始碼實現Spring原始碼
- mongodb核心原始碼實現及效能優化系列:Mongodb write寫(增、刪、改)模組原始碼實現MongoDB原始碼優化
- 手動實現一個promise(原始碼)Promise原始碼
- 原始碼解析.Net中DependencyInjection的實現原始碼
- 從kratos分析BBR限流原始碼實現原始碼
- Vue原始碼探究-核心類的實現Vue原始碼
- 【React原始碼解讀】- 元件的實現React原始碼元件
- Netty原始碼解析 -- PoolSubpage實現原理Netty原始碼
- 《Spring原始碼分析》IOC的實現Spring原始碼
- synchronized實現原理及ReentrantLock原始碼synchronizedReentrantLock原始碼
- Netty原始碼解析 -- PoolChunk實現原理Netty原始碼
- musl中strlen原始碼實現和分析原始碼
- TCC-Transaction 原始碼分析 —— TCC 實現原始碼
- 從原始碼解讀Category實現原理原始碼Go
- Redis原始碼閱讀:sds字串實現Redis原始碼字串
- Go 中的鎖原始碼實現:MutexGo原始碼Mutex
- ConcurrentHashMap 實現原理和原始碼分析HashMap原始碼
- InnoDB MVCC實現原理及原始碼解析MVC原始碼
- 【MyBatis原始碼分析】外掛實現原理MyBatis原始碼
- 【vue原始碼】簡單實現directive功能Vue原始碼
- 使用Akka實現CQRS/ES的原始碼原始碼
- .NET原始碼Stack和Queue的實現原始碼
- mongodb核心原始碼實現、效能調優、最佳運維實踐系列-command命令處理模組原始碼實現三MongoDB原始碼運維