Vue相关基础面试题

Vue常用的指令

显示数据 :{{data中的键}} v-text
解析超文本:v-html
属性值:v-bind 或 :简写
事件:v-on 或 @ 简写
v-for、v-if、v-else

为啥data要写函数里面返回对象

维护一份独立的作用域
一个组件被复用多次,就会创建多个实例,本质上都是基于同一个构造函数,如果data直接是对象,由于对象是引用类型,会影响到所有实例。因此,为了保证组件不同的实例之间data不冲突,data必须是一个函数。

v-if 与 v-show 的区别

相同点:都可以用于判断控制元素隐藏显示
不同点:v-if 语法更强;v-if控制dom,v-show控制css
频繁切换时,如提示框、tab选项卡等用v-show提升性能

v-if 和 v-for 的优先级

vue2 中,在一个元素上同时使用两者,v-for会优先作用;
vue3中,v-if 总是优先于 v-for 生效

为何v-for要写key

为了快速查找到节点,减少渲染次数,提升渲染性能

v-model原理

v-model是一个基于@input/change 和 v-bind:value 封装的语法糖,底层通过JS事件和Object构造函数的defineProperty进一步封装。

双向绑定/响应式原理

利用JS的Object.defineProperty进行数据劫持结合发布订阅实现数据通知更新
数据劫持:Object.defineProperty来劫持getter、setter
发布订阅:基于Vue的$on $off $emit 这三个API开发

vue响应失效原理

底层Object.defineProperty不能监控复杂类型的子
解决:
1、可以通过递归来实现深度劫持(监控复杂类型的子);
2、数组重写:push、pop、shift、unshift、sort、reverse、splice
3、可以通过额外的API
this. $forceUpdate()
this. $set(this.data数据, 要劫持得数组索引或对象键, 默认值)

computed 和 watch的区别

计算属性computed:有缓存,且是响应式依赖缓存,不支持异步
侦听器watch:无缓存,侦听模型数据变化,支持异步,不能调用
应用场景:
computed – 购物车统计总价总数量
watch – 网站搜索、监控路由同步面包屑、日期改变

生命周期函数(钩子函数)

每个 Vue 实例在被创建时都要经过一系列的初始化过程,如 需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。
在vue实例初始化过程中,调用的函数 称之为 钩子函数、或者叫生命周期钩子函数【因为初始化过程中有数据生成或销毁。】

beforeCreate 	创建Vue实例之前

created			异步请求(实例创建完成)

beforeMount  	渲染dom之前

mounted  		渲染dom完成、异步请求、操作dom

beforeUpdate 	重新渲染之前

updated   		数据更新等操作控制dom重新渲染完成,监控数据变化,进一步操作dom(聊天回顶部,订单图表)

beforeDestroy 	销毁之前

destroyed 		销毁完成,清除非vue资源,定时器登录验证码等

父子组件生命周期

挂载:父beforeCreate —> 父created —> 父beforeMount —>子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted
更新:父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated
销毁:父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed

组件通信

父传子props
子传父$emit
兄弟EventBus
状态管理工具vuex
利用ref 获取vue组件对象
利用 this . $parent获取vue组件对象
利用provide、inject
利用v-model
利用插槽

keep-alive

作用:缓存组件不需要重新渲染,多个静态tab切换,提高性能
特性:mounted仅首次触发,destroyed根本不触发
语法:<keep-alive></keep-alive>
生命周期:

  1. activated:缓存组件被激活;
  2. deactivated:离开缓存组件;
  3. errorCaptured: 当子孙组件出错时,会调用这个钩子函数;
    【组件被缓存了,只要访问或卸载就触发,可以触发n次】
    activated应用:加判断是否要重新请求接口
    deactivated应用:代替destroyed清除非vue组件

多个属性:

  1. include:(字符串或正则表达式),只有名称匹配的组件会被缓存。
  2. exclude:(字符串或正则表达式),任何名称匹配的组件都不会被缓存。
  3. max: (数字),最多可以缓存多少组件实例。

对虚拟DOM的理解

