一. vue watch 的监听
1.初始化监听对象设置 immediate: true,
2.深度监听, 设置属性为 deep: true,
3. 深度监听对象里面的一个属性,节约性能
4. “user.name”: { handle: function() {}, deep: true }
二.vue数组的变化
1.vue2.0 通过 this.list[5] = 7; 去改变 是不会导致 视图更新的, 因为 vue2.0 的底层实现原理是 通过definedProtyte 去实现的,
2.vue3.0 可以 通过this.list[5] = 7; 改变数组下标去更新试图, vue3.0 是响应式的, 底层实现逻辑是Proxy
三.路由的处理
1.vue 路由 匹配 notFound的页面是 {path: ‘/:path(.*)’, component: NotFound} 这个是匹配 所有路径, 不过要放到路由的最下面, 表示没有找到的页面, Vue Router的更多用法, 全局守护路由, 导航路由, 单页面路由,请移步Vue Router官网, 请移步
四.跨组件使用 具体用法
vue 也有跨组件 爷孙
组件的使用方法 provide(传递值) 跟 inject(接受值),React 跨组件是通过useContext来跨的,原理也差不多
五.vue的跨域解决
vue3.0 也提供了 跨域解决 问题, 直接写一个
devServer: {
proxy: {
'/path': {
target: "目标地址",
changeOrigin: true,
pathRewrite: {
'^/path': ''
}
}
}
}
六. vue3.0 setup的使用 具体用法
1.vue3.0 的setup 函数,是beforeCreate() 跟 created() 两个函数的结合体,
跟react的useEffect 有异曲同工之妙,只不过setup监听数据变化需要内部通过watch 跟 watchEffect函数去监听.
2.ref() 这个是 对基本类型 的赋值.
3.reactive 是对引用变量的赋值,这个就是 响应式的做法, 然后通过 ES6的 … 去解析用法, 相当于 拷贝了一份, 就是去了响应式了, 然后通过 toRefs的函数, 去使用, 就又可以恢复响应式数据了.
4.单文件作用域,在script 这里写了setup, 都不需要在 setup函数中来return导出需要的函数或者变量了, template 模板中都可以直接获取到上面的值, 可以简化很多的代码量
<script setup>
七.辅助函数 mapState用法, 其他辅助函数同理
1.computed: mapState({
count: state => state.count
});
// 也可以 使用 字符串
2.computed: mapState({
count: “count”
});
// 如果是 多个参数 返回的话, 可以使用 数组来解析
3.computed: mapState([“count”, “msg”]);
// 如果 computed 想使用自己的私有数据, 把mapState 解析一下就可以了
4.computed: {
add: function() {
return this.msg.split(‘’).reverse().join();
},
// 直接扩展运算符, 解析出来就可以了
…mapState([“count”, “msg”])
}
// 如果有命名空间了 nameSpace: true, name: ‘file’, 那么写法就会变化了
5.computed: {
add: function() {
return this.msg.split(‘’).reverse().join();
},
// 就需要在 mapState 前面加上 file这个名字
…mapState(‘file’, [“count”, “msg”])
}
八.v-for 和 v-if不能一起使用
不要将v-for 和v-if 一起使用, 因为v-if的优先级比较高, 会造成性能的浪费, 解决方法是对数据先在computed 里面做一下 过滤, 然后把过滤值 丢到v-for里面在循环一次, 为什么要放到 computed里面的呢? 因为computed 有缓存的作用, 页面刷新的时候 不会重复的执行
九.vue指令 全局跟局部的写法
//然后在要使用的元素上 加上 v-focus 就可以生效了
1.全局的使用方法
Vue.directive('focus', {
// inserted 提供的函数
inserted: function (el, binding) {
// el 是拿到 当前指定的dom节点数据
// binding 时拿到 属性值 等等
el.focus();
}
});
2.局部的使用方法
export default {
data() { },
// 自定义
directives: {
focus: {
inserted: function (el, binding) {
// el 是拿到 当前指定的dom节点数据
// binding 时拿到 属性值 等等
el.focus();
}
}
}
}
十.vue $nextTick的用法
vue中 $ nextTick 的用法, 为什么要使用这个函数呢?
使用场景:
1.在created 中进行dom操作, 因为dom还没有生成, 所有就要把操作 放到$ nextTick 中
2.在数据变化后, 执行dom操作, 而这个数据需要跟随着dom结构进行变化时,
就需要使用$ nextTick 操作
this.$nextTick(()=>{
this.msg = "sdfsdfsfd";
});
2.我们也可以使用 setTimeout 等待 1秒钟再来或者dom更新的数据,但是有坏处, 我们根本不知道具体项目中 需要等待多久,dom才能够完全刷新出来,
所以用$nextTick函数处理 才是最好的,vue的 $nextTick 跟react useEffectLayout 有异曲同工之妙,都是差不多的意思
说到这里,为什么 nextTick 可以在dom之后拿到数据呢?
Vue 处于性能的考虑,每次数据的变化,DOM并不会立即的更新,总结如下:
- Vue在修改Data时候, Vue会将所有data相关的Watcher 加入到任务放到队列中
- 然后传入调用 nextTick 回调,会传入DOM的更新会调中
执行nextTick时, 碰到异步代码的时候,会将更新DOM的异步任务放到队列中
这个也是为什么 Vue 没法在DOM更新的时候 同步去获取到数据更新的变化,因为他都是放到一个队列中,然后将异步更新DOM的数据在重新放到一个队列中,等待这个同步代码完成后再去执行异步的DOM更新
十一. 简单的实现一下 Vue2.0 的数据劫持
index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
视图分析1: <span class="box1"></span> <br />
视图分析2: <span class="box2"></span>
</body>
<script src="./index.js"></script>
<script>
let demoObj = {};
dataHijack({
data: demoObj,
tag: "view-1",
dataKey: "one",
selector: ".box1"
});
dataHijack({
data: demoObj,
tag: "view-2",
dataKey: "two",
selector: ".box2"
});
demoObj.one = "视图一";
demoObj.two = "试图二";
</script>
</html>
index.js 文件
let Dep = {
clientList: {},
listin: function(key, fn) {
(this.clientList[key] || (this.clientList[key] = [])).push(fn);
},
trigger: function() {
// 这里去找到key
// 这个 shift 会影响到原数组的值,会将原数组的第一个值 给返回回来
let key = Array.prototype.shift.call(arguments);
console.log(key);
console.log(this.clientList);
let fns = this.clientList[key];
if(!fns || fns.length == 0) {
return false;
}
for(let i=0, fn; fn=fns[i++];) {
// 上面通过了 shift已经移除了 第一个tag的值, 所以说这里就只有 val的值了, 下面的listin的funciton中就可以拿到val的值了
fn.apply(this, arguments);
}
}
};
// 劫持方法
const dataHijack = function({ data, tag, dataKey, selector }) {
let value,
el = document.querySelector(selector);
Object.defineProperty(data, dataKey, {
get: function() {
return value;
},
set: function(val) {
value = val;
console.log(val)
// 这个是发布
Dep.trigger(tag, val);
}
});
// 添加订阅者
Dep.listin(tag, function(val) {
el.innerHTML = val;
});
}
十二: 样式穿透