Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

部分Vue2基础题 #26

Open
yihan12 opened this issue Jan 2, 2024 · 0 comments
Open

部分Vue2基础题 #26

yihan12 opened this issue Jan 2, 2024 · 0 comments
Labels

Comments

@yihan12
Copy link
Owner

yihan12 commented Jan 2, 2024

Vue

Vue 借鉴了 angular 的模板和数据绑定技术;又借鉴了 react 的组件化和虚拟 DOM 技术

前言

面试前的临时抱佛脚,也能系统的梳理下所掌握的知识。

面试题

1.vue 的生命周期,生命周期的理解。

答案:

创建=>挂载=>更新=>销毁(也就是我们常说的八个阶段创建前/后挂载前/后更新前/后销毁前/后)。

含义:Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载 Dom===>渲染、更新===>渲染销毁等一系列过程,称之为 Vue 的生命周期。

作用:Vue 的生命周期有多个事件钩子,让我们在控制整个 Vue 实例的过程时更容易形成好的逻辑。

第一次页面加载会触发的钩子函数:beforeCreatecreatedbeforeMountmounted

Dom 渲染在哪个周期就已经完成:mounted

Vue 的页面请求一般放在哪个生命周期:createdmounted(区别:mounted 周期中 Dom 已经渲染完成,再去请求数据,就会有空壳 Dom 的情况,会影响布局;而 created 周期中操作 Dom 节点会找不到 Dom)。

如下图(vue 生命周期官网):
vue生命周期

上图理解:
首先需要我们去执行一个实例new Vue(),首先执行了 init(init 是 vue 组件默认去执行的),这时是事件和生命钩子的初始化(Init Events&Lifecycle);
在实例初始化之后(Init Events&Lifecycle)调用了 beforeCreate,此时事件已经好了,也能开始生命周期了(读取配置项,加载生命周期的方法)。

说明:这个时候 this 不能使用,data 中的数据、methods 的方法,以及 watcher 中的事件都不能获得

接着初始化 inject、provide、state 属性(设置 data、methods、computed...等配置项),也就是Init injections(注射)&reactivity(反应性)。在实例调用完成后他会立即调用 created。在这一步,实例已经完成以下配置:数据观测(data observer)、属性和方法的运算、watch/event 事件回调;然而挂载阶段还没开始,$el 属性目前不可见。所以在 init 的时候,事件已经调用了,因此在 beforeCreate 的时候不要修改 data 里面赋值的数据,最早也要在 created 里面做(添加一些行为)。

说明:created 这个时候可以操作 vue 中的数据和方法,但是还不能对 dom 节点进行操作

当 created 完成之后,它会去判断,instance(实例)里面是否含有 el 对象has 'el' option。如果没有的话,它就会挂载when vm.$mounted(el) is called,然后走下一步,判断是否有模板has 'template' option;如果有的话,他就会直接跳到下一步,判断是否有模板has 'template' option
如果有模板'template',就会把 template 解析成一个 render function。通过 render 函数去渲染创建 Dom 树compile template into render function;如果没有模板'template',就编译 el 对象外层 html 作为模板compile el's outerHtml as template
beforeMount 再有了 render 函数的时候才会执行,此时$el 和 data 都初始化了,但是在挂载前为虚拟的 Dom 节点。

说明:$el 属性已经存在,是虚拟 Dom,只是数据未挂载到模板中

然后继续执行 render 函数,当执行完 render 函数之后,也就是 el 被新创建的 vm.$el替换Create vm.$el and replace 'el' with it,并且挂载到实例上去之后就会调用 mounted 这个钩子。
在 mounted 挂载完成,dom 树已经完成渲染到页面,可进行 dom 操作。但是它不会承诺所有的子组件也都一起被挂载,如果希望等到整个视图都渲染完毕,可以用 vm.$nextTick()。

说明:挂载完毕,这时 Dom 节点被渲染到文档内,dom 操作在此时能正常进行

当数据有更新,就会调用 beforeUpdate,然后虚拟 dom 重新渲染补丁,以最小 dom 开支来重新渲染 domVirtual Dom re-render and patch

说明:beforeUpdate 是指 view 层的数据变化前,不是 data 中数据改变前触发,因为 Vue 是数据驱动的。这里适合在更新之前访问现有 Dom,比如手动移除已添加的事件监听器

