1、vue2 v-for>v-if(仅仅指同一个标签上) 应该将这两个分开: 外层套v-if,内层是v-for
(正确)
<!-- 判断假的,压根不会遍历 -->
<div v-if="state">
<p v-for="item in todos">{{item.title}}</p>
</div>
(同一个标签先v-for走三次生成3个p 然后挨个判断都隐藏删掉 脱裤子放屁的感觉)
<p v-for="item in todos" v-if="state">{{item.title}}</p>
2、为啥data要写函数里面返回对象
一个组件被复用多次,也就会创建多个实例,本质上都是基于同一个构造函数,如果data直接是对象,因为对象是引用类型,所以会影响到所有实例。
因此:为了保证组件不同的实例之间data不冲突,data必须是一个函数,保护变量的私有属性
3、### 如何实现组件通信?
常用:状态管理工具 vuex
常用:父传子 props、子传父$emit、兄弟 eventBus
常用:slot插槽
概率:通过组件实例 ref获取、 =》 parent获取、root获取、$children获取
概率:v-model
4、### 谈谈你对回流重绘的理解
回流/重排(DOM改变):页面布局流发生改变就叫做回流,例如:width、height、border、top等
重绘(CSS改变):重绘元素自身的样式发生改变但是不会影响布局流,例如:color、background、box-shadow等
5、父子组件生命周期顺序
问1:created、和mounted区别
答1:created不可以dom操作
问2:真的不可以吗
答2:可以通过 this.$nextTick()
问3:父子组件嵌套、生命周期执行顺序 created、mounted
答2:大方向 父created、子created、子mounted、父mounted
6、watch与created哪个先执行?
watch 中的 immediate 会让监听在初始值声明的时候去执行监听计算,否则就是 created 先执行
7、### 说一下v-model原理
v-model其实是个语法糖底层是基于【:value】和【@input】 封装
<input type="text" :value="msg" @input="msg = $event.target.value">
8、为啥VUE3要选择proxy和reflect
- Object.defineProperty 拦截的是对象的属性,会改变原对象。 proxy 是拦截整个对象,通过 new 生成一个新对象,不会改变原对象。
- proxy 语法更强,拦截方式除了上面的 get 和 set ,还有 11 种,以前就6个
- proxy 特性更强,可以监听未定义的,针对于N层则get时判断递归添加proxy拦截即可
9、路由鉴权,路由守卫
// permission.js
router.beforeEach((to, from, next) => {
if (store.getters.token) { // 判断是否有token
if (to.path === '/login') {
next({ path: '/' });
} else {
// 判断当前用户是否已拉取完user_info信息
if (store.getters.roles.length === 0) {
store.dispatch('GetInfo').then(res => { // 拉取info
const roles = res.data.role;
// 把获取到的role传进去进行匹配,生成可以访问的路由
store.dispatch('GenerateRoutes', { roles }).then(() => {
// 动态添加可访问路由表(核心代码,没有它啥也干不了)
router.addRoutes(store.getters.addRouters)
// hack方法 确保addRoutes已完成
next({ ...to, replace: true })
})
}).catch(err => {
console.log(err);
});
} else {
next() //当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入404页面
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next();
} else {
next('/login'); // 否则全部重定向到登录页
}
}
})
10、### 路由-导航守卫种类&作用
全局:beforeEach 登录状态、网页加载进度条
全局:beforeResolve 不用(路由、组件守卫被解析也就是被调用后)
全局:afterEach 关闭网页加载进度条 NProgress
路由:beforeEnter 不用
组件:beforeRouteEnter 组件被创建前(注:不能用this,vm)
组件:beforeRouteUpdate 动态路由匹配/动态获取路由参数
组件:beforeRouteLeave 未保存离开组件/清除定时器/切换组件保存数据等
11、HTTP状态码
2xx 200成功 201成功并创建新资源
3xx 301永久重定向 302临时重定向 304浏览器缓存
4xx 400参数有误 401密码错误 403无权访问 404文件不存在 405请求方式有误
5xx 500服务器错误
12、vue3的ref('')打印
这个对象里有一个 value 属性,当你看到 value 属性是 `(...)` 时,你应该立刻明白它是通过`Object.defineProperty` 定义的,通过定义之后就会产生 get 和 set 两个函数。
// ref 方法需要一个值,我们写作 value
function ref(value) {
// 它返回一个对象
{
// 对象中有一个 value 属性
// 是通过 Object.defineProperty 定义的
// 定义里会有一个 get 和 set 方法
get(){
// get 方法返回 value
return value
},
set(val){
// set 方法给 value重新赋值
value = val
}
}
}
// 大概就是这个样子
// 但是不要忘记了 vue 是带有响应式的
// 而响应式的原理是什么呢?
// 就是在 get 的时候进行依赖收集,就是说谁用到了我这个数据
// 而 set 的时候叫做派发更新,表示通知使用数据的地方数据更新了
// 那么就应该是如下的样子
function ref(value) {
{
get(){
// 依赖收集,我们称为 track()
return value
},
set(val){
// 派发更新 trigger()
value = val
}
}
}
13、watch、computed、created三者的执行顺序
一、默认加载情况
created>computed>watch
二、watch增加了immediate:true 这样优先级会提到最前面
watch > created > computed
14、组件渲染流程:
创建vnode、渲染vnode、生成vnode
渲染vnode过程主要是挂载组件:(创建组件实例、设置组件实例、设置并运行带副作用的渲染函数)
15、vue2生命周期
created(): 可以通过vn访问到data/methods方法。
beforeCreated和created之间可以完成数据劫持,数据代理。
created之后beforeMount之前 render()函数开始解析模板成虚拟DOM
mounted()完成挂载
16、render函数的作用
render函数用于生成虚拟DOM(VNode)树的函数。它是Vue.js的渲染函数,负责将组件的模板转换为可渲染的VNode树。