接上篇文章,新建computedMethods.js,复制observer.js代码。
在Vue类上加入computed,computed会去取值,取值就会添加watcher,形成依赖关系。Vue的constructor改写:
constructor(options) {
this.$el = options.el;
this.$data = options.data;
let computed = options.computed
//判断根元素是否存在,存在编译模板
if (this.$el) {
//将数据全部转化为object.defineProperty来定义
new Observer(this.$data)
for(let key in computed){ //有依赖关系 数据变化
Object.defineProperty(this.$data,key,{
get:()=>{
return computed[key].call(this)
}
})
}
//把数据获取操作,vm上的取值操作,都代理到vm.$data
this.proxyVm(this.$data)
new Compiler(this.$el, this);//编译
}
}
methods 我们采用v-on:click的方法绑定点击事件,在编译元素中解析了v-,按之前的写法会得到on:click,需要再次分割,得到click,改写编译元素的方法
// 编译元素
compileElement(node) {
let attributes = node.attributes //类数组
let attributesArr = [...attributes] //转数组
attributesArr.forEach(attr => { //attr 格式 name=value 找到元素
let { name, value: expr } = attr
if (this.isDirective(name)) { //注意此处命名变化,一直觉得起名字很费劲。
let [, directive] = name.split('-')
let [directiveName,eventName] = directive.split(':')
CompilerUtil[directiveName](node, expr, this.vm,eventName) //调用工具类 指令有很多,所以写一个工具类,用来处理不同指令
}
})
}
在编译工具中加入on
on(node,expr,vm,eventName){ //expr = change
node.addEventListener(eventName,(evt)=>{
vm[expr].call(vm,evt)
})
},
在 vue类中加入methods,获取到事件名即可
constructor(options) {
this.$el = options.el;
this.$data = options.data;
let computed = options.computed
let methods = options.methods
//判断根元素是否存在,存在编译模板
if (this.$el) {
//将数据全部转化为object.defineProperty来定义
new Observer(this.$data)
for(let key in computed){ //有依赖关系 数据变化
Object.defineProperty(this.$data,key,{
get:()=>{
return computed[key].call(this) //将this指向为vm
}
})
}
for(let key in methods){
Object.defineProperty(this,key,{
get(){
return methods[key]
}
})
}
//把数据获取操作,vm上的取值操作,都代理到vm.$data
this.proxyVm(this.$data)
new Compiler(this.$el, this);//编译
}
}
网友评论