然后就是 updated 执行。由于数据更改导致的虚拟 Dom 重新渲染和打补丁,在这之后会调用该钩子。当该钩子被调用时,组件 Dom 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况,应该避免在此期间更改状态。如果要更改相应状态,最好使用计算属性或 watcher 取而代之。

注意:updated 不会承诺所有的子组件也都会被重构。如果你希望整个视图都重绘完毕,可以用 vm.$nectTick()替换掉 uopdated
说明: view 层的数据更新后,data 中的数据通 beforeUpdate,都是更新完以后的。

beforeDestroy:实例在销毁之前调用,在这还能访问实例的数据when vm.$destory() is called
当组件销毁时,beforeDestroy 执行,清除 watcher、子组件、事件监听器等Teardown watchers,child components and event listeners

说明:实例在组件销毁之前调用,在这一步,实例完全可用

destroyed:Vue 实例销毁后调用,调用后,Vue 实例指示的所有东西会解绑,所有事件监听器会被移除,所有子实例也会被销毁。

说明:执行 destroy 方法后,对 data 改变不会触发周期函数,此时,Vue 实例已经解除事件监听和 dom 绑定,但是 Dom 结构依然存在


2.MVVM 和 MVC 的区别

答案:

mvc 和 mvvm 其实区别并不大,都是一种设计思想。主要是 mvc 的 controller 演变成 mvvm 的 viewModel。mvvm 主要解决了 mvc 中的大量的 Dom 操作是页面的渲染性能降低,加载速度变慢,影响用户体验。和当 model 频繁发生变化,开发者需要主动更新到 view。


3.vue 的优点是什么

答案:

  • 1.低耦合:视图View可以独立Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 2.可重用性:可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
  • 3.独立开发:开发人员可以专注于业务逻辑和数据开发ViewModel,设计人员可以专注于页面设计,使用 Expression Blend 可以容易设计界面并生成 xml 代码。
  • 4.可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。


4.vue 组件间的参数传递

答案:

  • 父组件与子组件传值:

    父组件传给子组件:子组件通过props方法接收数据;
    子组件传给父组件:$emit方法传递。

  • 兄弟组件间传值:

    eventBus:就是创建一个实践中心,相当于中转站,可以用它来传递事件和接收事件;
    vuex:适合比较大项目,具体看需求。


5.vue 路由的实现:Hash 模式和 History 模式

答案:

  • Hash 模式:是一种把前路由的路径用井号#拼接在真实 URL 后面的模式。当#后面的路径发生变化时,浏览器不会重新发起请求,而是会触发haschange事件。
    特点:hash 虽然在 URL 中,但是不被包括在 HTTP 请求中;用来指导浏览器动作,对服务端的安全无用,hash 不会重加载页面;可以为hash的改变添加监听事件。
    优点:浏览器的兼容性比较好,支持 IE8。
    缺点:路径在井号#后面,比较丑。
    读取:window.location.hash
  • History 模式:history 采用 HTML5 的新特性;且提供两个方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件监听到状态变更。
    监听 popState 事件,该事件能监听到:用户点击浏览器前进后退的动作;手动调用 history 的back,forwardgo方法。不能监听到:history 的pushState()replaceState()
    优点:理解比较正规,没有井号。
    缺点:兼容性不如 hash,且需要服务器支持,否则一刷新就 404 了。


6.vue 路由跳转

答案:

声明式(标签跳转)

<router-link :to="index></router-link>

编程式(js 跳转)

router.push("index");


7.v-if 和 v-show 的区别

答案:

  • v-if:用于条件性渲染一块内容,这块内容只会在指令表达式返回true的时候被渲染。
  • v-showv-show的元素始终会被渲染保留在 DOM 中。v-show只是简单的切换元素 css 的 display。

区别:
1.v-show是 css 显隐切换,v-if 是完整的销毁和重新创建;
2.使用频繁切换的时候用v-show,运行较少改变时用v-if;
3.v-if是条件渲染,当 false 的时候不会渲染,页面也不会有 html 标签生成,v-show则是不管为 true 或者 false,html 元素都存在,只是 css 样式 display 的显隐;
4.当我们需要经常切换某个元素的显隐时,使用v-show更加节省性能,当只需要一次切换时,使用v-if更加合理。


8.computed 和 watch 的区别

答案:

  • computed

