欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VUE 各种遇到的问题以及面试题

程序员文章站 2022-04-19 16:07:19
...

原文链接

原理

1.你知道vue的模板语法用的是哪个web模板引擎的吗?说说你对这模板引擎的理解.

mustache,主要是使用{{}}进行数据渲染。

2.你知道v-model的原理吗?那双向绑定的原理呢?

v-model是一个语法糖,真正实现双向绑定还是依靠v-bind:绑定响应式数据。以及触发input事件并传递数据(核心和重点)
双向绑定的原理:通过Observer把数据劫持(Object.defineProperty()),加入到订阅器(Dep),订阅器收集订阅者(watch),视图通过编译(Compile)
解析指令(Directive)等一系列操作收集给订阅者,最后通过触发数据变化update通知所有的订阅者完成数据驱动。
直白的理解为:Object.defineProperty()重新定义了set和get方法,修改触发set方法赋值。获取触发get方法取值,并通过数据劫持发布信息。

3.你知道vue中key的原理吗?说说你对它的理解

便于diff算法的更新,key的唯一性,能让diff算法更快的找到需要更新的dom节点。

4.Vue.Observable你有了解过吗?

vue2.6发布的一个新的api,可以处理简单的跨组件共享数据状态的问题。
精简版的vuex。

5.你知道style加scoped属性的用途和原理吗?

1.用途:防止全局同名css污染。
2.原理:在标签上添加v-data-something属性,再在选择器加上对应[v-data-something],即css带属性选择器,以此完成类似作用域的选择方式。

6.$nextTick的作用

// 官方文档:下次DOM更新循环结束执行延迟回调,在修改数据之后立刻调用这个方法,就会获取更新后的DOM。

//什么时候用到Vue.$nextTick();

//1.created初始化状态的时候没有挂载dom元素,所以此时需要操作dom元素就必须使用$nextTick();
//2.mounted不会承诺所有的子组件也都一起被挂载,如果你希望等到整个视图都渲染完毕,可以用$nextTick()替换mounted。

mounted:function(){
   this.$nextTick(()=>{
       
   })
}

文件路径

1.怎么解决vue打包后静态资源图片失效的问题?,那又怎么解决动态设置img的src不生效呢?

1.找到config/index.js配置文件,找到build打包对象里的assetsPublicPath属性,将默认值:'/',修改为:'./'。
2.因为动态添加的src被当做静态资源处理了,没有进行编译,所以要加上require。
<img :src="require('@/assets/images/xxx.png')" />

2.分析下vue项目本地开发完后部署到服务器后报404是什么原因?

1.检查nginx(服务器)配置,是否正确配置资源映射条件。
2.检查vue.config.js中是否配置了pubilcPath属性,检查是否和项目资源文件在服务器摆放的位置一样。

3.在vue项目中如何配置favicon?

1.在html中添加mate标签
2.在vue-cil中开发环境webpack.dev.config.js中配置,和生产环境webpack.prod.config.js中配置。

4.使用vue后怎么针对搜索引擎做SEO优化?

使用服务端渲染,vue官方推荐nuxt.js

生命周期

1.Vue生命周期可以分为几个阶段?

8个阶段
1.beforeCreate:创建前,(data和methods都没初始化)
2.created:创建后,(data和methods已经初始化)
3.beforeMount:载入前,(在内存中已经编译好了模板,但是还没有挂载到页面上,dom还没有生成)
4.mounted:载入后,(Vue实例已经初始化完成了,此刻dom已经生成)
5.beforeUpdate:更新前,(此刻页面的数据是旧的,data的数据是更新的了,也就是页面还没有和最新的数据同步)
6.updated:更新后(页面的数据已经和更新的数据同步了),
7.beforeDestroy:销毁前(此刻data,mothods,指令,过滤器都处于可用状态),
8.destroyed:销毁后(此刻所有的data,mothods,指令等等,都处于不可用状态)

2.Vue在created和mounted这两个生命周期中请求的数据有什么区别?

