<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>
{{a.b}}
</div>
<div>
{{c}}
</div>
</div>
<script>
// 判断是不是对象类型
function isObj(x){
if(Object.prototype.toString.call(x) == '[object Object]'){
return true
}
}
function Vue(options){
this._data = options.data
observe(this._data)
// 数据代理
for(let key in this._data){
Object.defineProperty(this,key,{
get(){
return this._data[key]
},
set(newVal){
this._data[key] = newVal
}
})
}
// 模板编译
compile(options.el,this)
}
function observe(data){
for(let key in data){
let val = data[key]
Object.defineProperty(data,key,{
get(){
return val
},
set(newVal){
if(newVal === val){
return
}
val = newVal
if(isObj(newVal)){
observe(newVal)
}
}
})
if(isObj(data[key])){
observe(data[key])
}
}
}
function compile(el,vue){
let dom = document.querySelector(el)
let fragment = document.createDocumentFragment()
while(child = dom.firstChild){
fragment.append(child)
}
let reg = /\{\{(.*)\}\}/
replace(fragment)
function replace(fragment){
Array.from(fragment.childNodes).forEach(node=>{
if(node.nodeType === 3 && reg.test(node.textContent)){
let l = RegExp.$1.split(".")
let val = vue
l.forEach(item=>{
val = val[item]
})
node.textContent = node.textContent.replace(reg,val)
}
if(node.childNodes){
replace(node)
}
})
}
dom.appendChild(fragment)
}
let vue = new Vue({
el:"#app",
data:{a:{b:1},c:2}
})
</script>
</body>
</html>
vue源码分析之模板编译(三)
最新推荐文章于 2022-11-04 10:33:23 发布