computed是计算属性,也就是计算值,更多用于计算值的场景;
具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时重新调用对应的getter来计算;
computed更适用于比较消耗性能的场景。

  • watch

watch更多的是[观察]的作用,类似某些数据的监听回调,用于观察 props 和$emit 或者本组件的值,当数据变化时来执行回调进行后续操作;
无缓存性,页面重新渲染时值不变化也会执行。

小结:

当需要进行数值计算时,而且依赖于其他数据,可以把这个数据设计为computed;
当需要在某个数据变化做一些事情,使用watch来观察这个数据的变化。


9.keep-alive 组件的作用

答案:

<keep-alive></keep-alive>包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重复渲染。

比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情...这样的话列表和详情就会是一个很高频率打开的页面,那么对列表组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染。

  • 常用的两个属性include\exclude允许组件有条件的进行缓存。
  • 两个生命周期activated\deactivated,用来得知当前组件是否处于活跃状态。
  • keep-alive中还运用了LRU(最近最少使用)的算法,选择最近最久未使用的组件予以淘汰。


10.Vue 组件的 data 为什么必须是函数

答案:

vue 组件的 data 值不能为对象,因为对象时引用类型,组件可能会被多个实例引用;
组件中的 data 写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的 data,类似于每个实例创建一个私有的数据空间,让各个组件实例维护各自的数据;
如果 data 值是对象,将导致多个实例共享一个对象,其中一个组件改变 data 的属性值,其他实例也会受到影响。


11.Vue.nextTick 和 vm.$nextTick 的作用

答案:

官方

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

Vue 在更新 DOM 时时异步的,当数据发生变化时,Vue 将开启一个一步更新的队列,视图需要等队列的所有数据变化完成之后,再统一进行更新;

如果我们一直在修改相同的数据,异步操作队列还会去重;

等待同一事件循环的所有数据变化完成之后,会将队列中的事件拿来进行处理,进行 Dom 更新。

如果想在修改数据后立刻得到更新后的 DOM 结构,可以使用Vue.nextTick()

总结:主要思路就是采用微服务优先的方式调用异步方法去执行 nextTick 包装的方法。


12.Vue 指令有哪些,作用

答案:

  • v-if:条件渲染指令。用于条件渲染一块内容,这块内容只能只在表达式返回true时才会被渲染。
    v-show渲染的元素会始终保留在 DOM 中,v-show的切换只是display的显隐。
  • v-for:列表渲染指令。基于数组渲染一个列表。
  • v-bind:属性绑定指令。给标签属性赋值。
    v-text:属性绑定指令。显示原文本。
    v-html:属性绑定指令。以标签内容显示。
  • v-on:事件绑定指令。用来监听 DOM 事件,并在触发时运行一些 js 代码。
    v-on:click
    v-on:keydown
    v-on:mouseover
  • v-model:双向数据绑定指令。给 value 赋值。


13.vue 和 react 的区别

答案:


14.vuex 总结

答案:

vuex 是一种状态管理机制,将全局组件的共享状态抽取出来为一个store,以一个单例的模式存在,应用任何一个组件中都可以使用,vuex 更改state的唯一途径是通过mutation,mutation需要commit触发,action实际触发是mutation,其中mutation处理同步任务,action处理异步任务。

state:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
getter:允许组件从 store 中获取数据,maoGetter 辅助函数仅仅是 store 中 getter 映射到局部计算属性。
mutation:唯一改变 store 状态的方法,且必须是同步函数。
action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
module:允许将单一的 store 拆分成单个 store,且同时保存在单一的状态树中。


15.SPA 单页面理解,优缺点?

答案:

SPA(single-page application)仅在 Web 页面初始化时加载响应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面重新加载。

优点:

  • 用户体验好,快,内容改变不需要重新加载整个页面,避免不必要的跳转和重复渲染;
  • SPA 相对服务器压力小;
  • 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

缺点:

  • 首屏(初次)加载慢:为实现单页 web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;

  • 不利于 SEO:由于所有的内容在一个页面动态替换显示,所以在 SEO 上有着天然的弱势。

  • 前进后退路由管理:由于单页面在一个页面中显示所有的内容,所以不能用浏览器的前进后退功能,所有页面的切换需要进行堆栈处理


16.new Vue()发生了什么?

