目录
目录
1、你认为vue的核心是什么
1.数据驱动,也就是数据的双向绑定,让视图(DOM)的内容随着数据的改变而改变
2.组件化系统,可实现拓展HTML元素,封装可用的代码
2、什么是组件化?组件化的好处是什么
1.是什么
- 将一个页面拆分成一个个的小组件的过程,每个小组件都有自己html css js
2.在vue中每个.vue文件都可以视为一个组件
3.组件化的优势:
- 便于维护,由于每个组件的职责单一,降低整个系统的耦合度
- 便于维护,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求
- 方便调试,由于整个系统是通过组件组合起来的,再出现问题的时候,可以排除法直接移除组件,或者根据报错的组件快速定位问题,之所以能够快速定位,是因为每个组件之间低耦合,职责单一,所以逻辑会比分析整个系统要简单。
3、怎么理解mvvm这种设计模式
1.是什么
Model-View-ViewModel(MVVM)是一个软件架构设计模式,是一种简化用户界面的事件驱动编程方式
2.设计思想
- Model 模型 指的是数据层
- View 视图 指的是用户页面
- ViewModel 视图模型
视图模型是MVVM模式的核心。它是连接view和model的桥梁,MVVM实现了view和model的自动同步,当model的属性改变时,我们不用自己手动操作DOM元素,来改变view的显示,反之亦然,我们称之为数据的双向绑定
4、组件中的data为什么是函数而不是一个对象
1.组件时用来复用的,组件中的data写成一个函数,数据以函数返回值形式定义,函数有独立的作用域,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。
2.而单纯写成对象形式,由于对象是引用类型,就使得所有的组件实例公用了一个data,就会造成一个变全都变的结果。
5、v-if和v-show的区别,使用场景的区别
1.是什么
- 它们都是vue的指令,用来控制标签元素的显示和隐藏的方法
2.区别
- v-if在条件切换的时候,会对标签进行适当的创建和销毁,而v-show仅在页面初始化的时候加载一次
- v-if是惰性的,只有条件为真时才会真正的渲染标签,条件不为真则不会渲染标签,而v-show无论条件是否为真都会渲染标签,它仅仅只做简单的display切换
3.使用场景
- v-if 适用于不需要频繁切换元素显示和隐藏的情况
- v-show 适用于频繁切换元素显示和隐藏的情况
6、v-for中为什么要加key
1.好处
- key的作用主要为了高效的跟新虚拟DOM,提高渲染性能
- key属性可以避免数据混乱的情况出现
2.原理
- vue实现了一套虚拟DOM,使我们可以不直接操作DOM元素只操作数据,就可以重新渲染页面,它背后的原理是高效的Diff算法;
- 当页面数据发生改变时,Diff算法只会比较同一层级的节点;
- 如果节点类型不同,直接干掉前面的子节点,在创建并插入新的节点,不会比较这个节点后面的子节点;
- 如果节点类型相同,则会重新设置该节点属性,从而实现节点更新;
- 使用key给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,就地更新从而找到正确的位置插入新的节点。
7、computed和watch的区别是什么
计算属性computed:
1.支持缓存,只有当依赖数据发送改变,才会重新进行计算;
2.不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3.如果computed需要对数据修改,需要写get和set两个方法,当数据变化时,调用set方法
4.computed擅长处理的场景:一个数据受多个数据的影响;
侦听属性watch:
1.不支持缓存,数据变,直接会触发相应的操作;
2.watch支持异步 监听的函数接收两个参数,第一个参数是新的值 ,第二个参数是输入之前的值
3.immediate:组件加载立即触发回调函数执行;
4.deep:true的意思就是深入监听,任何修改obj里面任何一个属性都会触发这个监听器的handler方法来处理逻辑;
5.watch擅长处理的场景:一个数据影响多个数据
8、怎么理解vue中的虚拟DOM
1.是什么
- 用js对象模拟真实DOM树,对真实DOM进行抽象
2.原理
- diff 算法——比较俩个虚拟DOM树的差异
- pach 算法——将两个虚拟DOM对象的差异应用到真正的DOM树
3.好处
- 性能优化
- 无需手动操作DOM
- 可以跨平台,服务端渲染等
9、怎么理解vue的生命周期
1.是什么
vue的生命周期:vue实例从创建到销毁的全过程
2.声明周期3个阶段
- 第一个阶段:初始化阶段(挂载)创建vue实例,准备数据,准备模板,渲染视图
- 第二个阶段:数据跟新阶段 当数据发送变化时,会进行新旧DOM的对比,对比出差异的部分,进行差异化更新
- 第三个阶段:实例销毁阶段 当vm.$destroy被调用,vue实例就会被销毁,释放相关资源,此时在更新数据,视图不会再发出变化;
10、vue 钩子函数有哪些,有哪些使用的场景
1.初始化阶段:
- beforeCreate 在data数据注入到vm实例之间,此时vm身上没有数据;
- created 在data数据租入2到实例之前,此时vm身上有数据
- beroreMount 生成结构替换视图之前,此时DOM还没更新
- mounted 生成的结构替换视图之前,此时DOM已经更新完成
2.数据更新阶段
- beforeUpdate 数据变化了,dom更新之前
- updated 数据变化了,dom更新之后
3.组件销毁阶段
- beforeDestroy 实例销毁,是否资源之前
- destroyed 实例销毁,是否资源之后
- 这些钩子函数会在vue的生命周期的不同阶段,自动被vue调用
2.常用的钩子函数使用场景
- beforeCreate 做loading的一些渲染
- created 结束loading,发送数据的请求,拿数据
- mounted 可以对dom进行操作,使用ref和 this.$refs.xxx
10、Vue的父组件和子组件生命周期钩子函数执行顺序
Vue 的父组件和子组件生命周期钩子函数执行顺序可以归为以下4部分:
1.加载渲染过程
- 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
2. 子组件更新过程
- 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
3. 父组件更新过程
- 父 beforeUpdate -> 父 updated
4. 销毁过程
- 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
11、vue组件传值的方式
1.父传子:
- 通过props传递
- 父组件:<child :list="list"/>
- 子组件:props[''list''],接收数据,接收之后使用和data中定义数据方式一样;
2.子传父
- 父组件给组件绑定一个自定义的事件,子组件通过$emit()触发该事件并传值
- 父组件:<child @receive = 'getData' />
getData(value){value就是接受的值}
- 子组件:this.$emit('receive',value)
3.兄弟组件传值 => 通过中央通信(事件总线) let bus = new Vue()
- A组件:methods :{
sendData(){
bus.$emit('getData',value)
} 发送
- B组件:created(){
bus.$on(‘getData’,(value)=>{value就是接收的数据})
} 进行数据接收
12.$nextTick是什么?原理是什么
- 背景
- 简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
- 原理
- 简单来说,nextTick是做了promise加上setTimeout的封装,利用事件换行机制,来确保当nextTick出现时,都是在我们所有操作DOM更新之后的。
- 场景:
4.1. 点击获取元素宽度
4.2. 使用swiper插件通过 ajax 请求图片后的滑动问题
4.3. 点击按钮显示原本以 v-show = false 隐藏起来的输入框,并获取焦点
13.谈谈你对 keep-alive 的了解
- 是什么
- keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染, 一般结合路由和动态组件一起使用,用于缓存组件
- 具体使用
2.1. 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated
2.2. 提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高
例如: <keep-alive include="a"> <component> <!-- name 为 a 的组件将被缓存! --> </component> </keep-alive> <keep-alive exclude="a"> <component> <!-- 除了 name 为 a 的组件都将被缓存! --> </component> </keep-alive>
14.谈谈你对slot的了解
- 是什么
- 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
- 插槽使用
- 插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
2.1. 默认插槽 => 在子组件中写入slot,slot所在的位置就是父组件要显示的内容
2.2. 具名插槽 => 在子组件中定义了三个slot标签,其中有两个分别添加了name属性
=> 在父组件中使用template并写入对应的slot名字来指定该内容
2.3. 作用域插槽 => 在子组件的slot标签上绑定需要的值<slot :data="user"></slot>
=> 在父组件上使用slot-scope=“user”来接收子组件传过来的值
15.v-model的原理是什么(双向数据绑定原理)
- 是什么
- 视图中的数据和模型中的数据相互关联
- v-model理解
- v-model主要提供了两个功能,view层输入值影响data的属性值,属性值发生改变会更新层的数值变化.
- v-model指令的实现:
2.1. v-bind:绑定响应式数据
2.2. 触发input事件并传递数据 (核心和重点)
- 底层原理(双向数据绑定/响应式原理)
- Vue 的响应式原理是核心是通过 ES5 的 Object.defindeProperty 进行数据劫持,然后利用 get 和 set 方法进行获取和设置,data 中声明的属性都被添加到了get和set中,当读取 data 中的数据时自动调用 get 方法,当修改 data 中的数据时,自动调用 set 方法,检测到数据的变化,会通知观察者 Wacher,观察者 Wacher自动触发重新render 当前组件(子组件不会重新渲染),生成新的虚拟 DOM 树,Vue 框架会遍历并对比新虚拟 DOM 树和旧虚拟 DOM 树中每个节点的差别,并记录下来,最后,加载操作,将所有记录的不同点,局部修改到真实 DOM 树上。
16.vue2.0和vue3.0响应式的区别
- Object.defineProperty
- 用于监听对象的数据变化
- 无法监听数组变化(下标,长度)
- 只能劫持对象的自身属性,动态添加的劫持不到
- Proxy
- proxy返回的是一个新对象, 可以通过操作返回的新的对象达到目的
- 可以监听到数组变化,也可以监听到动态添
17.你都做过哪些Vue项目上的性能优化
- v-if和v-for不能连用
- 页面采用keep-alive缓存组件
- 合理使用v-if和v-show
- key保证唯一
- 使用路由懒加载、异步组件、组件封装
- 防抖、节流
- 第三方模块按需导入
- 图片懒加载
- 精灵图的使用
- 代码压缩
- 加的数据
18.路由传参和获取方式的区别
- 方式:params 和 query
- 区别
- params用的是name,传递的参数在地址栏不会显示,类似于post
- query用的是path, 传递的参数会在地址栏显示出来,类似于get
- 获取路由传值
- this.$rotue.query.xx
- this.$rotue.params.xx
关联知识点 => 路由守卫
在 Vue Router 中,有三种类型的导航守卫方法可以使用:
- 全局守卫:beforeEach 和 afterEach
- 独享路由守卫:beforeEnter
- 组件内路由守卫:beforeRouteEnter、beforeRouteUpdate 和 beforeRouteLeave
导航守卫的执行顺序如下:
全局前置守卫 -> 路由独享守卫 -> 组件内守卫 -> 全局后置守卫
19.Vuex 是什么?有哪几种属性?
- 是什么
- Vuex 是专为Vue设计的状态管理工具,采用集中式储存管理 Vue 中所有组件的状态。
- 属性
- state属性:初始数据
- getters属性:从 state 中派生出的数据
- mutation属性:更新 store 中数据的唯一途径,其接收一个以 state 为第一参数的回调函数
- action 属性:提交 mutation 以更改 state,其中可以包含异步操作,数据请求
- module 属性:用于将 store分割成不同的模块。
- 遇到问题
- 数据在页面刷新后就会丢失, 一般配合本地存储使用
- 项目使用
- 用来存储token令牌等等