• vue的简单实现


    因为vue主要是通过数据劫持来实现的,通过getset来完成数据的读取和更新

    这里简单实现data,v-model,computed

    1模版

        <!DOCTYPE html>
        <html>
        <head>
            <title></title>
        </head>
        <body>
        <div id="app">
            <div>{{a.a}}</div>
            <div>{{c}}</div>
            <input type="text" v-model="c">
            {{hello}}
        </div>
        <script src="./mvvm.js"></script>
        <script type="text/javascript">
        
        let vue = new Vue2({
            el:"#app",
            data:{
                a:{a:1},
                b:[1,2,3],
                c:123123
            },
            computed:{
                hello(){
                    return this.a.a+this.c;
                }
            }
        })
        </script>
        </body>
        </html>

    js

    function Vue2(options = {}) {
        this.$options = options;
        let data = this._data = this.$options.data;
        observe(data);
        // this代理了this._data
        for (let key in data) {
            Object.defineProperty(this, key, {
                enumerable: true,
                get() {
                    return this._data[key];
                },
                set(newVal) {
                    this._data[key] = newVal
                }
            })
        }
    initComputed.call(
    this);//初始化computed

    new Compile(options.el, this) } //计算属性的实现 function initComputed(){ let vm = this; let computed = this.$options.computed; Object.keys(computed).forEach(function (k) { Object.defineProperty(vm,k,{
            //如果给的是函数那么调取函数,如果是对象那么获取对象的get方法 get:
    typeof computed[k] === 'function'?computed[k]:computed[k].get(), set(){} }) }) } function Compile(el, vm) { // el表示替换的范围 vm.$el = document.querySelector(el); let frament = document.createDocumentFragment();//文案碎片 while (child = vm.$el.firstChild) {//将app中的内容,移入到内存中 frament.appendChild(child) } //查找节点中的{{}} replace(frament); function replace(frament) { Array.from(frament.childNodes).forEach(function (node) { let text = node.textContent; let reg = /{{(.*)}}/; //判断{{}} if (node.nodeType === 3 && reg.test(text)) { console.log(RegExp.$1)//取出花括号中的变量 let arr = RegExp.$1.split('.');//[a,a],[b],[c] let val = vm; arr.forEach(function (k) { val = val[k] }) new Watcher(vm,RegExp.$1,function (newVal) { node.textContent = text.replace(/{{(.*)}}/, newVal) }) // node.textContent = text.replace(/{{(.*)}}/, val) } //判断v-model if(node.nodeType ===1 /*元素节点*/ ){ let nodeAttrs = node.attributes;//获取属性 console.log(nodeAttrs) Array.from(nodeAttrs).forEach(function (attr) { console.log(attr) let name = attr.name; let exp = attr.value; if(name.indexOf('v-')==0){ node.value = vm[exp]; } new Watcher(vm,exp,function (newVal) { node.value = newVal; }); node.addEventListener('input',function (e) { let newVal = e.target.value; vm[exp] = newVal; }) }) } if (node.childNodes) { replace(node) } }); } vm.$el.appendChild(frament) } //观察者 给队形增加Object.defineProperty // 数据劫持 function Observe(data) { let dep = new Dep(); for (let key in data) { let val = data[key]; observe(val); Object.defineProperty(data, key, { enumerable: true, get() { Dep.target&&dep.addSub(Dep.target);//监控值的变化 return val }, set(newVal) { if (newVal === val) { return } val = newVal; observe(newVal) dep.notify()//让所有的watch的update方法执行 } }) } } function observe(data) { if (typeof data !== "object") return; return Observe(data) } //发布订阅 function Dep() { this.subs = [] } Dep.prototype.addSub = function (sub) {//订阅 this.subs.push(sub) } Dep.prototype.notify = function () { this.subs.forEach(sub=>sub.update()) } function Watcher(vm,exp,fn) { this.vm = vm; this.exp = exp; this.fn = fn; Dep.target = this; let val = vm; let arr = exp.split('.') arr.forEach(function (k) { val = val[k] }) Dep.target = null; } Watcher.prototype.update=function () { let val = this.vm; let arr = this.exp.split('.'); arr.forEach(function (k) { val = val[k] }) this.fn(val) }
  • 相关阅读:
    win10 系统下myeclipse 下启动 tomcat7 所遇到的问题
    搭建个人博客&论坛(LAMP):wordpress、discuz、phpMyAdmin
    拟合优度检验和独立性检验
    作业day19
    numpy
    正则模块
    模块功能
    模块
    匿名函数、异常处理
    递归和迭代器
  • 原文地址:https://www.cnblogs.com/caoruichun/p/10801412.html
Copyright © 2020-2023  润新知