答案:

  • new Vue()创建 Vue 实例,它内部执行了根实例的初始化过程。
  • 具体包括以下操作:
    选项合并
    $children$refs$slots$createElement等实例的方法初始化
    自定义时间处理
    数据响应式处理
    生命钩子的调用(beforecreate created)
    可能的挂载
  • 总结:new Vue()创建了根实例并准备好数据和方法,未来执行挂载时,此过程还会递归的应用于它的子组件上,最终形成一个有紧密关系的组件实例树。


17.vue 性能优化

答案:

1) 编码阶段:

  • 尽量减少 data 中的数据,data 中的数据都会增加 getter 和 setter,会收集对应的 watcher;
  • 如果需要使用 v-for 给每项元素绑定事件时使用事件代理;
  • SPA 页面采用 keep-alive 缓存组件;
  • 在更多情况下使用 v-if 替代 v-show;
  • key 保证唯一;
  • 使用路由懒加载、异步组件;
  • 防抖节流;
  • 第三方模块按需导入;
  • 长列表滚动到可视区动态加载;
  • 图片懒加载、不在 HTML 里缩放图像、使用雪碧图(CSS sprite)、使用字体图标(iconfont)、使用 WebP;
  • 降低重绘重排的频率和成本;
  • CSS 读写分离,不用 js 操作元素样式;
  1. 用户体验:
  • 骨架屏;
  • PWA;
  • 使用缓存(客户端缓存,服务端缓存,服务端开启 gzip 压缩);

3)SEO 优化:

  • 预渲染;
  • 服务端渲染 SSR;

4)打包优化:

  • 压缩代码(注意:不要对图片文件进行 Gzip 压缩);
  • Tree Shaking/Scope Hoisting;
  • 使用 cdn 加载第三方模块;
  • 多线程打包 happypack;
  • splitChunks 抽离公共组件;
  • sourceaMap 优化


18.vue 的 MVVM

答案:

ViewModel:做了两件事情达到数据绑定,首先将模型转换为视图,即将后台传递的数据转化成所看到的的页面,实现方式数据绑定;二是将视图转化成模型,即将所看的页面转化成后端数据
,实现方式是 DOM 事件监听。
MVC 和 MVVM 最大的区别是:实现了 view 和 model 的自动同步,也就是当 model 属性改变时,我们不需要手动操作 DOM 元素,来改变 view 的显示,而是改变属性后,该属性对应的 view 层会自动改变(对应 vue 数据驱动的思想)
整体看来,MVVM 比 MVC 精简得多,不仅简化了业务与界面的依赖 ,还解决了数据频繁更新的问题,不用再用选择器操作 DOM 元素。因为在 MVVM 中,View 不知道 Model 的存在,View 和 ViewModel 也观察不到 View,这种低耦合模式提高代码的可重用性。


19.为什么官方说 vue 没有完全遵循 MVVM 思想

答案:

严格的 MVVM 要求 View 不能和 Model 直接通信,而 vue 提供了$refs 这个属性,让 Model 可以直接操作 View,违反了这一规定,所以 View 没有完全遵循 MVVM


20.vue 八种组件通信方式

答案:

1.props/$emit

父组件传给子组件:父组件 ':/v-bind',子组件通过props方法接收数据;
子组件传给父组件:$emit方法传递,父组件'@'接受。

2.$children/$parent
指定已创建的实例之父实例,在两者之间建立父子关系,子实例可以用this.$parent访问父实例,子实例被推入父实例的$children 数组中。
this.$parent/this.$children[0]

注意:节制的使用$parent$children-它们的主要目的是作为访问组件的应急方法更推荐propsevents实现父子组件通信。

3.provide/inject
父组件通过provide提供变量,然后子组件通过inject来注入变量,(官方不推荐在实际业务中使用,但是写组件库时很常见)。

4.ref/refs
ref被用来给元素或者子组件注册引用信息,引用信息将会注册在父组件的$refs对象上。如果在普通的 DOM 元素上使用,引用指向 DOM 元素;如果用在子组件上,引用就会指向组件实例。

注意:$refs不是响应式的,因此不应该试图用它在模板中做数据绑定。

5.eventBus
eventBus(又称为事件总线) 兄弟组件数据传递,这种情况下可以使用事件总线的方式。在 vue 中可以使用它来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向事件中心注册发送事件或接收事件,所以组件都可以通知其他组件。

