19. vue的原理

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:

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:

语法:

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:

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:

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:

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 >

{{a}}--{{b}}-{{c}}

</div>

</body>

<script>

let vm = new Vue({

el:"#app",

data,

});

</script>

res:

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\node_modules\vue\dist\package.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'),

}

}

},

以上是 19. vue的原理 的全部内容, 来源链接: utcz.com/z/378014.html

回到顶部