HLJ 发布于
2018-05-30 12:51:09

vue面试题

上一篇文章:

es6面试题

下一篇文章:

css面试题

Vue 的优缺点

  • 优点
  • 创建单页面应用的轻量级Web应用框架
  • 简单易用
  • 双向数据绑定
  • 组件化的思想
  • 虚拟DOM
  • 数据驱动视图
  • 缺点
  • 不支持IE8

SPA 的理解

  • SPA单页应用。在WEB页面初始化时一同加载Html、Javascript、Css。一旦页面加载完成,SPA不会因为用户操作而进行页面重新加载或跳转,取而代之的是利用路由机制实现Html内容的变换
  • 优点
  • 良好的用户体验,内容更改无需重载页面。
  • 基于上面一点,SPA相对服务端压力更小。
  • 前后端职责分离,架构清晰。
  • 缺点
  • 由于单页WEB应用,需在加载渲染页面时请求JavaScript、Css文件,所以耗时更多。
  • 由于前端渲染,搜索引擎不会解析JS,只能抓取首页未渲染的模板,不利于SEO。
  • 由于单页应用需在一个页面显示所有的内容。

如何实现 v-model

  • v-model指令用于实现input、select等表单元素的双向绑定,是个语法糖。
  • 原生 input 元素若是text/textarea类型,使用 value 属性和 input 事件。
  • 原生 input 元素若是radio/checkbox类型,使用 checked属性和 change 事件。
  • 原生 select 元素,使用 value 属性和 change 事件。
  • input 元素上使用 v-model 等价于
    <input :value="message" @input="message = $event.target.value" />
    
  • 实现自定义组件的 v-model
  • 自定义组件的v-model使用prop值为value和input事件。若是radio/checkbox类型,需要使用model来解决原生 DOM 使用的是 checked 属性 和 change 事件,如下所示。
    // 父组件
    <template>
    <base-checkbox v-model="baseCheck" />
    </template>
    // 子组件
    <template>
    <input type="checkbox" :checked="checked" @change="$emit('change', $event.target.checked)" />
    </template>
    <script>
    export default {
    model: {
      prop: 'checked',
      event: 'change'
    },
    prop: {
      checked: Boolean
    }
    }
    </script>
    

    router-link上事件无效解决方法

  • 使用@click.native。原因:router-link会阻止click事件,.native指直接监听一个原生事件。

常用的修饰符

  • 表单修饰符
  • lazy: 失去焦点后同步信息
  • trim: 自动过滤首尾空格
  • number: 输入值转为数值类型
  • 事件修饰符
  • stop:阻止冒泡
  • prevent:阻止默认行为
  • self:仅绑定元素自身触发
  • once:只触发一次
  • 鼠标按钮修饰符
  • left:鼠标左键
  • right:鼠标右键
  • middle:鼠标中间键

class 与 style 如何动态绑定

  • class 和 style 可以通过对象语法和数组语法进行动态绑定

  • 对象写法
    <template>
    <div :class="{ active: isActive }"></div>
    <div :style="{ fontSize: fontSize }">
    </template>
    <script>
    export default {
    data() {
      return {
        isActive: true,
        fontSize: 30
      }
    }
    }
    
  • 数组写法
    <template>
    <div :class="[activeClass]"></div>
    <div :style="[styleFontSize]">
    </template>
    <script>
    export default {
    data() {
      return {
        activeClass: 'active',
        styleFontSize: {
          fontSize: '12px'
        }
      }
    }
    }
    </script>
    

    slot 插槽

  • slot 插槽,可以理解为slot在组件模板中提前占据了位置。当复用组件时,使用相关的slot标签时,标签里的内容就会自动替换组件模板中对应slot标签的位置,作为承载分发内容的出口。

  • 主要作用是复用和扩展组件,做一些定制化组件的处理。

  • 插槽主要有3种

  • 默认插槽
    // 子组件
    <template>
    <slot>
      <div>默认插槽备选内容</div>
    </slot>
    </template>
    // 父组件
    <template>
    <Child>
      <div>替换默认插槽内容</div>
    </Child>
    </template>
    
  • 具名插槽
  • slot 标签没有name属性,则为默认插槽。具备name属性,则为具名插槽

// 子组件
<template>
  <slot>默认插槽的位置</slot>
  <slot name="content">插槽content内容</slot>
</template>
// 父组件
<template>
   <Child>
     <template v-slot:default>
       默认...
     </template>
     <template v-slot:content>
       内容...
     </template>
   </Child>