当项目较大时,就容易造成难以维护的灾难。

1)初始化

// event-bus.js
import Vue from "vue";
export const EventBus = new Vue();

2)发送事件

import { EventBus } from "./event-bus.js";

EventBus.$emit("addition", {
  num: this.num++,
});

3)接收事件

import { EventBus } from "./event-bus.js";

EventBus.$on("addition", (param) => {
  this.count = this.count + param.num;
});

4)移除事件监听者

import { EventBus } from "./event-bus.js";

EventBus.$off("addition", {});

6.Vuex
解决了多个视图依赖同一状态来自不同视图的行为需要变更同一状态的问题。

7.localStorage/sessionStorage

8.$attrs$listeners


21.vue 内置指令

答案:

v-text:更新元素的textContent
v-html:更新元素的 innerHTML。容易导致 XSS 攻击,永不在用户提交内容上使用。
v-show:用于切换元素的display来进行显隐。
v-if/v-else/v-else-if:可以配合template使用;当和v-for使用的时候优先级比v-if高。
v-for:基于源数据多次渲染元素或模板块;优先级比v-if高,最好不用一起使用,尽量用计算属性去解决;注意增加唯一 key 值,不要使用 index 作为 key。
v-on:普通元素上用于监听 DOM 事件;缩写@;自定义元素组件上,监听子组件触发的自定义事件。
v-bind:缩写:,用于绑定属性;动态更新 html 元素上的属性。
v-model:在普通标签上,变成 value 和 input 的语法糖,并会处理拼音输入法问题;在组件上,也是处理 value 和 input 语法糖。
v-slot:缩写#;提供具名插槽,或需要接收 prop 的默认插槽。
v-pre:跳过这个元素和子元素的编译过程,以此来加快整个项目的编译速度。
v-cloak:这个指令保持在元素上直到关联实例结束编译--解决初始化慢,导致页面闪动的最佳实践。
v-once:定义它的元素和组件只渲染一次,包括元素组件的所有子节点,首次渲染后,不在随数据变化重新渲染,将被视为静态内容。


22.怎样理解 vue 单向数据流

答案:

所有的prop都使得其父子prop之前都形成了一个单向下行的绑定:数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改。这样会防止子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。


23.vue2.0 响应式原理

答案:

数据劫持+观察者模式

对象内部通过 defineReactive 方法,使用Object.defineProperty将属性进行劫持(只会劫持已存在的属性),数组则是重写数组方法来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存在它所依赖的 watcher(依赖收集),当属性变化后会通知自己对应的 watcher 去更新。

对象的新增或删除属性无法被 set 监听到,只有对象本身存在的属性修改才会被劫持。


24.vue 如何检测数组发生变化

答案:

数组考虑性能原因没有用defineProperty对数组每一项进行拦截,而是对七对数组方法(push,shift,pop,splice,unshift,sort,reverse)进行重写。

所以 vue 修改数组的索引和长度是无法监控的,需要通过以上 7 种变异方法修改数组才会触发数组对应的 watcher 进行更新。


25.vue3.0 部分知识点

答案:

1)响应式原理的改变,Proxy 取代 Object.defineProperty
2)组件选项声明方式 Composition api setup
3)模板语法变化 slot 具名插槽语法,自定义指令 v-moddel 升级
4)支持 Fragment(多根节点)和 Protal 组件


26.vue 父子组件生命钩子函数周期执行顺序

答案:

加载渲染过程:

父 beforeCreate->父 created->父 beforeMount->子 beforecreate->子 created->子 beforeMount->子 mounted->父 mounted。

子组件更新过程:

父 beforeUpdate->子 beforeUpdate->子 updated->父 updated

父组件更新过程:

父 beforeUpdate->父的 updated

销毁过程:

父 beforeDestory->子 beforeDestory->子 destroyed->父 destroyed


27.虚拟 DOM 是什么,有什么优缺点

答案:

由于浏览器操作 DOM 是很昂贵的。频繁操作 DOM 会产生性能问题。

本质是用一个原生的 JS 对象去描述一个 DOM 节点,是真实 DOM 的一层抽象。