1.在created请求时,是在页面渲染出来之前做的事情,如果数据过大,可能造成页面白屏过久,因为created还没有dom元素生成。并且也不能操作dom元素
2.在mounted请求时,是在页面渲染出来之后做的事情,此时可以操作dom元素。

3.跟keep-alive有关的生命周期是哪些?描述下这些生命周期

1.activated: 页面第一次进入的时候,钩子触发的顺序是created->mounted->activated
2.deactivated: 页面退出的时候会触发deactivated,当再次前进或者后退的时候只触发activated

4.第一次加载页面时会触发哪几个钩子?

1.beforeCreate
2.created
3.beforeMount
4.mounted

组件

1.如何通过子组件访问父组件的实例

this.$parent :拿到父组件的实例
this.$children拿到子组件实例(数组)

2.如何访问子组件的实例或者子元素

//父组件
<template>
    //给子组件绑定ref属性
    <base-alert ref="baseAlert"></base-alert>
</template>
使用this.$refs.baseAlert获取到子组件,并且可以调用子组件this.$refs.baseAlert.add()方法。

3.vue怎么实现强制刷新组件?

//强制刷新某组件
<SomeComponent :key='theKey'>
//选项里绑定data
data(){
  return{
      theKey:0
  }
}
//刷新key达到刷新组件的目的
theKey++;

4.vue自定义事件中父组件如何接收子组件的多个参数?

//子组件提交多个参数
var data = {
    'name':'1',
    'name2':'2'
}
this.$emit('func',data)

5.vue给组件绑定自定义事件无效怎么解决?

1、组件外部加修饰符:.native
//父组件
<div>
     <my-children @click.native='onClick'></my-children>
</div>
2、组件内部添加$emit()方法提交事件

6.vue如果想扩展某个现有的组件时,该怎么做?

1.使用slot插槽。
2.使用mixin混入。
3.使用vue.extends直接扩展。(优先级比mixin高)
4.使用HOC高阶组件。

7.vue为什么要求组件模板只能有一个根元素?

就像一个HTML文档只能有一个根元素一样....
多个根元素必将导致无法构成一颗树
所以解释了 <template></template>只有一个<div>根元素。

8.vue中什么是递归组件?

//当前注册一个vue组件定义 name 为 'node-tree' ,在组件 template 内部调用 实现递归。
//tree.vue
<template>
        <template v-for="item in parentItem.list">
            <node-tree v-if="item.list&&item.list.length!==0" :parent-item="item" >
                <!--无限递归,-->
            </node-tree>
        </template>
</template>
<script>
    export default{
        name:'nodeTree',
    }
</script>

9.vue边界情况有哪些?

1.访问元素&组件
   访问根实例
   访问父组件实例
   访问子组件实例或子元素
   依赖注入
2.程序化的事件侦听器
   $on(event,,,) :侦听一个事件
   $once(event,,,):一次性侦听一个事件
   $off(event,,,):停止侦听一个事件
3.循环引用
   3.1:递归组件
   3.2:组件之间的循环引用

10.vue组件中定时器要怎么销毁?

const time = setInterval(()=>{
    //do.somthing
},500)
//通过$once监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy',()=>{
     clearInterval(time)
})

11.vue组件会在什么情况下被销毁?

在组件中使用v-if的时候。

12.vue组件里写的原生addEventListeners监听事件,可以用手动销毁吗?为什么?

可以用手动销毁,因为一方面是绑定多次,另一方面是函数没有释放会造成内存溢出。

13.你了解函数式组件吗?

需要提供一个render方法,接收一个参数(createElement函数),方法内根据业务逻辑写需求,createElement创建vnodes,最后return vnodes

createElement函数接收三个参数,1:html标签或自定义组件。2:一个object(包含props,on...等等),3:children(通过createElement构建,或者字符串)

问题知识点-HTML

1.Vue渲染模板时怎么保留模板中的HTML注释呢?

