好家伙,
代码出了点bug,暂时只能实现这两种形式
完整代码已开源https://github.com/Fattiger4399/analytic-vue.git
Vue:watch的多种使用方法
watch有非常多种使用方式,我们要对其进行分类讨论处理
1.初始化:
//initState.js
if (opts.watch) {
initWatch(vm);
}
initWatch()方法
function initWatch(vm) {
//1 获取watch
let watch = vm.$options.watch
console.log(watch)
//2 遍历 { a,b,c}
for (let key in watch) {
//2.1获取 他的属性对应的值 (判断)
let handler = watch[key] //数组 ,对象 ,字符,函数
if (Array.isArray(handler)) {//数组 []
handler.forEach(item=>{
服务器托管网 createrWatcher(vm,key,item)
})
} else {//对象 ,字符,函数
//3创建一个方法来处理
createrWatcher(vm,key,handler)
}
}
}
createrWatcher()
//格式化处理
//vm 实例
//exprOrfn key
//hendler key对应的值
//options 自定义配置项 vue自己的为空,用户定义的才有
function createrWatcher(vm,exprOrfn,handler,options){
//3.1 处理handler
if(typeof handler ==='object'){
options = handler; //用户的配置项目
handler = handler.handler;//这个是一个函数
}
if(typeof handler ==='string'){// 'aa'
handler = vm[handler] //将实例行的方法作为 handler 方法代理和data 一样
}
//其他是 函数
//watch 最终处理 $watch 这个方法
// console.log(vm,"||vm")
// console.log(exprOrfn,"||exprOrfn")
// console.log(handler,"||handler")
// console.log(options,"||options")
return vm.$watch(vm,exprOrfn,handler,options)
}
原型上挂$watch方法
export function stateMixin(vm) {
console.log(vm,6666)
//列队 :1就是vue自己的nextTick 2用户自己的
vm.prototype.$nextTick = function (cb) { //nextTick: 数据更新之后获取到最新的DOM
// console.log(cb)
nextTick(cb)
},
vm.prototype.$watch =function(Vue,exprOrfn,handler,options={}){ //上面格式化处理
// console.log(exprOrfn,handler,options)
//实现watch 方法 就是new watcher //渲染走 渲染watcher $watch 走 watcher user false
// watch 核心 watcher
let watcher = new Watcher(Vue,exprOrfn,handler,{...options,user:true})
if(options.immediate){
handler.call(Vue) //如果有这个immediate 立即执行
}
}
}
2.watcher.js
watcher类
class Watcher { //vm 实例 //exprOrfn vm._updata(vm._render()) constructor(vm, exprOrfn, cb, options) { // 1.创建类第一步将选项放在实例上 this.vm = vm; this.exprOrfn = exprOrfn; this.cb = cb; this.options = options; // 2. 每一组件只有一个watcher 他是为标识 this.id = i服务器托管网d++ this.user = !!options.user // 3.判断表达式是不是一个函数 this.deps = [] //watcher 记录有多少dep 依赖 this.depsId = new Set() if (typeof exprOrfn === 'function') { this.getter = exprOrfn }else{ //{a,b,c} 字符串 变成函数 this.getter =function(){ //属性 c.c.c let path = exprOrfn.split('.') let obj = vm for(let i = 0;i){ obj = obj[path[i]] } return obj // } } // 4.执行渲染页面 this.value = this.get() //保存watch 初始值 } addDep(dep) { //去重 判断一下 如果dep 相同我们是不用去处理的 let id = dep.id // console.log(dep.id) if (!this.depsId.has(id)) { this.deps.push(dep) this.depsId.add(id) //同时将watcher 放到 dep中 // console.log(666) dep.addSub(this) } // 现在只需要记住 一个watcher 有多个dep,一个dep 有多个watcher //为后面的 component } run() { //old new let value = this.get() //new let oldValue = this.value //old this.value = value //执行 hendler (cb) 这个用户wathcer if(this.user){ this.cb.call(this.vm,value,oldValue) } } get() { // Dep.target = watcher pushTarget(this) //当前的实例添加 const value = this.getter()// 渲染页面 render() with(wm){_v(msg,_s(name))} ,取值(执行get这个方法) 走劫持方法 popTarget(); //删除当前的实例 这两个方法放在 dep 中 return value } //问题:要把属性和watcher 绑定在一起 去html页面 // (1)是不是页面中调用的属性要和watcher 关联起来 //方法 //(1)创建一个dep 模块 updata() { //三次 //注意:不要数据更新后每次都调用 get 方法 ,get 方法回重新渲染 //缓存 // this.get() //重新渲染 queueWatcher(this) } }
3.看看效果
id="app">{{a}}'./dist/vue.js'> let vm = new Vue({ el: "#app", data: { a: 1, b:[1,2], c:{c:{c:100}} }, methods:{ aa(){ console.log(2000) } }, //watch 基本使用方式 //1 属性 :方法(函数) //2 属性 :数组 //3 属性 :对象 //4 属性 :字符串 watch: { 'c.c.c'(newValue,oldValue){ console.log(newValue,oldValue,'||this isnewValue,oldValue from c.c.c') }, a:{ handler(){ // console.log('a数据更新') }, immediate:true }, // a:'aa', } }) vm.a = 100 // vm.b[1] = 2 console.log(vm.c.c.c=2000)
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
目录 一、前言 二、什么是单例模式 1、Singleton类 2、客户端 三、单例模式三要素 四、单例模式的应用 1、数据库连接池 2、配置信息 3、日志记录器 五、单例模式优缺点 1、优点 ①服务器托管网、节约资源 ②、全局访问 ③、控制实例 2、缺点 ①、…