Vue常见面试题总结

2022-07-21 19:41:14 浏览数 (1)

1.vue的生命周期

组件创建期间的四个生命周期函数:

beforeCreate 实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据,常用于初始化非响应式变量。

created 实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组,常用于简单的ajax请求,页面的初始化。

beforeMount 在挂载开始之前被调用,页面中的元素,还没有真正的替换过来,只是之前的一些模板字符串,如{{}}中的data中的数据并不能调用,只会显示字符串。

mounted 实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。用户已经可以看到渲染好的页面,是实例创建期间最后一个生命周期函数,执行完mounted就表示,实例已经被完全创建好了。

组件运行周期的生命周期函数:

beforeupdate 表示界面还没有被更新,但是数据(data)已经更新了,执行时,页面显示数据还是旧的数据,此时data已经更新,页面上的数据暂时未和data保持同步。

updated 事件执行的时候,页面 data数据已经保持同步了,都是最新的。

组件销毁的生命周期函数:

beforeDestroy 钩子函数时,vue实例就已经从运行阶段进入了销毁阶段,实例身上所有的data和所有的methods,以及过滤器,指令都是处于可用状态,还没有被完全销毁。

destroyed 组件已经被完全销毁了,此时组件中所有的数据、方法、指令、过滤器都无法使用。

2.如何封装axios

https://zhuanlan.zhihu.com/p/32734197

这个知乎网站查看

3.vue-router的钩子函数

1.vue router.beforeEach(全局前置守卫)

beforeEach的钩子函数,他是一个全局的before钩子函数,(beforeeach)意思是在每次每一个路由改变时都执行一次。

它的三个参数:

to:(router路由对象)即将要进入的目标路由对象to对象下面的属性: path params query hash...

from:(router路由对象)当前导航正要离开的路由

next:(function函数)一定要调用该方法来resolve这个钩子。

next(无参数的时候):进行管道中的下一个钩子,如果走到最后一个钩子函数,那么导航的状态就是confirmed(确认的)

next('/')或者next({path:'/'}):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

4.vue项目上线后出现白屏的情况怎么处理

第一种:由于把路由模式mode设置成了history了,默认是hash.

解决办法:路由里面router/index.js路由配置里面默认模式是hash,如果改成了history模式的话,打开也会是一片空白。所以改为hash或者直接把模式配置删除,让它默认的就行。如果非要使用history模式的话,需要你在服务端加一个覆盖所有的情况的候选资源;如果url匹配不到任何静态资源,则应该返回一个index.html,这个页面就是你项目的依赖页面。

第二种:打包后的dist目录下的文件引用路径不对,会因找不到文件而报错导致白屏。

解决办法:修改一下config下面的index.js中build模块导出的路径。因为index.HTML里面的内容都是通过script标签引入的,而前面的路径不对,打开肯定是空白的。

第三种:在项目中使用了es6的语法,一些浏览器不支持es6,造成编译错误不能解析而造成白屏

解决方法:1.安装npm install --save-dev babel-preset-es2015

2.安装 npm install --save-dev babel-preset-stage-3

3.在项目根目录创建一个.babelrc文件 里面内容 最基本配置是:

{

// 此项指明,转码的规则

"presets": [

// env项是借助插件babel-preset-env,下面这个配置说的是babel对es6,es7,es8进行转码,并且设置amd,commonjs这样的模块化文件,不进行转码

["env", { "modules": false }],

// 下面这个是不同阶段出现的es语法,包含不同的转码插件

"stage-2"

],

// 下面这个选项是引用插件来处理代码的转换,transform-runtime用来处理全局函数和优化babel编译

"plugins": ["transform-runtime"],

// 下面指的是在生成的文件中,不产生注释

"comments": false,

// 下面这段是在特定的环境中所执行的转码规则,当环境变量是下面的test就会覆盖上面的设置

"env": {

// test 是提前设置的环境变量,如果没有设置BABEL_ENV则使用NODE_ENV,如果都没有设置默认就是development

"test": {

"presets": ["env", "stage-2"],

// instanbul是一个用来测试转码后代码的工具

"plugins": ["istanbul"]

}

}

}

然后重启npm run dev 你会发现,可以在其他低版本浏览器跑了,基本兼容所有浏览器,ie8以下除外。而且大多数的手机浏览器也ok。重新打包到正式环境也正常。

5.token值的应用,存储在什么地方

token可以存在 Storage (localStorage sessionStorage cookie )。这些基本上支持H5的浏览器对这个本地储存都兼容。如果您是IE678之类的,建议存cookie。

Storage的localStorage长期有效,sessionStorage关闭浏览器时会自动清除

cookie的可以设置有效期。

在做登录界面时代码如下:

登录页面(login.vue)

代码语言:javascript复制
methods: {
  handleLogin (data) {
    api.AuthResource.save(data).then(response => {
      if (!response.ok) {
        console.log('登录失败')
      }
      const token = response.data.token
      window.localStorage.setItem('token', token)
      window.location.pathname = '/'
    }, response => {
      console.log('登录失败')
    })
  }
}

