持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
接上文数据劫持完成以后,就开始需要和视图进行挂钩了,开始写模板了。回到我们的index.html中增加模板。
第一步 增加模板
// index.html
<div id="app">
<span>{{name}}</span>
<span>{{age}}</span>
</div>
<script src="vue.js"></script>
<script>
const vm = new Vue({
data:{
name:'i东东',
age:18
},
el:'#app',
})
</script>
在页面中可以用Mustache语法,也就是双大括号进行取值,但是我们需要对模板进行编译,所以我们就加一个属性el:'#app',表示我们要将数据解析到el元素上,紧接着就需要将模板里面的数据进行替换。首先能够想到的方法就是:
- 模板引擎:每次拿到模板,用数据进行替换。这样做的缺点就是性能差,需要正则匹配替换(vue1.0的时候没有引入虚拟DOM的改变)
- 操作虚拟DOM:数据变化后比较虚拟DOM的差异,最后更新需要更新的地方
- 核心就是将模板转换成js语法,通过js语法去生成虚拟DOM
第二步 判断是否有模板
语法之间的转换,像ES6转到ES5 语法转义需要先变成语法树再重新组装代码成为新的语法,需要将模板先编译成ast语法树再进行转换,那么我们就需先拿到模板,再进行解析。模板可以写在下面这些地方:
- template
- el
- render(){return h('div',{ })} 将template语法转化为render函数
const vm = new Vue({
data:{
name:'i东东',
age:18
},
// el:'#app', // 需要将数据解析到el元素上
template:'<div>hh</div>'
render(){
return h('div',{
})
}
})
vm.$mount('#app')
紧接着就需要到到我们初始化的地方init.js进行判断是否有el,如果有的话说明有模板,这个时候就需要去挂载数据
// src/init.js
if (options.el) {
vm.$mount(options.el) // 实现数据挂载
}
Vue.prototype.$mount = function (el) {
......
}
第三步 扩展$mount
Vue.prototype.$mount = function (el) {
const vm = this
el = document.querySelector(el)
let ops = vm.$options
if (!ops.render) { // 先看有没有写render函数
let template // 没有render函数再看有没有写template,没写template就用外部的template
if (!ops.template && el) { // 内有写模板,但是写了el
template = el.outerHTML
} else {
if (el) {
template = ops.template // 如果有el就采用模板进行编译
}
}
// 写了template就用template
if (template) {
// 这里需要对模板进行编译
const render = compileToFcuntion(template)
ops.render = render // jsx最终会编译成h('xxx')
}
}
}
script标签引用的vue.global.js这个编译过程是在浏览器运行的,runtime(运行时)是不包含模板编译的 整个编译是打包的时候通过loader来转义.vue文件的,用runtime的时候不能使用template
运行index.html控制台输出如上信息,就正确拿到了模板,最后就可以通过compileToFcuntion(模板)函数,对模板进行编译了,这个方法属于核心编译方法,所以在src下新增一个模块compiler。
src/compiler/index.js
// 对模板进行编译处理
export function compileToFcuntion(template){
// 1.将template转换为ast语法树
// 2.生成render方法 render方法执行后的结果就是虚拟DOM
console.log(template);
}
运行index.html当
src/compiler/index.js的console.log(template)输出如上图,则说明成功了,接下来就可以在src/compiler/index.js进行模板的编译处理。
最后
对模板的编译处理放在下一篇写,不断学习进阶,加油!