文章目录
一、准备步骤
(1)、新建vue.js文件
(2)、新建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{ str }}
<h1>{{ str }}</h1>
<input type="text" v-model="str">
<button @click="change()">hahh</button>
</div>
</body>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
str:'hahh'
},
})
</script>
</html>
(3)、在文件中引入vue.js文件
注意:这时候的vue.js里面的是什么东西都没有,因此我们是在vue.js中手写vue插值语法
二、开始操作
1、原生vue是使用new的形式
注意:这里new的形式表示vue.js里面是采用类的方式
1.1、编写Vue类
class Vue{
}
2、在使用官方vue.js时在html文件中是采用向Vue类中传入一个大对象。
例如:
new Vue({
el:'#app',
data:{},
methods:{},
……
})
2.1、在Vue类中传入大对象
class Vue{
/*这里的options是前面传过来的大对象,放在constructer构造方法里面*/
constructor(options){
}
}
2.2、实现在官方vue中打印的this. d a t a 和 t h i s . data和this. data和this.el
class Vue{
/*这里的options是前面传过来的大对象,放在constructer构造方法里面*/
constructor(options){
this.$data = options.data
this.$el = document.querySelector(options.el) //选择根节点
}
}
2.3、实现插值解析
这里我们先写一个实现模版解析的方法,并在构造方法中使用它
class Vue{
/*这里的options是前面传过来的大对象,放在constructer构造方法里面*/
constructor(options){
this.$data = options.data
this.$el = document.querySelector(options.el) //选择根节点
this.analysis( this.$el ) //向方法中传入根节点
}
analysis(el){
//首先得到根节点下的所有子节点 得到的是一个 Nodelist 数组
const childNodes = el.childNodes
//遍历所有子节点
childNodes.forEach(childEl => {
//判断节点类型
/*
* 3 为文本节点
* 1 为元素节点
* 我们在 实现模版解析的时候 实际是解析的 {{}} 中的东西,因此我们只需要找到文本节点即可,若不是文本节点继续找就行了
*/
if(childEl.nodeType == 1){
if(childEl.childNodes.length > 0){
//实现一种递归的形式
analysis(childEl)
}
}
if(childEl.nodeType == 3){
// 正则判断 {{}}
let reg = /\{\{(.*?)\}\}/g
childEl.textContent = text.replace(reg,(macth,vmKey) => {
vmKey = vmKey.trim()
return this.$data[vmKey];
})
}
})
}
}
3、写法2
注意:这一个比较通俗易懂
注意!!!:这种方式有一个小bug不知有没有人能够看出来呀 哈哈哈哈
class Vue{
constructor( options ){
this.$el = document.querySelector( options.el )
this.$data = options.data
this.analysis( this.$el )
}
// 模版解析
analysis( rootNode ){
const childNodes = rootNode.childNodes
// 遍历子节点
childNodes.forEach(child => {
//判断节点类型
/*
* 3 为文本节点
* 1 为元素节点
* 我们在 实现模版解析的时候 实际是解析的 {{}} 中的东西,因此我们只需要找到文本节点即可,若不是文本节点继续找就行了
*/
if(child.nodeType == 3){
//得到原节点为解析的内容 {{ xxx }}
const nodeTextContent = child.textContent.trim()
//得到 '{{' 和 '}}' 符号的下标
let begin = nodeTextContent.indexOf('{{')
let end = nodeTextContent.indexOf('}}')
//得到 {{ }} 符号中间的属性
let key = nodeTextContent.slice(begin+2,end).trim()
//判断模版字符是否完整
if( begin > -1 && end > -1 ){
//完整就解析
child.textContent = this.$data()[key]
}
}
//递归
if(child.nodeType == 1){
this.analysis( child )
}
});
}
}
总结
提示:需要对dom树有一定的了解