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 id="app">
{{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的原理的更多相关文章

  1. vue路由原理剖析

    单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面, 实现这一点主要是两种方式: 1.Hash: 通过改变hash值 2.History: 利用history对象新特性(详情可出门左拐见:  ...

  2. vue 编译原理 简介

    来源 tinycompile 关于vue的内部原理其实有很多个重要的部分,变化侦测,模板编译,virtualDOM,整体运行流程等. 之前写过一篇<深入浅出 - vue变化侦测原理> 讲了 ...

  3. vue运行原理

    Vue工作原理小结 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简 ...

  4. framework7的改进,以及与vue组合使用遇到的问题以及解决方法 (附vue的原理)

    framework7官方提供了vue+framework7的组合包,但是那个包用起来复杂度较高,而且不灵活.听说bug也不少. 所以我想用最原始的方式单独使用vue和framework7. 遇到以下问 ...

  5. vue 动画原理 part1

    Vue动画原理 增加和删除css增加样式实现一个过渡效果也就是动画效果 1.需要动画效果的标签外包裹一个transition标签 会被自动分析css样式,然后自动构建一个动画流程 transition ...

  6. vue 实现原理及简单示例实现

    目录 相关html代码,用于被解析绑定数据 observer代码 Dep代码 Watcher 代码 Compile 代码 vue 简要构造函数 创建vue实例 结语 主要理解.实现如下方法: Obse ...

  7. vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)

    第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件) #课程目标 掌握vue实例的相关属性和方法的含义和使用 了解vue的数据响应原理 熟悉创建组件,了解全局 ...

  8. vue 快速入门 系列 —— 侦测数据的变化 - [vue api 原理]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue api 原理] 前面(侦测数据的变化 - [基本实现])我们已经介绍了新增属性无法被侦测到,以及通过 delete 删除数据也不会 ...

  9. vue SSR : 原理(一)

    前言: 由于vue 单页面对seo搜索引擎不支持,vue官网给了一个解决方案是ssr服务端渲染来解决seo这个问题,最近看了很多关于ssr的文章, 决定总结下: 参考博客:从0开始,搭建Vue2.0的 ...

随机推荐

  1. Python - 列联表的独立性检验(卡方检验)

    Python - 列联表的独立性检验(卡方检验) 想对两个或两个以上因子彼此之间是否相互独立做检验时,就要用到卡方检验,原以为在Python中实现会像R的chisq.test一样简便,但scipy的s ...

  2. C# SemaphoreSlim 实现

    当多个任务或线程并行运行时,难以避免的对某些有限的资源进行并发的访问.可以考虑使用信号量来进行这方面的控制(System.Threading.Semaphore)是表示一个Windows内核的信号量对 ...

  3. Linux中非正常关闭vi编辑器产生swp文件怎么删除

    Linux中非正常关闭vi编辑器产生swp文件,会导致编辑文件时提示如下内容(图我是从网上找的): 这是因为异常关闭vi编辑器产生swp文件导致,假设编辑的文件名是file.sh,那么生成的swp文件 ...

  4. Webhook 实践 —— 自动部署

    https://segmentfault.com/a/1190000007892407 安装nodejs 安装nodejs建议直接下载二进制包,把官网上的64位二进制版本下载地址复制下来,执行 wge ...

  5. 对Faster R-CNN的理解(2)

    2. 区域建议网络 区域建议网络(Regional Proposal Network, RPN),根据特征图上每一个点的向量,为这个点生成k个矩形建议框.每一个点输出的内容包括:reg层4个输出x.y ...

  6. Python 进制转换 二进制 八进制 十进制 十六进制

    Python 进制转换 二进制 八进制 十进制 十六进制 作者:方倍工作室 地址:http://www.cnblogs.com/txw1958/p/python3-scale.html 全局定义一定不 ...

  7. 生产系统ELK日志采集系统

    总结下,生产在运转的日志采集系统!后续的扩展在于elasticsearch节点与logstash节点与kafka+zookeeper,目的提高吞吐量!

  8. Mongodb系列- java客户端简单使用(CRUD)

    Mongodb提供了很多的客户端: shell,python, java, node.js...等等. 以 java 为例实现简单的增删改查 pom文件: <dependencies> & ...

  9. CentOS 6.5 x64下安装宝塔面板、阿里安骑士

    一.安装宝塔: CentOS下命令(https://www.bt.cn/bbs/thread-1186-1-1.html) yum install -y wget && wget -O ...

  10. python 执行sql得到字典格式数据

    本文在提供一种方式,实现执行sql语句 返回字典结果集 # 连接数据库,数据库的,这里使用的setting中的默认设置,在这里不做具体的介绍,不懂的可以百度一下 conn = MySQLdb.conn ...