//模板标签添加 comments 属性
<template comments>
     ...
</template>

2.如何修改分隔符"{{}}"?

//对于laravel+vue开发已经成为常态(php),laravel框架开发下我们的分隔符"{{}}"是和vue+webapck+node是一样的。所以我们要修改我们的分隔符。

var vm =new Vue({
     el:"app",
     delimiters:['${' , '}'], //修改定界符'{{}}';
    data(){}
})
//最后laravel框架下的分割符变成了${}

3.slot(插槽)的理解有多少?

//插销显示与否:应根据父组件在引入子组件时,子组件中是否存在模板。

1.匿名插槽:在父组件中只能出现一个。
2.具名插槽:在父组件中可以出现多个
3.作用于插槽:在插槽中要绑定数据,
<slot name="up" :data="data"></slot>
 export default {
    data: function(){
      return {
        data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
      }
    },

4.如何优化首页的加载速度?

1.http请求控制次数。
2.异步加载数据,异步路由。
3.分屏加载,按需加载,延迟加载图片,cdn静态资源缓存。 

问题知识点-CSS

1.Vue的:class和;style有几种表达方式?

:class 绑定变量,绑定对象,绑定一个数组,绑定三元运算符
:style 绑定变量,绑定对象,绑定函数返回值,绑定三元运算符

问题知识点-JS

1.Vue中怎么重置data

1.Object.assign()方法:用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。
2.this.$data:获取当前状态下的data。
3.this.$option.data:获取该组件初始化状态下的data。
4.Object.assign(this.$data,this.$option.data);

2.watch的属性用箭头函数定义结果会怎么样?

this为undefined,因为箭头函数绑定了父级作用域的山下文,所以this将不会按照期望指向vue实例。

3.在vue项目中如果methods的方法用箭头函数定义结果会怎么样?

因为箭头函数默认绑定了父级作用域的上下文,所以this将不会绑定vue实例,所以this是undefined。

4.你有使用过babel-polyfill模块吗?主要是用来做什么的?

babel默认只进行转换语法,而不转换新的api。所以想要转换新的api还需要对应的转换插件。或者使用polyfill模拟新api。

5.说说你对vue的错误处理的了解?

vue错误处理有两种,
1.errorCaptured:是组件内部钩子,可以捕获到本组件以及子孙组件抛出的错误,接收参数有error,vm,info三个参数,return false后可以阻止错误继续向上抛出、
2.errorHandler:为全局钩子,使用vue.config.errorHandler配置,接收参数和errorCaptured一致,2.6后可捕获v-on与promise链的错误,可用于统一错误处理与错误兜底。
  1. 在vue事件中传入$event,使用e.target和e.currentTarget有什么区别?
e.target:属于事件发生者(鼠标触发的元素)
e.currentTarget:属于事件绑定的元素。

7.vue变量名如果以_、$开头的属性会发生什么问题?怎么访问到它们的值?

以_或者$开头的属性 不会被vue实例代理,因为它们可能会和vue内置属性,api方法冲突,
我们可以使用vm.$data._property的方式访问这些属性

8.vue使用v-for遍历对象时,是按照什么顺序遍历的?如何保证顺序?

1.会先判断对象是否存在iterator接口,如果有循环执行next()方法。
2.没有iterator的情况下,会调用Object.Keys()方法,在不同的浏览器中,js引擎不能保证输出的顺序是一致的。
3.如果想要保证输出的顺序一致,可以将对象放进数组中,作为数组的元素。

9.说下attrsattrs和listeners的使用场景

$attrs:获取父级以上的所有(非props属性)的属性。
$listeners:调用在父级以上的所有定义的方法。

10.EventBus事件总线注册在全局上时,路由切换的时候重复触发事件,该如何解决呢?

1、EventBus的使用
//创建EventBus
import Vue from 'vue'
export default new Vue;

2、在main.js导入eventbus,然后挂载在vue原型上

import bus from './utils/eventBus';

Vue.prototyle.bus = bus;

3、发送事件
//在触发事件的地方发送事件
this.bus.$emit(this.$route.path);$emit()里面接收一个string字符串事件名,

4、接收事件
//事件已经发送,接下来只需要在需要接收事件的地方接收这个事件,然后对事件进行响应就可以了。
this.bus.$on(this.$route.path,()=>{
  this.getData();
})
//接收事件同样需要一个事件名。

5、事件重复触发的问题
 //我们只需要在组件的beforeDestroy或者destroy生命周期中执行销毁方法。
beforeDestroy(){
 this.bus.$off(this.$route.path)
}

6、如果使用this.$route.path作为事件名,那么虽然我们在生命周期注销了事件,但是还是发现事件会执行多次,原因在于我们在beforeDestroy中,this.$router.path根本不是我们发送和响应事件时候的路由了,而是将要跳转的页面路由。所以只要我们在当前页面用一个变量将当前路由存下来。用这个变量作为变量名注销事件即可。

11.Vue组件中写name选项有什么作用?

1.使用keep-alive时,可以搭配组件name进行缓存过滤
2.DOM做递归组件时需要调用自身name。
3.vue-devtools调式工具里显示的组件名称是有vue中name决定的

12.Vue中的provide和inject是什么?

provide:是一个对象,或者是返回对象的函数,里面包含要给子孙后代的东西,也就是属性和属性值。(不再需要逐级往上找值)
inject:是一个字符串数组,或者是一个对象,属性值可以是一个对象,包含from,和default默认值。

13.v-if和v-for同时出现的优先级问题?

//v-for的优先级比v-if高。所以同时出现的时候,先给v-for套一层template作为父级元素,再在父级元素进行v-if判断

<template v-if>
    <div v-for></div>
<template>

指令与修饰符

1.v-once的使用场景有哪些?

表单提交,可防止用户在请求未响应时再次点击多次触发。

2.vue修饰符.lazy的理解?

由input事件改变为change事件。

3.常用的指令

1.v-if 、2.v-for、3.v-on、4.v-bind、5.v-once 、
6.v-foucs、7.v-blur、8.v-model、 9.v-hide、10.v-show

4.v-cloak和v-pre指令的理解

1.v-cloak:是指在HTML渲染之前定义的一个指令属性,通常用于解决网络延迟页面显示Vue源码的问题。

<div id='app' v-cloak>
  {{context}}
</div>

//CSS
[v-cloak]{
   display:none;//隐藏{{context}}源码的显示。
}

2.v-pre:跳过添加v-pre指令的元素以及它的所有子元素的编译过程。

<span v-pre>{{msg}}</span>
//即使在data定义了msg,这里仍然会在页面显示{{msg}}

5.指令的钩子有哪些?

1.bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性初始化设置
2.inserted:被绑定元素插入父节点时调用(仅保证父节点的存在,但不一定已被插入文档中)
3.update:所在组件的VNode更新时调用。但是可能发生在其子VNode更新之前。指令的值可能发生了变化。也可能没有。
4.componentUpated:指令所在的组件的VNode及其子VNode全部更新后调用。
5.unbind:只调用一次,指令与元素解绑时调用

6.prevent.self与self.prevent的先后顺序问题

//prevent.self 阻止元素所有自身的点击事件
<div @click="fun()">
    <a href="@/pages/home/homeIndex" @click.prevent.self="fun1()">
        <span v-on:click="fun2()">sapn标签</span>
    </a>    
</div>

//点击span标签 会触发fun2和fun函数 但是 a标签所有的事件都不会触发,包括链接跳转

//self.prevent 阻止元素自身的点击事件
<div @click="fun()">
    <a href="@/pages/home/homeIndex" @click.self.prevent="fun1()">
        <span v-on:click="fun2()">sapn标签</span>
    </a>    
</div>

//点击span标签 会触发fun2和fun函数 但是 a标签自身的点击事件不会触发,而会触发链接跳转

相关标签: vue 面试题