接口配置(api.js)

代码语言:javascript复制
 Vue.http.interceptors.push((request, next) => {
  if (window.localStorage.getItem('token')) {
    Vue.http.headers.common['Authorization'] = 'Bearer '   window.localStorage.getItem('token')
  }
  next((response) => {
    if (response.status === 401) {
      del('token')
      window.location.pathname = '/login'
    }
  })
})

配置路由(router.js)

代码语言:javascript复制
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: require('./views/Home'),
    meta: {
      requiresAuth: true
    }
  },
]

const router = new VueRouter({
  routes: routes
})

router.beforeEach((to, from, next) => {
  let token = window.localStorage.getItem('token')
  if (to.matched.some(record => record.meta.requiresAuth) && (!token || token === null)) {
    next({
      path: '/login',
      query: { redirect: to.fullPath }
    })
  } else {
    next()
  }
})

export default router

原理是通过vue-router的beforeEach钩子,在每次路由到一个地址的时候先判断该路由是否携带了meta信息,且该信息中的requireAuth是否为true,如果为true表示该路由是需要身份验证的。则去localStorage找token,若token不存在则表示用户未认证,去登录请求token。若token存在则拿着token去请求。

6.vue路由的说明以及应用

路由中有三个基本的概念 route, routes, router。

    1, route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮 => home内容, 这是一条route, about按钮 => about 内容, 这是另一条路由。

    2, routes 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, { about按钮 => about 内容}]

    3, router 是一个机制,相当于一个管理者,它来管理路由。因为routes 只是定义了一组路由,它放在哪里是静止的,当真正来了请求,怎么办?就是当用户点击home 按钮的时候,怎么办?这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。

    4,客户端中的路由,实际上就是dom 元素的显示和隐藏。当页面中显示home 内容的时候,about 中的内容全部隐藏,反之也是一样。客户端路由有两种实现方式:基于hash 和基于html5 history api.

7. 跨域问题的解决

1)后台更改header:

代码语言:javascript复制
 header('Access-Control-Allow-Origin:*');//允许所有来源访问 
 header('Access-Control-Allow-Method:POST,GET');//允许访问的方式

2)使用jQuery提供的jsonp:

代码语言:javascript复制
methods: {
 getData () {
 var self = this
 $.ajax({
   url: 'http://f.apiplus.cn/bj11x5.json',
   type: 'GET',
   dataType: 'JSONP',
   success: function (res) {
     self.data = res.data.slice(0, 3)
     self.opencode = res.data[0].opencode.split(',')
   }
 })
}}

3)使用http-proxy-middleware代理解决(项目需要使用到vue-cli脚手架搭建)

比如请求url:"http://f.apiplus.cn/bj11x5.json"

1.打开config/index.js,在Proxytype中添加如下代码:

代码语言:javascript复制
 proxyTable: {
   '/api': {  //使用"/api"来代替"http://f.apiplus.c"
     target: 'http://f.apiplus.cn', //源地址
     changeOrigin: true, //改变源
     pathRewrite: {
       '^/api': 'http://f.apiplus.cn' //路径重写
       }
   }
 }

‍ 2.使用axios请求数据时直接使用“/api”

代码语言:javascript复制
 getData () { 
         axios.get('/api/bj11x5.json', function (res) { 
           console.log(res) 
          })

8、vuex是什么?怎么使用?哪种功能场景使用它?

答:vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,….. export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车

9、mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?

答:一个model view viewModel框架,数据模型model,viewModel连接两个

区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

场景:数据操作比较多的场景,更加便捷

10、自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?

答:全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。组件内定义指令:directives

钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)

钩子函数参数:el、binding

11、Vue的双向数据绑定原理是什么?

12、vue如何实现父子组件通信,以及非父子组件通信?

可以通过props属性来实现

父组件:

//这里必须要用 - 代替驼峰

data(){ return { msg: [1,2,3] }; }

子组件通过props来接收数据: 方式1:

props: ['childMsg']

方式2 :

props: { childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告 }

方式3:

props: { childMsg: { type: Array, default: [0,0,0] //这样可以指定默认的值 } }

这样呢,就实现了父组件向子组件传递数据。

可以通过eventHub来实现通信. 所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件.

let Hub = new Vue(); //创建事件中心

组件1触发:

methods: { eve() { Hub.$emit('change','hehe'); //Hub触发事件 } }

组件2接收:

created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }

这样就实现了非父子组件之间的通信了.原理就是把Hub当作一个中转站!

13. Vue中插槽-----特殊特性slot、slot-scope与指令v-slot的使用方法

https://blog.csdn.net/qq_40616529/article/details/94033417

14、说说你对 SPA 单页面的理解,它的优缺点分别是什么?

15、组件中 data 为什么是一个函数?

【更多扩展】30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度) -- 基础必须掌握

https://blog.csdn.net/xu_song/article/details/102861394

0 人点赞