• 数据响应式 模仿vue 渲染数据、双向绑定


    模仿vue 渲染数据、双向绑定

    创建html页面

      <div id="app">
        {{ name }}
        <div>{{age}}</div>
        <span>{{message}}</span>
        <div>
        <input v-model="model" />
        {{ model }}
      </div>
    

    js 部分

    class Vue extends EventTarget {
      constructor(option) {
        super();
        this.option = option;
        // 赋值data值
        this.$data = this.option.data;
        // 获取当前 app
        this.el = document.querySelector(this.option.el);
        this.observe(this.$data)
        this.compilNode(this.el)
      }
    
      observe(data) {
        const that = this;
        this.$data = new Proxy(data, {
          get(target, prop) {
            // 返回调用值
            return target[prop];
          },
          set(target, prop, newValue) {
            // 创建一个事件对象,名字为newEvent,类型为 prop传递名称
            let event = new CustomEvent(prop, {
              detail: newValue
            })
            // 触发自定义事件 
            that.dispatchEvent(event);
            // target[prop] = newValue
            // return newValue
            return Reflect.set(target, prop, newValue)
          }
        })
      }
    
      compilNode(el) {
        let child = el.childNodes;
        Array.from(child).forEach((node) => {
          if(node.nodeType === 3) {
            let text = node.textContent;
            let reg = /{{s*([^s{}]+)s*}}/g; //匹配当前页面{{name}}值
            if(reg.test(text)){
              let $1 = RegExp.$1;
              // 查看当前data 是否有值 && 替换当前内容
              this.$data[$1] && (node.textContent = text.replace(reg, this.$data[$1]));
              // 将自定义事件绑定在 EventTarget 对象上
              this.addEventListener($1, e=>{
                // 监听当前 name名称 替换DOM内容
                node.textContent = text.replace(reg, e.detail);
              })
            }
          } else if(node.nodeType === 1){
            let attr = node.attributes;
            // 获取当前自定义属性 查看是否为v-model
            if(attr.hasOwnProperty('v-model')) {
              // 获取v-model 值
              let keyName = attr['v-model'].nodeValue;
              // 将仓库值赋值给当前文本框
              node.value = this.$data[keyName];
              // 监听文本框内容是否改变
              node.addEventListener('input', e => {
                // 修改仓库值
                this.$data[keyName] = node.value
              })
            }
            // 传递当前元素 处理元素标签
            this.compilNode(node);
          }
        })
      }
    }
    
     // 引用
       var vm = new Vue({
        el: '#app',
        data: {
          name: '张三',
          age: 15,
          model: '这是双向数据绑定值',
          message: '这是一个说明文件'
        }
      })
    

    视图

  • 相关阅读:
    lua的数组下标是从1开始的
    DestroyImmediate的一些坑
    c#的IDisposable
    unity工具开发(转)
    winform控件命名规范对照表
    C#调用Exe程序示例
    System.Diagnostics.Process.Start的妙用
    C#中AppDomain.CurrentDomain.BaseDirectory及各种路径获取方法
    C# WindowsAPI
    TabPage判断重复添加Page
  • 原文地址:https://www.cnblogs.com/wangyong1997/p/13259104.html
Copyright © 2020-2023  润新知