优点:
1)保证性能下限:框架的虚拟 DOM 需要适配任何上层 api 可能产生的操作。不需要手动操作 DOM,还能保持不错的性能,保证性能下限。
2)无需手动操作 DOM。我们无需手动操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和数据双向绑定帮我们可预期更新视图,极大提高我们的开发效率。
3)跨平台:虚拟 DOM 本质上是 javascript 对象,而 DOM 与平台强相关,相比之下,虚拟 DOM 可以进行更方便的跨平台操作,例如服务器渲染,weex 开发等等。

缺点:
1)无法进行极致优化,虽然虚拟 DOM+合理的优化,足以应用大部分应用的性能需求,但在一些性能要求极高的应用中,虚拟 DOM 无法针对性的极致优化。
2)首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入慢。


28.v-model 原理

答案:

v-model 只是语法糖而已
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件。

text 和 textarea 使用 value 和 input 事件
checkbox 和 radio 使用 checked 和 change 事件
select 将 value 作为 prop,并将 change 作为事件


29.v-for 为什么要加 key

答案:

如果不使用 key,Vue 会使用最大限度减少动态元素并且尽可能尝试的修改/复用相同类型元素的算法。key 是 vue 中 vnode 的唯一标记,通过这个 key,我们 diff 操作更准确,更快速。

更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key===b.key 对比中可以避免就地复用的情况,所以更加准确。

更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快。


30.vuex 页面刷新数据丢失怎么解决

答案:

需要做 vuex 数据持久化,一般使用本地储存的方案来保存数据,可以自己设计储存方案,也可以使用第三方插件。

推荐使用 vuex-persist 插件,他就是为了 vuex 持久化而生的一个插件,不需要你手动存取 storage,而是将状态保存至 cookie 或者 localstorage 中。


31.vue.set方法原理

答案:

修改vue视图不会发生变化的两种情况:

  • 在实例创建后,添加新的属性到实例上。(给响应式对象增加属性的时候)
  • 直接更改数组下标来更改数组的值。

原理:

因为响应式数据,我们给对象和数组本身增加了__ob__属性,代表的是Observer实例,当给对象新增不存在的属性,首先会把新的属性进行响应式跟踪,然后触发对象__ob__的dep收集到的watcher去更新,当修改数组索引时我们调用数组的splice去更新数组。


32.自定义指令

答案:

有些情况需要对DOM进行底层操作,这个时候会用到自定义指令。

指令本质上是装饰器,是vue对HTML元素的扩展,给HTML元素增加自定义功能,vue编译DOM时,会找到指令对象,执行指令的相关方法。

五个生命周期:bindinsertedupdatecomponentUpdatedunbind

  1. bind:只调用一次,指令第一次绑定元素时调用。在这里可以进行一次性的初始化设置。
  2. inserted:被绑定元素插入父节点时调用,(仅保证父节点存在,但不一定已被插入文档中)。
  3. update:所在组件的VNode更新时调用,但是可能发生在其子Vnode更新之前,指令的值可能发生了变化,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新,
  4. componentUpdated:指令所在的VNode及其子VNode全部更新后调用。
  5. unbind:只调用一次,指令与元素解绑时调用。

原理:


33.vue 修饰符有哪些

答案:

事件修饰符

  • .stop:阻止事件继续传播
  • .prevent:阻止标签默认行为
  • .capture:使用事件捕获模式,即元素自身触发的事件现在此处处理,然后才交由内部元素处理。
  • .self:只当在event.target是当前元素自身时触发处理函数
  • .once:事件将只会触发一次
  • .passive:告诉浏览器你不想阻止事件的默认行为

v-model修饰符

  • .lazy:通过这个修饰符转变为change事件再同步
  • .number:自动将用户输入的值变为数值类型
  • .trim:自动过滤用户输入的首位空格

键盘事件修饰符

  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键

  • .ctrl
  • .alt
  • .shift
  • .meta

鼠标按钮修饰符

  • .left
  • .right
  • .middle


34.vue 不能监听对数组的哪些操作,怎么解决

答案:

  • 使用索引修改数组项时,解决:Vue.setvm.$setsplice
  • 修改数组长度时 解决:splice


3.vue 内置指令

答案:

严格的 MVVM 要求 View 不能和 Model 直接通信,而 vue 提供了$refs 这个属性,让 Model 可以直接操作 View,违反了这一规定,所以 View 没有完全遵循 MVVM


@yihan12 yihan12 added the vue2 label Jan 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant