总结

54 阅读4分钟

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生命周期

image.png

created(): 可以通过vn访问到data/methods方法。
beforeCreated和created之间可以完成数据劫持,数据代理。
created之后beforeMount之前 render()函数开始解析模板成虚拟DOM
mounted()完成挂载

16、render函数的作用

render函数用于生成虚拟DOMVNode)树的函数。它是Vue.js的渲染函数,负责将组件的模板转换为可渲染的VNode树。