前端面试题总结(二)

128 阅读5分钟

1. vue路由怎么传参的

  1. params传参
    • this.$router.push({name:'index', params: {id:item.id}})
    • this.$route.params.id
  2. 路由属性传参
    • this.$router.push({name: '/index/${item.id}'}),路由配置:{path:'/index:id'}
  3. query传参
     this.$router.push{{
       name: 'index',
       query: {id:item.id}
     }}
    

2. vue路由的hash模式和history模式有什么区别

  1. hash模式的路由地址上有#,history模式没有
  2. 在做回车刷新的时候,hash模式会加载对应页面,history会报错404
  3. hash模式支持低版本浏览器,而history不支持,因为是H5新值的API
  4. hash模式不会重新加载页面,单页面应用必备
  5. history有历史记录,H5新增了pushState和replaceState()去修改历史记录,并不会立刻去发送请求
  6. history需要后台配置

3. 路由拦截是怎么实现的

  1. 路由拦截 axios拦截
  2. 需要在路由配置中添加一个字段,它是用于判断路由是否需要拦截的。
     {
       name: 'index',
       path: '/index',
       component: Index,
       meta: {
         requireAuth: true
       }
     }
     router.beforeEach((to, from,next)=>{
       if(to.metarequireAuth===true) {
         if (store.state.token) {
           next();
         } else {
         }
       }
     })
    

4. vue的动态路由的动态路由

  • 要在路由配置里设置meta属性,扩展权限相关的字段,在路由导航守卫里通过判断这个权限标识实现路由的动态增加和跳转。
  • 根据用户登录的账号,返回用户角色。 前端再根据角色,跟路由的meta.role进行匹配,把匹配的路由形成可访问的路由。

5.如何解决刷新后二次加载路由?

  1. window.location.reload(),当这个方法被调用时,浏览器会完全重新加载当前页面,可能会导致所有客户端JavaScript变量和DOM都被重置。
  2. matcher matcher通常是在vue router中用于追踪和匹配路由的内部属性
     const router = createRouter()
     export function resetRouter(){
       const newRouter = createRouter()
       router.matcher = newRouter.matcher
     }
    

6. vuex刷新数据会丢失吗?怎么解决?

  1. vuex会重新获取数据,页面也会丢失数据,丢失数据原因:
    • vuex存储的数据知识在页面中,相当于全局变量,页面刷新时vuex里的数据会重新初始化,导致数据丢失。
    • vuex里的数据是保存在运行内存里的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据会被重新赋值。
  2. 解决思路:把数据直接保存在浏览器缓存里(sessionStorage、localStorage、cookie),页面刷新后再从浏览器中取出,达到可以动态更新的方法。 监听浏览器的刷新事件,在刷新前把数据保存到sessionStorage,刷新后请求数据,请求到了用vuex,如果没有 那就用sessionStorage里面的数据。

7. computed和watch的区别

  1. computed是计算属性,watch是监听 监听的是data中的数据变化
  2. computed是支持缓存,依赖的属性值发生变化,计算属性才会重新计算,否则用缓存;watch是不支持缓存的
  3. computed不支持异步,watch可以异步操作
  4. computed是第一次加载就监听,watch是不监听
  5. computed函数中必须有return,watch中不用

8. vuex在什么场景会去使用?属性有哪些?

  1. 属性有:
  • state 存储变量
  • getters state的计算属性 doubleSum(state){}
  • mutations 提交更新数据的方法,必须同步 function(state,value){}
  • actions 和mutations差不多,提交mutations来修改数据,可以包括异步操作 function(context,value){}
  • modules 模块化vuex仓库
      // 引入Vue
      import Vue from 'vue';
      // 引入vuex
      import Vuex from 'vuex'
      Vue.use(Vuex) // use 之后创建vm的时候,可以有store配置项
    
      // 准备actions,用于响应组件中的动作
      const actions = {
        // 可简写为 jiaOdd(context, value){}
        jiaOdd: function (context, value) {
          if (context.state.sum % 2 != 0) {
            context.commit('JIA', value)
          }
        }
      }
      // mutations 用于操作数据(state)
      const mutations = {
        JIA(state, value) {
          state.sum += value;
        }
      }
      // state 用于存储数据
      const state = {
        sum: 0
      }
      export default new Vuex.Store({
        actions,
        mutations,
        state   
      })
    
  1. 使用场景:用户的个人信息、购物车模块、订单模块、结算

9.Object.defineProperty()-对对象的某个属性(对象新增、删除某个属性,无法检测到)、或者数组的索引进行劫持(用数组的方法,没办法感知);Object.defineProperty(操作对象,操作属性,{}) 在对象中实现数据的劫持

  1. Object.defineproperty 的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。 Object.defineproperty可以接收三个参数,Object.defineproperty(obj, prop, desc):
  • obj : 第一个参数就是要在哪个对象身上添加或者修改属性
  • prop : 第二个参数就是添加或修改的属性名
  • desc : 配置项,一般是一个对象。writable: 是否可重写;value:当前值;get:读取时内部调用的函数;set:修改时内部调用的函数;enumerable:是否可以枚举;configurable:是否可再次修改配置项。
      let arr = [1, 2, 3];
      const arrayProto = Array.prototype;
      let arrMethods = ['push', 'pop', 'shift', 'unshift','splice', 'sort', 'reverse']
      arrMethods.forEach(method => {
        observer(arrayProto, method, arrayProto[method]);
      });
      // 第一个参数:arrayProto
      // 第二个参数:key
      function observer(obj, key, value) {
        Object.defineProperty(obj, key, {
          value(...args) {
            console.log(this);
            console.log(value);
            value.apply(this, args)
          }
        });   
      }
      const arrayProto = Array.prototype;
      Object.defineProperty(obj, key, value)
    
      // Object.defineProperty(操作对象,操作属性,{})方法使用
      let data = {
        name: '张三',
        age: 19
      }
      let value = data.name;
      function observer(obj, key, value) {
        Object.defineProperty(obj, key, {
            configurable: true, // 可配置的
            enumerable: true, // 可迭代的
            get() {
              console.log('get', value);
              return value; // data.name 会一直触发get,因此将data.name保存在value变量中 返回
            },
            set(newValue) {
              console.log('set', newValue);
              value = newValue;
            }
          })
      }
        for (let key in data) {
          observer(data, key, data[key]);
      }
        let arr = [1, 2, 3];
        arr.forEach((item, index) => {
          observer(arr, index, arr[index])  
      })
    
      let  person = {
        name:"码农",
        age: 18   
      }
      Object.defineProperty(person,'sex',{
        value:"男",   //设置属性值
        enumerable:true, //控制属性是否可以枚举,默认值是false
        writable:true, //控制属性是否可以被修改,默认值是false
        configurable:true //控制属性是否可以被删除,默认值是false
      })
      console.log(person)