虚拟DOM:通过js对象来描述真实的DOM,从而减少回流重绘,提升性能。
通过diff算法,更新DOM数据
Diff算法:用于比较新旧两个虚拟dom之间差异的一种算法
步骤一:用JS对象模拟DOM树;
步骤二:一层一层比较两棵虚拟DOM树的差异(同层级比较);
步骤三:把差异应用到真实的DOM树上;
步骤四:在页面展示;

MVVM、MVC的理解

MVVM
Model代表数据模型(模型),View代表ui组件(视图),ViewModel是view、model的桥梁,数据会绑定到ViewModel并自动将数据渲染到页面,视图变化会通知ViewModel层更新数据。
便于团队协作开发,减少代码冗余。
MVC
将程序划分为M模型、V视图、C控制器,从而便于团队协作开发,减少代码冗余。

MVVM 与 MVC区别:
都是软件开发中常见的开发模式或者开发思想;
MVC后端居多,MVVM前端;
MVC单向通信 ,目的将M和V代码分离;MVVM是双向通信,不需要手动操作DOM.

路由模式

hash、history、abstract
hash/history用于客户端,abstract用户服务端
hash和history的区别:
1、外观:hash有#号,history没有#号
2、刷新:
hash刷新会加载到地址栏对应的页面;
history刷新浏览器会重新发起请求,如果服务器没有匹配的url,就会出现404。
3、原理:
hash通过监听浏览器的 onhashchange() 事件,查找对应的路由规则;
history利用H5新增的 pushState() replaceState() 方法改变url
4、记录:
hash模式只有#号后面的内容被修改才会添加新的记录栈;
history通过pushState() 设置的url与当前url一样也会被记录到历史记录栈中。

$router 和 $route的区别

$router 为VueRouter的实例,是一个全局路由对象,用来操作路由的,包含了路由跳转的方法,钩子函数等。
如: this. $router.push()
$route 为当前路由信息对象(跳转的路由对象),是一个局部的对象,每一个路由都会有一个 $route对象。
如: $route.path 当前路由对象的路径; $route.params 当前参数; $route.name 路由名称; $route.query 路由查询参数

路由钩子函数

  1. 全局的路由钩子函数
    beforeEach(全局前置钩子):在每次每一个路由改变的时候都要执行一遍
    它有三个参数:
    to: route:即将要进入的目标 路由对象;
    from:route:当前导航正要离开的路由;
    next:function:一定要调用该方法来resolve这个钩子。执行效果依赖next方法。
    应用场景:
    1)进行一些页面跳转前的处理,例如跳转到的页面需要进行登录才可以访问时,就会做登录的跳转;
    2)进入页面登录判断、管理员权限判断、浏览器判断;
    afterEach(全局后置钩子)
    beforeEach是在页面加载之前的,而afterEach是在页面加载之后的,所以这些钩子是不会接受next函数,也不会改变导航本身
  2. 单个路由内的钩子函数
    beforeEnter:可以直接在路由配置上直接定义,这些守卫与全局前置守卫的方法参数是一样的
  3. 组件内的路由钩子函数
    beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave
    应用场景:
    1)清除组件中的定时器;
    2)当页面有未关闭的窗口,或未保存的内容时,阻止页面跳转;
    3)保存相关内容到Vuex和Session中。

路由传参方式

vue-router传递参数有两个大类:①编程式的导航 router.push。②声明式的导航 <router-link>

  1. params属性传参
  2. 动态路由方式(路由属性配置传参)
  3. query属性传参(可以解决页面刷新参数消失问题的)

路由原理

基于SPA单页面应用思想,利用BOM API 实现
hash 利用 location对象的hash属性 改变,利用 window对象的onhashchange 监控;
history 利用 history对象的pushState方法 改变,利用 window对象的onpopstate 监控。

路由懒加载原理

vue的 异步组件 结合 (webpack提供的)代码切割功能 实现的
普通导入:import 组件名 from 路径及文件名 打开就触发
动态导入:component: () => import(路径及文件名) 访问才触发

单页应用SPA(single-page application)

SPA是一种特殊的web应用。将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript和CSS。 一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是利用JavaScript动态的变换HTML的内容, 从而实现UI与用户的交互。实现局部刷新

