• 19. vue的原理


    vue:原理1 => Object.defineProperty

    当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

    creat对象

    let obj1 = {};
    //定义对象 Object.create(null)
    //包含 Object类里的的默认方法 new Object();

    let obj2 = Object.create(null);
    //创建真正的空对象 {里面生命都没有}

    exp:

    <script>
    
    let obj1 = {};
    //定义对象  Object.create(null)
    //包含 Object类里的的默认方法  new Object();
    
    let obj2 = Object.create(null);     
    //创建真正的空对象 {里面生命都没有}
    
    console.log(1,obj1);
    console.log(2,obj2);
    
    </script>
    

    res:
    image
    exp:
    //定义对象 Object.create(null/obj)

    let p1 = new Person("张三",18);
    let p2 = Object.create(p1); ///相当于继承 自己身上没有任何属性

    <script>
    //定义对象  Object.create(null/obj)
    class Person{
        constructor(name,age){
            this.name = name;
            this.age = age;
        }
        getName(){
            return this.name;
        }
        getAge(){
            return this.age;
        }
    }
    class Worker extends Person{
    
    }
    let p1 = new Person("张三",18); 
    let p2 = Object.create(p1); ///相当于继承  自己身上没有任何属性
    
    console.log(1,p1);
    console.log(2,p2);
    console.log(3,new Worker("aaa",10));
    
    console.log("------------------------------------");
    
    console.log(2,p2,p2.name,p2.age,p2.getName,p2.getAge);
    </script>
    

    res:
    image

    语法:

    Object.defineProperty(对象, 属性, 描述对象options)

    description、options:

    value     初始化值
    writable    是否可以修改
    enumerable  是否可以枚举(循环、遍历)
    configurable  是否可以配置 删除
    get       获取数据时触发
    set       设置,更改数据时触发

    Object.defineProperty(obj,"name",{
        value:"abc",  初始化值
        writable:true, 是否可以修改
        enumerable:true,  是否可以枚举(循环、遍历)
        configurable:true, 是否可以配置 删除
    });
    

    默认情况下:
    value:默认值 undefined
    writable/enumerable/configurable都是false

    exp1:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
    //函数必须有三个参   
    //Object.defineProperty(对象, 属性, 描述对象options)
    //作用 : 用来定义和修改以及监听对象的属性变化的
    
    let obj = {a:1,b:2};
    
    Object.defineProperty(obj,"name",{
        value:"abc",
    });
    
    //修改
    obj.name = "ccc";
    //获取
    console.log(obj); //{a: 1, b: 2, name: "abc"}
    console.log(obj.name);//abc
    
    console.log("------循环 for in --");
    for(let name in obj){
        console.log(name + ":" + obj[name]);
    }//a:1
     //b:2
    
    console.log("------循环 Object.keys--");
    console.log(Object.keys(obj));//["a", "b"]
    console.log(Object.values(obj));//[1, 2]
    console.log("------删除 --");
    delete obj.name;
    console.log(obj.name);//abc
    
    </script>
    </head>
    <body>
    
    </body>
    </html>
    

    res:
    image

    exp2:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
    //函数必须有三个参
    //Object.defineProperty(对象, 属性, 描述对象options)
    //作用 : 用来定义和修改以及监听对象的属性变化的
    
    let obj = {a:1,b:2};
    
    Object.defineProperty(obj,"name",{
        value:"abc",
        writable:true,
        enumerable:true,
        configurable:true,
    });
    
    //修改
    obj.name = "ccc";
    //获取
    console.log(obj);//{a: 1, b: 2, name: "ccc"}
    console.log(obj.name);//ccc
    
    console.log("------循环 for in --");
    for(let name in obj){
        console.log(name + ":" + obj[name]);
    }//a:1
    //b:2
    //name:ccc
    console.log("------循环 Object.keys--");
    console.log(Object.keys(obj));//["a", "b", "name"]
    console.log(Object.values(obj));//[1, 2, "ccc"]
    console.log("------删除 --");
    delete obj.name;
    console.log(obj.name);//undefined
    console.log(obj);//{a: 1, b: 2}
    
    </script>
    </head>
    <body>
    </body>
    </html>
    

    exp3:

    <script>
    //函数必须有三个参  
    //Object.defineProperty(对象, 属性, 描述对象options)
    //作用 : 用来定义和修改以及监听对象的属性变化的
    
    let obj = {a:1,b:2};
    
    //get/set  ---> value/writable
    Object.defineProperty(obj,"name",{
        //value:"abc",
        get(){
            console.log("有人来访问了");
            return "abc";
        },
        set(value){
            console.log("有人来修改了"+value);
        },
        //writable:true,
        enumerable:true,
        configurable:true,
    });
    
    //获取
    console.log(1,obj.name, "name" in obj);
    //有人来访问了 //1 "abc" true
    console.log(2,obj);
    //修改 设置
    obj.name = 1;//有人来修改了1
    
    console.log("------循环 for in --");
    for(let name in obj){
        console.log(name + ":" + obj[name]);
    }//a:1
     //b:2
     //有人来访问了
     //name:abc
    
    console.log("------循环 Object.keys--");
    console.log(Object.keys(obj));
    //["a", "b", "name"] //有人来访问了
    console.log(Object.values(obj));//[1, 2, "abc"]
    console.log("------删除 --");
    delete obj.name;
    console.log(obj.name,"name" in obj);//undefined false
    console.log(obj);
    </script>
    

    res:
    image

    exp4:

    <script>
    //函数必须有三个参  
    //Object.defineProperty(对象, 属性, 描述对象options)
    //作用 : 用来定义和修改以及监听对象的属性变化的
    
    let obj = {a:1,b:2};
    
    //get/set  ---> value/writable
    let initValue = "数据初始化";
    Object.defineProperty(obj,"name",{
        //value:"abc",
        get(){
            console.log("get");
            return initValue;
        },
        set(value){
            initValue = value;
            console.log("set");
        },
        //writable:true,
        enumerable:true,
        configurable:true,
    });
    
    //获取
    console.log("修改前");
    console.log(1,obj.name, "name" in obj);//get //1 数据初始化 true
    console.log(2,obj); //{a:1,b:2}
    //修改 设置
    obj.name = 1;//set
    console.log("修改后");
    console.log(1,obj.name, "name" in obj);//1 true
    console.log(2,obj);//{a:1,b:2,name:1}
    </script>
    

    res:
    image

    exp5:
    模仿vue

    <script>
    //函数必须有三个参  
    //Object.defineProperty(对象, 属性, 描述对象options)
    //作用 : 用来定义和修改以及监听对象的属性变化的
    
    let data = {a:1,b:2};
    
    //Vue:defineReactive
    
    function observer(data){
        //[a,b]
        Object.keys(data).forEach(function(key){
            let initValue = "";
            Object.defineProperty(data,key,{
                get(){ 
                    return initValue;
                },
                set(value){ 
                    initValue = value;
                    document.body.innerHTML  = value;
                },
                enumerable:true,
                configurable:true,
            });
        })
    }
    
    observer(data);
    document.onclick = function(){
        //document.body.innerHTML = 12;
    
        data.a = 12;
        console.log(data)
    }
    </script>
    

    vue:原理2 => vue3 代理 proxy

    一切操作都走代理对象!

    let proxy = new Proxy(需要代理的对obj,代理处理的功能{
    			get(target,key,proxy){}
    			set(target,key,value,proxy){}
    			has(target,key){}
    			deleteProperty(target,key){}
    });
    

    exp1:

    <script>
    //proxy - 监听 Object.observe()
    
    let data = {
        a:1,
        b:2
    }
    let proxy = new Proxy(data,{
        get(){
            console.log("有人来get");
        },
        set(){
            console.log("有人来set");
        }
    });
    
    proxy.a;//有人来get
    proxy.a = 12;//有人来set
    </script>
    

    exp2:

    <script>
    //proxy - 监听 Object.observe()
    let data = {
        a:1,
        b:2
    }
    
    let proxy = new Proxy(data,{
        get(target,key,proxy){
            //console.log("get",target == data,key,proxy);
    
            ///console.log("get this",this);
            return target[key]; 
        },
        set(target,key,value,proxy){
            console.log("set",target,key,value,proxy);
    
            target[key] = value;
        }
    });
    //设置
    proxy.a = 12;
    //获取
    console.log("获取:",proxy.a);
    </script><script>
    //proxy - 监听 Object.observe()
    
    let data = {
        a:1,
        b:2
    }
    
    let proxy = new Proxy(data,{
        get(target,key,proxy){
            //console.log("get",target == data,key,proxy);
    
            ///console.log("get this",this);
            return target[key]; 
        },
        set(target,key,value,proxy){
            console.log("set",target,key,value,proxy);
    
            target[key] = value;
        }
    });
    
    
    //设置
    proxy.a = 12;//set {a: 1, b: 2}, a ,12 , proxy{a: 1, b: 2}
    
    //获取
    console.log("获取:",proxy.a);//获取:12
    </script>
    

    exp3:

    <script>
    //proxy - 监听 Object.observe()
    
    let data = {
        a:1,
        b:2
    }
    
    let proxy = new Proxy(data,{
        get(target,key,proxy){
            //console.log("get",target == data,key,proxy);
    
            ///console.log("get this",this);
            return target[key]; 
        },
        set(target,key,value,proxy){
            console.log("set",target,key,value,proxy);
    
            target[key] = value;
        }
    });
    
    
    //设置
    proxy.a = 12;//set {a: 1, b: 2}, a ,12 , proxy{a: 1, b: 2}
    
    //获取
    console.log("获取:",proxy.a);//获取:12
    </script>
    
    模拟报错:
    <script>
    //proxy - 监听 Object.observe()
    
    let data = {
        a:1,
        b:2
    }
    let proxy = new Proxy(data,{
        get(target,key,proxy){
            return target[key]; 
        },
        set(target,key,value,proxy){
            target[key] = value;
            //document.body.innerHTML = value;
        },
        has(target, key){
            console.log("has");
            //return key in target;
    
            if(key in target){
                return true;
            } else {
                throw new Error(`1111[Vue warn]: Property or method "${key}" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
    
            (found in <Root>)`)
            }
    
        },
        deleteProperty(target, key){
            console.log("del");
            if(key in target){
                return delete target[key];
            } else {
                return false;
            }
        }
    });
    
    console.log(1111,"c" in proxy);
    
    //console.log(delete proxy.c);
    
    
    
    document.onclick = function(){
        //document.body.innerHTML = 12;
    
        proxy.a = 12;
    }
    
    </script>
    </head>
    <body>
        <div id="app">
            {{a}}--{{b}}-{{c}}
        </div>
    </body>
    <script>
    let vm = new Vue({
        el:"#app",
        data,
    });
    </script>
    

    res:
    image

    vue-cli:2.x

    https://www.npmjs.com/package/vue-cli

    vue-cli:3.x

    https://cli.vuejs.org/       英文
    https://cli.vuejs.org/zh/     中文
    https://github.com/vuejs/vue-cli

    注意:vue-cli2升级到vue-cli3必须先删除原来的模块

    cnpm i -g vue-cli
    cnpm i -g @vue/cli 必须先删除vue-cli

    https://www.jb51.net/article/137710.htm

    创建项目命令

    2.x vue init
    3.x vue create

    exp:
    vue create myvue3

    选择安装的模块、插件

    1、空格 选择
    2、a 全选
    3、i 反选

    这里是把babel,postcss,eslint这些配置文件放哪
    独立文件放置 √
    放package.json里

    启动项目命令

    2.x npm start
    3.x npm run serve

    配置代理服务器/端口

    需要创建 vue.config.js 文件盒工程文件(package.json)是平级

    devServer: {
    	port:9000,
    	// proxyTable: {  
    	proxy: { 
    	    "/anhao": {
    	      target: "http://localhost:3000",
    	      changeOrigin: true,
    	      pathRewrite: {  //需要rewrite重写的, 如果在服务器端做了处理则可以不要这段
    	        "^/anhao": ""
    	      }
    	    },
    	  },
    	}
    }
    

    vue add router     cnpm i -S router
    vue add vuex      vue i -S vuex

    插件: https://github.com/RuMengkai/awesome-vue

    element
    mint-ui

    插件的写法:

    1、对象形式
    export default {
    	install(Vue,options){
    			Vue.prototype.$xxx = {
    				 methods(){
    				 		options
    				 }
    			};
    	}
    }
    
    2、函数形式
    export default (Vue,options)=>{
    		Vue.prototype.$xxx = {
    			 methods(){
    			 		options
    			 }
    		};
    }
    
    使用:

    Vue.use(插件模块);

    vue-cli:用的vue.js

    myvue ode_modulesvuedistpackage.json

    "main": "dist/vue.runtime.common.js",

    不要采用runtime形式的文件

    最好采用 dist/vue.esm.js

    添加 配置文件:vue.config.js 在项目的根目录下

    configureWebpack: config => {
        config.resolve = {
           extensions: ['.js', '.vue', '.json',".css"],
            alias: {
              'vue$': 'vue/dist/vue.esm.js',
              '@': resolve('src'),
            }
        }
    },
    

    image

  • 相关阅读:
    Sage CRM升级后的问题跟进
    js 控制滚动条位置
    初学Jquery插件制作:在SageCRM的查询屏幕隐藏部分行的功能
    [转摘] Reporting Service 200
    js数组去重复项
    JavaScript tips 1024 * 768
    javascript 的 replace 函数
    the secret of sagecrm urls
    Sage CRM 自增ID的方案和遇到的问题
    EXTJS 可编辑列表的时间编辑问题
  • 原文地址:https://www.cnblogs.com/zhongchao666/p/9463034.html
Copyright © 2020-2023  润新知