------------vue2 部分面试题--------#
(1)防抖:就是将一段时间内连续的多次触发转化为一次触发。
(2)节流:减少一段时间内触发的频率
区别:两者区别在于函数节流是固定时间做某一件事,比如每隔1秒发一次请求。而函数防抖是在频繁触发后,只执行一次(两者的前提都是频繁触发)
场景:
(1)节流:一般是onrize,onscroll等这些频繁触发的函数,比如你想获取滚动条的位置,然后执行下一步动作;鼠标不断点击触发,mousedown(单位时间内只触发一次)…
(2)防抖:频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器;search搜索联想,用户在不断输入值时…
一.生命周期
1.什么是生命周期函数
生命周期函数 又叫钩子函数 是到了某一个时间点会自动触发 我们讨论的是 vue 实例的钩子函数 从 vue 实例创建到销毁的过程中 到了一定的时间节点就会触发
1.1 生命周期函数有哪些
创建阶段
-
beforeCreate 实例创建之前 这个时候什么都没有 data methods 都不能用 也没有 this
-
created 创建之后 也是最早的可以使用 data 和 methods 的钩子函数 这个时候有 this 了
-
beforeMount 组件挂载之前
-
mounted 组件挂载之后 这个时候能拿到 dom 节点使用
运行阶段 只要修改 data 就会触发
-
beforeUpdate 数据变了 视图还没变
-
updated 数据变了 视图也变了
销毁阶段
-
beforeDestory 组件销毁之前 是最后一个能使用 data 和 methods 的钩子函数
-
destoryed 组件销毁之后
除了这八个 还有 三个 如果用 keep-alive 缓存了组件 就会有 actived deactived 这两个钩子函数 activated 组件激活 deactivated 组件停用 errorCaptured 子组件出错的时候会触发这个钩子函数
1.2 项目开发中 在生命周期里都做过什么功能
我在写效果的过程中 会在 created 或者 mounted 中发送 http 请求
created 和 mounted 的区别 就是 created 比 mounted 执行的时间更早所以会更多的在 created 中请求 mounted 的特点是可以操作 dom 节点
还会用 created 钩子函数 获取 本地存储的数据
1.3 ⻚⾯第⼀次加载时⽗⼦组件⽣命周期执⾏的顺序是什么?
自己试一试 把顺序写一下
页面—beforeCreate
页面—created
页面—beforeMount
组件—beforeCreate
组件—created
组件—beforeMount
组件—mounted
页面—mounted
二.vuex 的理解
vuex 是 vue 的状态管理工具 管理项目中的公共数据 能够在所有的组件中使用 一共有五大核心 state 存放公共数据的地方 通过 this.$store.state.xxx调用 mutations 修改 state 的地方 只有这里能修改 通过this.$store.commit 调用 getters 相当于是之前的计算属性 通过 this.$store.getters 调用 actions 执行异步操作的地方 通过 this.$store.dispatch 调用 modules 模块化
vuex 缺点就是刷新数据会丢失 我们可以保存本地存储 或者 安装 vuex 持久化插件 vuex-persist 去实现自动本地存储
2.1vuex 的执行机制
我在项⽬当中如果要改变 state 的状态,我们⼀般是在组件⾥⾯调⽤ this.$store.dispatch ⽅式来触发 actions ⾥⾯的⽅法,在 actions ⾥⾯的⽅法通过 commit 来调⽤ mutations ⾥⾯定义的⽅法来改变 state,同时这也是 vuex 的执⾏机制
2.2 怎么开启严格模式
strict: true, 跟 state 同级的地方设置这个属性 开启完严格模式后 如果不是通过 mutation 修改的 state 就会报错 strict 严格模式只适合开启在开发环境下
2.3 modules
把仓库里的数据分模块管理
每个模块里又有四个核心 state mutations getters actions
然后引入仓库 并且在 modules 下注册模块 在定义的 modules 里开启一个命名 namespaced:true
export default { computed: { arr() { return this.$store.state.a.arr; //使用 模块a里的state数据arr }, }, methods: { add() { this.$store.commit("a/add"); //调用a下面的add方法 }, }, };
三.路由的模式 以及原理 区别
⾯试官您好,接下来我给您介绍⼀下 vue 的路由模式,vue 的路由模式⼀共有两种,分别是哈希和 history.他们的区别是 hash 模式不会包含在 http 请求当中,并且 hash 不会重新加载⻚⾯,⽽使⽤ history 模式的话,如果前端的 url 和后端发起请求的 url 不⼀致的话,会报 404 错误,所以使⽤ history 模块的话我们需要和后端进⾏配合. history 的原理就是利⽤ ht
四.导航守卫
路由的导航守卫 又叫做路由的钩子函数(生命周期函数) 就是在跳转页面的 时候把 路由拦下来 做一些操作 再放行 一共有三种
第一种是全局守卫 beforeEach 路由进入之前 afterEach 路由进入之后
第二种 组件内守卫 beforeRouteEnter 路由进入之前 beforeRouteUpdate 路由更新之前 beforeRouteLeave 路由离开之前
第三种 独享守卫 beforeEnter 路由进入之前
有三个参数 to from next next 这个参数 在路由 3.x 版本的时候 是必须的 但是到了路由 4.x 版本的时候 next 参数变成可选的了
一般来说 vue2 搭配 3.x 的路由 vue3 搭配 4.x 的路由
比如说 购物车页面只有登陆的才能访问 我们可以用组件级守卫守卫购物车页面 如果已经登陆存的有 token 的话 就继续访问这个页面 如果没有登陆的话就会跳转到登陆页面
beforeRouteEnter(to, from, next) { if (localStorage.getItem("token")) { next(); } else { next("/login"); }
next 参数 除了括号里可以是空和路径之外 还可以是一个回调函数(回调函数就是一个被作为参数传递的函数) 比如说 token 被存进 vuex 里就能这么写:
beforeRouteEnter(to, from, next) { // if (localStorage.getItem("token")) { // next(); // } else { // next("/login"); // } next((vm) => { // vm就是 这个组件实例 就是this if (vm.$store.state.token) { next(); } else { next("/login"); } }); },
五.methods computed watch
5.1 methods 就是方法 我们写的点击事件等各种事件都放在 methods 里
5.2 计算属性 computed 计算属性 有缓存功能就是当跟他有关的值发生变化的时候才会重新计算 还有一个特点就是必须要有 return 值 return 就是把计算的结果 return 出去
5.3 watch watch 可以监听 数据和路由的变化
watch 监听路由的变化 监听路由的话就是监听 $router
watch: { $route: { handler(newval, oldval) { console.log(newval, oldval); }, }, },
watch 监听 数据的变化 watch 有三个参数 deep immediate handler 当我们不需要 deep 和 immediate 的时候 就可以简写为一个函数 这个函数就是 handler
watch: { num: { deep: true, //深度监听 immediate: true, //进入页面立刻监听 handler(newval) { console.log(newval); }, //执行函数 参数是newval 和 oldval }, // num() {}, // 之前写的只有一个函数的情况 是handler的简写 不需要 deep 和 immediate的时候可以简写 },
六.组件通信
父传子
首先在使用子组件的标签上 通过自定义属性传递变量 在子组件中 通过 props 接受 在接收的时候有两种接收方式 数组形式 和 对象形式 对象形式可以规定传来的变量的数据类型(type)默认值(default)以及是否必填(required)
子传父
首先在使用子组件的标签上定义一个自定义事件 在子组件里通过 this.$emit 去调用这个自定义事件 $emit 方法的第一个参数是自定义事件的名字 第二个参数是就是子组件要传递给父组件的变量 最后在父组件接收使用就可以了
兄弟组件 利用中央事件总线 eventbus
在 main.js 中 把一个空的 vue 实例挂载在 vue 的原型上起名叫$bus 传数据的时候用this.$bus.$emit传 在要接受数据的子组件 在 created钩子函数中 用$on 方法接收
这是暂时给大家总结的三种 后期还有 另外几种扩展的 后边再总结
七.nextTick
在 dom 更新之后执行的延迟回调 因为 vue 的 dom 更新是异步的 所以 当 dom 还未更新的时候我们无法拿到最新的 dom 来用 放在 nextTick 里的代码 就会在 dom 更新之后执行 就能拿到最新的 dom 来用了
八.常用的修饰符
.trim 去除⾸尾多余的空格 .stop 阻⽌事件冒泡 .once 只渲染⼀次 .self 事件只作⽤在元素本身 .number 将值转化为 number 类型 .capter 组件之间捕获 .prevent 阻⽌元素的默认⾏为 .native 事件穿透,让我们可以在⾃定义组件上触发原生的事件
九.keep-alive
keep-alive 是 vue 内置的⼀个组件,⽽这个组件的作⽤就是能够缓存不活动的组件,我们能够知道,⼀般情况下,组件进⾏切 换的时候,默认会进⾏销毁,如果有需求,某个组件切换后不进⾏销毁,⽽是保存之前的状态,⽐如说刚刚填好的表单数 据。那么就可以利⽤ keep-alive 来实现 被缓存的组件 切换的时候不会触发创建和销毁的钩子函数 而是会触发跟 keep-alive 相关的 activated(激活) deactivated(停用)这两个钩子函数
keep-alive 标签 有 include 属性和 exclude 属性 include 属性 定义了要缓存谁 exclude 属性 定义了不缓存谁 还可以利用 路由的 meta 信息去规定缓存谁不缓存谁
我在写项目的过程中 可以使用 keep-alive 缓存刚刚填好的表单数据 还可以记录页面滚动条的距离,离开再回来滚动条还在这个位置
十.过滤器 filter
所谓的 vue 过滤器就是将数据进⾏⼆次处理,得到我们想要的结果数据 vue 的过滤器分为两种,第⼀种是全局过滤器,通过 vue.filter 来进⾏定义,第⼆种是局部过滤器,需要定义在组件内部,用 filters 过滤 项⽬中我们通过过滤器将后台返回的状态 0 和 1 转化为⽀付或者未⽀付 还有对时间格式进行过滤
vue3 中没有过滤器了
十一.插槽
⾸先呢,所谓的插槽就是⼀个占位符,将⾃定义组件的内容展示出来.我们知道⾃定义的组件⾥⾯如果写内容的话,⻚⾯是不会显 示出来的,如果我们想让⾃定义组件⾥⾯的内容显示出来,我们就需要使⽤ slot 的插槽. ⽽插槽分别具名插槽和匿名插槽、以及作⽤域插槽. 我们⽤的⽐较多的具名插槽和匿名插槽,具名插槽需要所有 slot 标签上指定 name 属性,⽽在对应标签上添加# 属性指定名字. 在项⽬中我们⼀般在进⾏组件封装的时候会使⽤插槽,以上就是我对插槽的理解.
作用域插槽 是把子组件里的数据传到父组件的插槽里使用
十二.跨域
什么是跨域 跨域是浏览器的跨域 不符合 域名 协议 端口号一样(同源策略) 的请求都会出现跨域的问题 跨域的解决方法 最多的情况是后端处理跨域 前端的跨域 服务器代理 jsonp vue 中是 proxy 代理实现跨域
vue 的跨域 用 proxy 实现
十三.axios 封装
-
先创建 utils 文件夹
-
创建 request.js
-
引入 axios
-
配置 基本路径和超时时间
-
配置请求拦截和响应拦截
-
在请求拦截里可以放 loading 和 token
-
在响应拦截中 可以 清除 loading 还有处理错误编码字典
-
最后把我们封装的 axios 实例 导出
十四.axios 拦截器
拦截器有两种 一个是请求拦截一个是响应拦截 拦截器不需要手动调用而是每次发送 http 请求的时候都会自动触发 我们一般在请求拦截中 放全局的 loading 和 token 在响应拦截中关闭全局的 loading 和对 token 进行过期处理 还可以处理错误编码字典
十五.说⼀下 vue 和 jquery 的区别
⾸先呢 jquery 他是⽤ js 封装的⼀个类库,主要是为了⽅便操作 dom 元素,⽽ vue 他是⼀个框架,并且呢,他会从真实 dom 构建出⼀个 虚拟的 dom 树,通过 di!算法渲染只发⽣改变的 dom 元素,其他的相同的 dom 元素不⽤在重新渲染. ⽽使⽤ jquery 去改变 dom 元素 的时候,即使有相同的 dom 元素也会重新渲染, jq 重点操作 dom,而 vue 重点操作数据。以上就是我对 vue 和 jquery 区别的理解.
十六.vue 中 data 发⽣变化,视图不更新如何解决?(必问) 过⼀下
在 vue2 中 vue 实例的 data 数据是响应式 的 就是数据变了 视图也会跟着变,如果给某一个 data 新添加了一个字段 这个新添加的字段因为 js 的限制不响应,需要使用 this.$set 方法代替原本的普通添加方法 就能实现响应,这个方法的三个参数 是给谁添加 添加的字段 初始值 如果不是在组件中 用这个方法 那么就用 Vue.set
在 vue3 中数据响应的原理从 definedproperty 变成了 proxy 所以不会存在数据变了视图不变的问题
十七.mvvm 代表框架是 vue mvc 代表框架是 jq 和 react
-
说⼀下什么是 mvvm 模式?(70%) MVVM 是把 MVC 的 Controller 和 MVP 的 Presenter 改成了 ViewModel 。 View 的变化会⾃动更新到 ViewModel , ViewModel 的变化也会⾃动同步到 View 上显示。这种⾃动 同步是因为 ViewModel 中的属性实现了 Observer ,当属性变更时都能触发对应的操作
2.MVVM模式的优点以及与MVC模式的区别?
MVVM 模式的优点: 1、低耦合: 视图(View)可以独⽴于 Model 变化和修改,⼀个 ViewModel 可以绑定到不同的"View"上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候 View 也可以不变。 2、可重⽤性: 你可以把⼀些视图逻辑放在⼀个 ViewModel ⾥⾯,让很多 view 重⽤这段视图逻辑。 3、独⽴开发: 开发⼈员可以专注于业务逻辑和数据的开发(ViewModel),设计⼈员可以专注于⻚⾯设计。 4、可测试: 界⾯素来是⽐较难于测试的,⽽现在测试可以针对 ViewModel 来写。 MVVM 和 MVC 的区别: mvc 和 mvvm 其实区别并不⼤。都是⼀种设计思想。 主要区别 mvc 中 Controller 演变成 mvvm 中的 viewModel, mvvm 通过数据来显示视图层⽽不是节点操作。 mvvm 主要解决了: mvc 中⼤量的 DOM 操作使⻚⾯渲染性能降低,加载速度变慢,影响⽤户体验。
十八.虚拟 dom
虚拟 dom 是利用 js 描述元素与元素的关系,用 js 对象来表示真实的 DO