优点:减少http请求、加快访问速度、提高用户体验度
缺点:

  • 不利于SEO优化(解决:nuxt.js 是基于vue开发的服务端渲染框架 )
  • 首屏加载慢
    解决:静态资源本地缓存;UI框架按需加载;图片资源压缩(雪碧图);避免组件重复打包

vuex

vuex:vue中的状态管理工具、更方便组件通信
构建一个中大型单页应用时考虑使用

五个状态

1、state:所有共享数据统一放到state中,与data类似

2、mutation: 类似于事件,用于改变状态

3、action: 和mutation相似,但是action是异步操作,触发mutation改变状态

4、getter: 类似vue中的computed,进行缓存,对Store中的数据进行加工处理形成新的数据

5、modules: 分模块,大型项目一个对象管理会非常臃肿,难以维护

axios怎么封装

1.导入axios模块

2.创建request 实例 
	const request=axios.create({
			baseURL='  ',
			timeout: 
	})

3.请求拦截器:网页顶部加载进度条、token、content-type

4.响应拦截器:response.data,关闭loading

5.导出request 实例    export default request

axios配置

axios怎么配置

//1.基础配置config,
import axios from "axios";

let http = axios.create({
  baseURL: "/api", //基础地址
  timeout: 1000 * 10, //超时设置
  withCredentials: true, //是否携带凭证进行数据交换
});
//2.接口封装api,
import axios from "./config";

export const loginApi = (username, password) =>
  axios.post("/api/users/login", {
    username,
    password,
  });

export const verifyCaptchaApi = (captcha) =>
  axios.get("/api/users/verifyCaptcha", {
    params: {
      captcha,
    },
  });
......
//3.axios拦截配置

axios拦截请求

//拦截的目的,就是为了给每个请求都添加相同的请求头
//也是简单的安全防御方法,防止用户调取接口私自请求
http.interceptors.request.use((config) => {
  //config就是拦截的每一个请求
  //除了登入和获取验证码以外,其它的请求都带上 authorization这个请求头,值是token
  let token = localStorage.getItem("my-token");
  let pathList = ["/user/login", "/users/getCaptcha"]; //不需要加请求头的路径清单
  //config.url就是拦截到的请求地址
  let result = pathList.includes(config.url);
  if (!result) {
    config.headers.authorization = token;
  }
  //只要return config就相当于放行
  return config;
}); 

axios拦截响应

//拦截响应
//token校验失败的原因 token的周期(5min左右)
//token校验失败,我们就要让页面跳转到登入页
http.interceptors.response.use((config) => {
  //如果响应的数据中,code===1004或者10022的时候,表示登入过期了,或者token验证失败,那么就需要跳转到登入页,并且提示用户登入过期
  if (config.data.code === "1004" || config.data.code === "10022") {
    //跳转到登入页
    router.push("/login");
    el.Message.error("登入信息过期,请重新登入");
    //清除token
    localStorage.removeItem("my-token");
  }
  return config;
});

webpack有哪些loader、plugins

1.常见的loader

file-loader:打包图片,打包字体图标

url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(提升网页性能)

css-loader:处理CSS文件

style-loader:将css文件通过css-loader处理之后,将处理之后的内容插入到HTML的HEAD代码中。

scss-loader:自动将scss转换为CSS

less-loader:自动将less转换为CSS

eslint-loader:检查常见的 JavaScript 代码错误,也可以进行"代码规范"检查

vue-loader:

2.常见的plugins

HtmlWebpackPlugin:会在打包结束之后自动创建一个index.html, 并将打包好的JS自动引入到这个文件中。

copy-webpack-plugin:打包相关的文档

mini-css-extract-plugin:门用于将打包的CSS内容提取到单独文件的插件

terser-webpack-plugin:压缩js代码

optimize-css-assets-webpack-plugin:压缩css代码

image-webpack-loader或img-loader:压缩图片

babel:将ES678高级语法转换为ES5低级语法

babel-preset-env:解决兼容哪些浏览器

gulp和webpack区别

Gulp:侧重于开发整个过程的控制管理

Webpack:更侧重于模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值