Vue2.0与3.0区别
cnpm install -g @vue/cli
vue create vue-learning03
cd vue-learning03
vue add vue-learning03
Vue2.0是option API写法 低耦合低内聚,太分散
Vue3.0是composition API,基于函数
import { ref } from "vue"
const useCompute = (count) => {
const plus = () => {
count.value ++;
}
const minus = () => {
count.value --;
}
return {plus, minus}
}
setup () {
const count = ref(0);
const {plus, minus} = useCompute(count);
return {
count,
plus,
minus
}
}
所有视图中需要的数据和方法 都需要在setup里面return出来
- 响应式原理
defineProperty机制是通过拦截对象的属性和操作
数组的push或者是通过下标设置值等操作是无法触发defineProperties里set方法的
所以Vue里面push等是通过底层匹配字符串 重新写的方法,所以代码就会更多,反之proxy就不需要做这些处理
因为proxy是es6 考虑兼容性所以Vue2.0没有使用
function defineProperty () {
var _obj = {};
var cache = 0;
// Object.defineProperty(_obj, a, { value: 1 })
Object.defineProperties(_obj, {
a: {
// value: 1,
// writable: true, // 写 默认false obj.a=xx
// enumerable: true, // 枚举 默认false forin + console
// // conf 一般指的文件夹 config 一般指的是文件
// configurable: true, // 删除 默认false delete obj.a
get () {
return cache
},
set (newVal) {
// newVal就是外层给这个属性赋的值
cache = newVal;
}
},
b: { value: 2 }
})
}
-
处理对象
-
创建出来的对象如果不修改三个属性就 不可修改、不可枚举、不可删除
-
每一个属性定义的时候都会产生getter和setter的机制
-
数据劫持 通过对对象属性的三个属性设置来控制这个属性的修改枚举删除是否可行,通过get set控制属性的存取逻辑扩展,中间可以用闭包
-
但是如果属性描述符里有writable或者value 就不可以有get和set,互斥冲突
-
响应式编程 就是一个方法的执行会通知别的方法执行类似 观察者模式|订阅模式
- ES6 proxy代理
代理机制是重写proxy的方法
var target = {a: 1, b: 2};
var proxy = new Proxy(target, {
get (target, prop) {
// get必须return
// return target[prop];
return Reflect.get(target, prop);
},
set (target, prop, value) {
// set的时候把代理的源对象也修改
target[prop] = value;
},
has (target, prop) {
return target[prop];
},
deleteProperty (target, prop) {
delete target[prop];
}
})
console.log("a" in proxy);
delete proxy.a;
- 可以代理对象数组函数
// ECMAScript 内键的对象操作 14种方法
// object 广义的对象,Object 狭义的对象
// 因为有的并不是对象,可能是方法可能是数组,所以ES6推出一个内置对象Reflect 反射,方法集容器,除了枚举的十三种方法都在里面
// 而且Reflect可以接收返回值
var obj = {a: 1, b: 2}
1、获取原型 [[GetPrototypeOf]]
var proto = Object.getPrototypeOf(obj);
// obj.__proto__
// Object.protytype
JS 弱点 很多命令是关键字(in 、instansof) 不是方法式
2、设置原型 [[SetPrototypeOf]]
Object.setPrototypeOf(obj, {c: 3});
// obj.__proto__ = xx
// Object.prototype = xx
3、获取对象的可扩展性 [[IsExtensible]]
var extensible = Object.isExtensible(obj);
// 可枚举修改扩展删除 bool
freeze冻结 不可增加 不可删除 不可写 可读
seal封闭 不可增加 不可删除 可写 可读
4、获取自有属性 [[GetOwnProperty]]
Object.setPrototypeOf(obj, {c: 3});
Object.getOwnPropertyNames(obj); // 返回 ["a", "b"]
5、禁止扩展对象 [[PreventExtensions]]
Object.preventExtensions(obj);
6、拦截对象操作 [[DefineOwnProperty]]
Object.defineProperty
7、判断是否是自身属性 [[HasProperty]]
obj.hasOwnProperty("a"); // bool
8、判断属性是否在对象中 [[GET]]
"a" in obj
obj.a
// bool
9、设置对象属性 [[SET]]
obj.a = 4;
obj["b"] = 5;
10、删除对象属性 [[Delete]]
delete obj.a
11、枚举 [[Enumerate]]
for (var k in obj) {
console.log(k, obj[k]);
}
// for in 获取的k 是自有属性+原型上的属性
12、获取自有键集合 [[OwnPropertyKeys]]
Object.keys(obj)
13、调用函数
function test () {};
test();
test.call / apply
14、new
function test () {};
var newTest = new test();
// 自己封一个proxy
function MyProxy (target, handel) {
let _target = deepClone(target);
Object.keys(_target).forEach((key) => {
Object.defineProperty(_target, key, {
// 这里写target是为了直接修改外面的target变量
get () {
return handel.get && handel.get(target, key);
},
set (newVal) {
handel.set && handel.set(target, key, newVal);
}
})
})
return _target;
// 深拷贝 这里只考虑了数组
function deepClone (org, tar) {
var tar = tar || {},
toStr = Object.prototype.toString,
arrType = "[object Array]";
for (var key in org) {
if (org.hasOwnProperty(key)) {
if (typeof(org[key]) === "object" && org[key] !== null) {
tar[key] = toStr.call(org[key]) === arrType ? [] : {};
deepClone(org[key], tar[key]);
} else {
tar[key] = org[key]
}
}
}
return tar;
}
}
let target = {
a: 1,
b: 2
}
let proxy = new MyProxy(target, {
get (target, prop) {
return "GET " + prop + " = " + target[prop];
},
set (target, prop, value) {
target[prop] = value;
console.log("SET " + prop + " = " + value);
}
})
console.log(proxy.a);
proxy.b = 3;