</template>
  • 作用域插槽
  • 子组件在作用域上绑定的属性来将组件的信息传给父组件使用,这些属性会被挂在父组件接受的对象上。
    // 子组件
    <template>
    <slot name="footer" childProps="子组件">
      作用域插槽内容
    </slot>
    </template>
    // 父组件
    <template>
    <Child v-slot="slotProps">
      {{ slotProps.childProps }}
    </Child>
    </template>
    

    Vue.directive 有写过么,应用场景有哪些?

  • Vue.directive 可以注册全局指令和局部指令。
    // 注册
    Vue.directive('my-directive', {
    bind: function () {},
    inserted: function () {},
    update: function () {},
    componentUpdated: function () {},
    unbind: function () {}
    })
    // 注册 (指令函数)
    Vue.directive('my-directive', function () {
    // 这里将会被 `bind` 和 `update` 调用
    })
    // getter,返回已注册的指令
    var myDirective = Vue.directive('my-directive')
    
  • 指令定义函数提供如下钩子函数
  • bind:指令第一次绑定到元素时调用(只调用一次)
  • inserted: 被绑定元素插入父节点时使用(父节点存在即可调用)
  • update:被绑定元素所在模板更新时调用,不论绑定值是否变化。通过比较更新前后的绑定值。
  • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  • unbind: 只调用一次,指令与元素解绑时调用。
  • 我项目中有涉及 一键copy、权限控制 都可以用指令的方式控制,目的就是简化我们的工作量。

Vue 过滤器了解么

  • Vue 过滤器可用在两个地方:双花括号插值和 v-bind 表达式。
  • Vue3 中已经废弃这个特点。
  • 过滤器分为 全局过滤器 和 局部过滤器。
  • 局部过滤器
    <template>
    <div>{{ message | formatMessage }}</div>
    </template>
    <script>
    export default {
    filters: {
      formatMessage: function(value) {
        // 可基于源值做一些处理
        return value
      }
    }
    }
    </script>
    
  • 全局过滤器
    Vue.filter('formatMessage', function(value) {
    // 可基于源值做一些处理
    return value
    })
    
  • 过滤器可串联,执行顺序从左到右,第二个过滤器输入值是第一个过滤器的输出值。
    <div>{{ message | formatMessage1 | formatMessage2 }}</div>
    

v-show 与 v-if 有什么区别?

  • 相同点:两者都是达到显示隐藏的功能,
  • 不同点:v-show指令通过修改元素的display属性让其显示或者隐藏,v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

computed 和 watch 的区别和运用的场景?

  1. computed
    • 当一个属性受多个属性影响的时候就需要用到computed
    • 最典型的栗子: 购物车商品结算的时候
    • 模板内的表达式非常遍历,但是呢复杂的逻辑,都应当使用计算属性。
    • 计算属性缓存 vs 方法
      • 计算属性具有缓存性,当相关属性值改变时才重新求值,相反只返回之前计算的结果。不必再次执行函数
      • 方法是每次触发都重新渲染重新调用函数,
  2. watch:
    • 当一条数据影响多条数据的时候就需要用watch
    • 搜索数据

Vue 的父组件和子组件生命周期钩子函数执行顺序?

  • 加载渲染过程:

    • 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
  • 子组件更新过程:

    • 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
  • 父组件更新过程:

    • 父 beforeUpdate -> 父 updated
  • 销毁过程:

    • 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
生命周期 阶段 描述
beforeCreated 创建前 vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
created 创建后 vue实例的数据对象data有了,$el还没有。
beforeMount 模板载入前 vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换
mounted 模板载入后 vue实例挂载完成,data.message成功渲染。
beforeUpdate 组件更新前 组件更新之前调用
updated 组件更新后 组件更新之后调用
beforeDestroy 组件销毁前 调用$destroy方法后,立即执行beforeDestroy
destroyed 组件销毁后 组件销毁后调用,此时只剩下dom空壳

Vue2.x 生命周期

1. 有哪些生命周期
系统自带:
  beforeCreate
  created
  beforeMount
  mounted
  beforeUpdate
  updated
  beforeDestroy
  destroyed
2. 一旦进入到页面或者组件,会执行哪些生命周期,顺序。
 beforeCreate
 created
 beforeMount
 mounted
3. 在哪个阶段有$el,在哪个阶段有$data
    beforeCreate 啥也没有
    created  有data没有el
    beforeMount 有data没有el
    mounted 都有
4. 如果加入了keep-alive会多俩个生命周期
    activated、deactivated
5. 如果加入了keep-alive,第一次进入组件会执行哪些生命?
 beforeCreate
 created
 beforeMount
 mounted
 activated
6. 如果加入了keep-alive,第二次或者第N次进入组件会执行哪些生命周期?
只执行一个生命周期:activated

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

  • 因为组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。

keep-alive>的作用是什么?

  • 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染

vue如何在父组件中调用子组件的方法

  • 通过 ref

v-if和v-for谁的优先级高

  • v-for的优先级高,所以也就是说如果他俩在一起使用时,v-if会运行很多遍,解决办法就是在循环的模版外边套一层框子,在这个框子上使用v-if就好了

v-on可以绑定多个方法吗?

  • 可以,直接在后边跟上就可以了
    <div v-on="{click:myclick,mouseleave:myMouseleave}"></div>
    

如何让CSS只在当前组件中起作用?

  • 在组件中的style前面加上scoped

如何获取dom?

  • ref="domName" 用法:this.$refs.domName

为什么使用key

  • 需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。 作用主要是为了高效的更新虚拟DOM

请说出vue.cli项目中src目录每个文件夹和文件的用法?

  • assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置; app.vue是一个应用主组件;main.js是入口文件。

