Vue2指令原理手写

文件结构

index.js

/*
 * @Author: RealRoad
 * @Date: 2024-10-31 17:13:50
 * @LastEditors: Do not edit
 * @LastEditTime: 2024-10-31 17:15:57
 * @Description: 
 * @FilePath: \project_10_08\vite-project\src\testVue\index.js
 */
import Vue from './Vue.js'
window.Vue=Vue

Vue.js

import Compile from './Compile.js'
import observe from './observe.js'
export default class Vue{
    constructor(options){
        //把参数options对象存为$options
        this.$options = options ||{}
        //数据
        this._data=options.data || undefined;
        Observe(this._data)
        //数据要变为响应式的


        //模板编译
        new Compile(options.el,this)
    }
}

Compile.js

/*
 * @Author: RealRoad
 * @Date: 2024-10-31 16:25:34
 * @LastEditors: Do not edit
 * @LastEditTime: 2024-10-31 16:28:44
 * @Description: 
 * @FilePath: \project_10_08\vite-project\src\testVue\Compile.js
 */
export default class Compile{
    constructor(el,vue){
        //vue实例
        this.$vue=vue;
        //挂载点
        this.$el=document.querySelector(el)
        if(this.$el){
            //调用函数,让节点变为fragment,类似与mustache中的tokens。
            //实际上用的是AST,这里就是轻量级的,fragment
           let $fragment= this.node2Fragment(this.$el);
            //编译
            this.compile($fragment);


    }
}
    node2Fragment(el){
        var fragment=document.createDocumentFragment();
        var child;
        //el为第一个子元素,循环添加到fragment中

        //让所有dom节点都添加到fragment中
        while(child=el.firstChild){
            fragment.appendChild(child);
        }

        return fragment
    }
    compile(el){
        //获取所有子节点
        var childNodes=el.childNodes;
        var self=this
        //遍历所有子节点
        for(let i=0,len=childNodes.length;i<len;i++){
            let node=childNodes[i];
            //判断是否是元素节点
            if(node.nodeType===1){
                self.compileElement(node);
            }else if(node.nodeType===3){
                self.compileText(node);
        }}

     }
     compileElement(node){
        //获取所有属性节点
        var attributes=node.attributes;
       
        //类数组变为数组
        [].slice.call(attributes).forEach(attr=>{
            if(attr.name==="v-model"){
                //获取属性值
                var value=attr.value;
                node.addEventListener("input",()=>{
                    this.$vue[value]=node.value
                })
            }else if(attr.name==="v-text"){
                node.textContent=this.$vue[attr.value]
            }
            else if(attr.name==="v-html"){
                node.innerHTML=this.$vue[attr.value]

             }
             else if(attr.name==="v-bind"){
                node.setAttribute(attr.value,this.$vue[attr.value])
            }
            else if(attr.name==="v-on"){
                node.addEventListener(attr.value,()=>{

             })}else if(attr.name==="v-show"){
                node.style.display=this.$vue[attr.value]===true?"":"none"

              }else if(attr.name==="v-if"){
                node.style.display=this.$vue[attr.value]===true?"":"none"}
                

        })
    }
    compileText(){

    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mez_Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值