实现网站的主要页面实现
使用vue实现小米商城的首页 分类页 商品详情页 个人中心页
这个网站基本框架是如何实现的求解答
还有用了什么具体方法
vue,vue-router,vuex
因为对象最多也就几十个属性,拦截起来数量不多,但是数组可能会有几百几千项,拦截起来非常耗性能,所以直接重写数组原型上的方法,是比较节省性能的方案
数组考虑性能原因没有用 defineProperty 对数组的每一项进行拦截,
而是选择对 7 种数组(push,shift,pop,splice,unshift,sort,reverse)方法进行重写
举例:
//!!!对数组方法进行重写:
//原来的 oldArrayProto用来执行数组上的方法(比如 push,pop,shift)
//新的 newArrProto 用来体现视图的更新
const oldArrayProto = Array.prototype;
const newArrProto = Object.create(oldArrayProto);
['push','pop','shift','unshift','splice','reverse','sort'].forEach(methodName => {
newArrProto[methodName] = function() {
console.log('更新视图 --> 数组');
oldArrayProto[methodName].call(this,...arguments);
}
})
并且在 observer() 函数中,监测是否为数组
//判断是否是数组!!!
if(Array.isArray(target)) {
target.__proto__ = newArrProto;
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Vue响应式</h1>
<script>
const data = {
name:'zs',
age:18,
friend:{
friendName:'ls'
},
colors:['red','orange','green']
}
//!!!对数组方法进行重写:
//原来的 oldArrayProto用来执行数组上的方法(比如 push,pop,shift)
//新的 newArrProto 用来体现视图的更新
const oldArrayProto = Array.prototype;
const newArrProto = Object.create(oldArrayProto);
['push','pop','shift','unshift','splice','reverse','sort'].forEach(methodName => {
newArrProto[methodName] = function() {
console.log('更新视图 --> 数组');
oldArrayProto[methodName].call(this,...arguments);
}
})
//变成响应式数据
observer(data);
function observer(target) {
if(typeof target !== 'object' || target === null) {
return target;
}
//判断是否是数组!!!
if(Array.isArray(target)) {
target.__proto__ = newArrProto;
}
for(let key in target) {
defineReactive(target, key, target[key]);
}
}
function defineReactive(target, key, value) {
//深度观察
observer(value);
Object.defineProperty(target, key, {
get(){
return value;
},
set(newValue){
observer(newValue);
if(newValue !== value) {
value = newValue;
console.log('更新视图 --> 对象');
}
}
})
}
data.age = { number: 20 };//监测对象
data.colors.push('blue');//监测数组
console.log(data.colors);
</script>
</body>
</html>