$nextTick的使用

  • 获取更新后的dom内容
  • 当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值, 你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。

Vue请求初始化数据放在Created还是Mounted?

(1)mounted

  如果把所有请求放在created里面的话,请求过多会,加载太慢会导致页面出现短暂的白屏情况,一般上我写的话,接口不复杂会放created里面,接口多复杂的话会放在mounted里面.

(2)mounted

  created 是加载DOM,html之后 就马上执行, 比如初始化,获取屏幕高度调整,赋值等等,而mounted就是执行包括js之后,准备开始调用方法,也就是说 类似传统开发那样,先加载jquery 再调用插件

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

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。简单来说就是:应用遇到多个组件共享状态时,使用vuex。
  • 场景:多个组件共享数据或者是跨组件传递数据时

vuex有哪几种属性

  • 有五种,分别是State , Getter , Mutation , Action , Module (就是mapAction)
  • state:vuex的基本数据,用来存储变量
  • geeter:从基本数据(state)派生的数据,相当于state的计算属性
  • mutation:是用来改变state值的唯一方法,是同步请求
    store.commit('increment')
    
  • action:通常是异步用来提交mutation,而不是直接变更状态。
    store.dispatch('increment')
    
  • modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?

  • 一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。

  • 二、如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便

什么是Webpack

  • webpack 是一个现代 JavaScript 应用程序的静态模块打包器

  • 入口(entry)、输出(output)、loader、插件(plugins)、模式

  • webpack打包原理本
  • 把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载。

有哪些常见的Loader?他们是解决什么问题的?

  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
  • url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
  • source-map-loader:加载额外的 Source Map 文件,以方便断点调试
  • image-loader:加载并且压缩图片文件
  • babel-loader:把 ES6 转换成 ES5
  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性
  • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
  • eslint-loader:通过 ESLint 检查 JavaScript 代码

有哪些常见的Plugin?他们是解决什么问题的?

  • define-plugin:定义环境变量
  • commons-chunk-plugin:提取公共代码
  • uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码

Loader和Plugin的不同?

  • Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
  • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

keep-alive

https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive https://www.jianshu.com/p/d9211d5b5837 https://blog.csdn.net/fu983531588/article/details/90321827

vue终极性能优化方案(解决首页加载慢问题)

  • 1、(CDN引入第三方库)对于第三方js库的优化,分离打包

    生产环境是内网的话,就把资源放内网,通过静态文件引入 如果有外网的话,可以通过CDN方式引入,因为不用占用访问外网的带宽,不仅可以为您节省流量,还能通过CDN加速,获得更快的访问速度。但是要注意下,如果你引用的CDN 资源存在于第三方服务器,在安全性上并不完全可控。

  • 2、使用vue-router路由懒加载

    在访问到当前页面才会加载相关的资源

  • 3、打包文件中去掉map文件

    打包的app.js过大,另外还有一些生成的map文件。先将多余的map文件去掉,

找到config文件夹下index.js文件,把这个build里面的productionSourceMap改成false即可

  • 4、图片资源的压缩
  • 5、gzip打包

    通过减少文件体积来提高加载速度

  • 6、webpack相关配置优化
  • 7、前端页面代码层面的优化

Vue 组件间通信有哪几种方式?

  • (1)props / $emit 适用 父子组件通信
  • (2)ref 与 $parent / $children 适用 父子组件通信
  • (3)EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
  • (4)$attrs/$listeners 适用于 隔代组件通信
  • (5)provide / inject 适用于 隔代组件通信
  • (6)Vuex 适用于 父子、隔代、兄弟组件通信

vue-router 路由模式有几种?

  • Hash: 使用URL的hash值来作为路由。支持所有浏览器。
  • History: 以来HTML5 History API 和服务器配置。

delete和Vue.$delete删除数组的区别

  • delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。
  • Vue.$delete直接删除了数组 改变了数组的键值。

key主要是解决哪一类的问题,为什么不建议用索引index(重绘)

  • (1)key的作用主要是为了高效的更新虚拟DOM
  • (2)当以index为key值时,如果数组长度发生变化,会导致key的变化,比如删除其中某一项,那么index会相应变化。 所以用index作为key和不加index没有什么区别,都不能提升性能。一般用每项数据的唯一值来作为key,就算数组长度变化,也不会影响到这个key

如何获取传过来的动态参数?

  • 在组件中,使用$router对象的 params.id,即 $route.params.id 。

vue- router有哪几种导航钩子?

  • 有3种。
  • 第一种是全局导航钩子:router.beforeEach(to,from,next)。作用是跳转前进行判断拦截。
  • 第二种是组件内的钩子。
  • 第三种是单独路由独享组件。

当使用组件的kep- alive功能时,增加以下两个周期。

  • activated在keep- alive组件激活时调用;
  • deactivated在keep-live组件停用时调用。
文章来源:
最后生成于 2023-06-18 18:28:37
上一篇文章:

es6面试题

下一篇文章:

css面试题

此内容有帮助 ?
0