2022前端面试题之VUE(持续更新中哦)

霖霂晗

。。。
vue.js的两个核心是什么?
- 数据驱动(双向数据绑定)核心是VM,即ViewModel,保证数据和视图的一致性
- 组件系统
Vue双向数据绑定的原理
- Vue.js是采用 数据劫持 结合 发布者-订阅者模式 的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发给订阅者,触发相应的监听回调
请说出vue几种常用的指令
- v-if:根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。
- v-show:根据表达式之真假值,切换元素的 display CSS 属性。
- v-for:循环指令,基于一个数组或者对象渲染一个列表,vue 2.0以上必须需配合 key值 使用。
- v-bind:动态地绑定一个或多个特性,或一个组件 prop 到表达式。
- v-on:用于监听指定元素的DOM事件,比如点击事件。绑定事件监听器。
- v-model:实现表单输入和应用状态之间的双向绑定
- v-pre:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
- v-once:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能
vue生命周期
- beforeCreate:创建前
- created:创建后
- beforeMount:挂载前
- mounted:挂载后
- beforeUpdate:更新前
- updated:更新后
- activated():keep-alive 组件激活时调用
- deactivated(); keep-alive 组件停用时调用
- beforeDestroy:销毁前
- destroyed:销毁后
- errorCaptured(2.5.0+ 新增)
v-if 和 v-show 有什么区别
相同点
- 动态显示DOM元素。
区别
- v-if 是 真正 的 条件渲染,有更高的切换消耗,v-if适合运行时条件很少改变时使用
- v-show 只是简单地切换元素的 CSS 属性display。有更高的初始消耗,v-show适合频繁切换
vue常用的修饰符
- .stop - 调用 event.stopPropagation(),禁止事件冒泡。
- .prevent - 调用 event.preventDefault(),阻止事件默认行为。
- .capture - 添加事件侦听器时使用 capture 模式。
- .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
- .left - (2.2.0) 只当点击鼠标左键时触发。
- .right - (2.2.0) 只当点击鼠标右键时触发。
- .middle - (2.2.0) 只当点击鼠标中键时触发。
- .passive - (2.3.0) 以 { passive: true } 模式添加侦听器
vue中 key 值的作用
- 唯一性,用于 管理可复用的元素
- v-for 的默认行为会尝试原地修改元素而不是移动它们。要强制其重新排序元素,你需要用特殊属性 key 来提供一个排序提示
什么是$nextTick?
- 因为Vue的异步更新队列,$nextTick是用来知道什么时候DOM更新完成的。
Vue 组件中 data 为什么必须是函数?
- 因为组件是共享的,但他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的对象,不要和其他组件共用一个对象
v-for 与 v-if 的优先级
- v-for的优先级比v-if更高
- 永远不要把 v-if 和 v-for 同时用在一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断)
- 如果避免出现这种情况,则在外层嵌套 template (页面渲染不生成dom节点),再这一层进行 v-if 判断,然后再内部进行 v-for 循环
<template v-if="isShow">
<p v-for="item in items">
</template>
vue中组件之间调用
vue中子组件调用父组件的方法
- 在子组件中通过'$emit'触发 当前实例上的 自定义事件。
- this.$emit('func',this.msg) (fuc是父组件中的函数,this.msg是传递给父组件的值)
父组件给子组件通过props传值
vue父组件调用子组件中的方法
- 在父组件中:首先要引入子组件 import Child from './child';
- 是在父组件中为子组件添加一个占位,ref="mychild"是子组件在父组件中的名字
- 父组件中 components: {} 是声明子组件在父组件中的名字
- 在父组件的方法中调用子组件的方法,很重要 this.$refs.mychild.parentHandleclick("hello");
Vue组件通讯方式
- props / $emit 适用 父子组件通信
- ref 与 $parent / $children 适用 父子组件通信
- $emit / $on 适用于 父子、隔代、兄弟组件通信
- $attrs/$listeners 适用于 隔代组件通信
- provide / inject 适用于 隔代组件通信
- Vuex 适用于 父子、隔代、兄弟组件通信
Vue中$set()的作用
- 给对象添加新的属性。如果视图不能更新的话用$set可以进行视图更新。只所以用$set 是因为Vue无法监听普通的新增属性的变化。
Axios
-Axios 是一个基于 promise 的 HTTP 库,可以在浏览器和 node.js 中运行 - 特性
1.从浏览器中创建 XMLHttpRequests 2.从 node.js 创建 http 请求 3.支持 Promise API 4.拦截请求和响应 5.转换请求数据和响应数据 6.取消请求 7.自动转换 JSON 数据 8.客户端支持防御 XSRF - 安装方法npm install axios
- 引入(一般在封装接口的js文件中引入)import axios from 'axios';
- 搭配UI框架如:iview、vant、elementUI等
vue中的跨域问题处理
-
为什么会出现跨域呢? 不满足同源策略:协议+域名+端口一致
-
解决跨域 在vue项目中找到vue.config.js文件中devServer配置
vue-router有哪几种导航钩子( 导航守卫 )?
- 全局守卫: router.beforeEach
- 全局解析守卫: router.beforeResolve
- 全局后置钩子: router.afterEach
- 路由独享的守卫: beforeEnter
- 组件内的守卫: beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave
vue-router路由的两种模式
- vue-router路由提供了两种路由模式:hash模式和history模式。
- hash模式:在浏览器中符号“#”,#以及#后面的字符称之为 hash, 用 window.location.hash 读取
- 在vue的router中,通过修改vueRouter的mode属性来决定使用history还是hash。默认为hash模式。
vue 路由跳转
- 标签跳转 router-link
<li >
<router-link to="user">点击验证动画效果 </router-link>
</li>
-
事件跳转 this.$router.push() query 传参,相当于get请求,页面跳转时参数会在地址栏中显示
this.$router.push({
path:'/user',
query:{
id:this.id
params 传参,相当于post请求,页面跳转时参数不会在地址栏中显示,通过this.$route.params.id获取
this.$router.push({
path:'/user',
params:{
id:this.id
注意:query刷新不会丢失query里面的数据 params刷新会丢失 params里面的数据。 - this.$router.replace{path:'/user'} (描述:同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录) - this.$router.go(n) 相对于当前页面向前或向后跳转多少个页面,类似 window.history.go(n)。n可为正数可为负数。正数返回上一个页面 - this.router.forward() 前进一步 - this.router.back() 回退一步
vuex(状态管理器的使用)
- State:单一状态树
- Getters:状态获取
- Mutations:触发同步事件
- Actions:提交mutation,可以包含异步操作
- Module:将vuex进行分模块
安装
npm install vuex --save
语法
- 在 src/文件下面创建store文件创建index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
//挂载Vuex
Vue.use(Vuex)
//创建VueX对象
const store = new Vuex.Store({
//state定义属性
state: {
count: 0,
//getters 不会修改state里面是数据,获取最新的数据
getters:{
shownum(state){
return '当前最新的值为【'+state.count+'】'
//只有mutations才能变更store中的数据,不能在mutations函数中执行异步操作
mutations: {
addition(state) {
state.count++
//actions用于异步操作,但是在action中要通过触发mutation的方式来变更数据
actions: {
export default store
-
在main.js中引用
import store from './store'//引入store文件夹下面的index.js
访问vuex的值state
- 第一种:通过this.$store.state.count 访问 count为vuex中state中属性的名称
- 第二种:
引入import {mapState} from 'vuex'
computed: {
...mapState(['count'])//mapState映射
调用vue中mutations函数的方法
- 第一种
this.$store.commit('addition2',2) //调用vue中mutations函数的方法,addition2函数名称,2是传递的参数
- 第二种
import {mapMutations} from 'vuex',
methods: {
...mapMutations(['subtraction','subtraction2']),
subbtn(){
this.subtraction();
subbtn2(){
this.subtraction2(3)
触发vue中actions函数的方法(vuex异步操作通过this.$store.dispatch触发actions里面的函数)
- 第一种
this.$store.dispatch('函数名')vuex异步操作通过this.$store.dispatch触发actions里面的函数
- 第二种
import {mapActions} from 'vuex'
methods: {
...mapActions(['subAsync','subAsync2']),
subbtn3(){
this.subAsync();
subbtn4(){
this.subAsync2(4);