文章目录
- 1. 谈谈对vue的双向绑定原理的理解?
- 2. v-if和v-show区别?
- 3. 关于Vuex的内容
- 4. 单页面应用是什么?优缺点?如何弥补缺点
- 5. 组件及通信方式有哪些?
- 6. vue优点?
- 7. Computed 和 Watch 的区别
- 8. Computed 和 Methods的区别
- 9. slot是什么?有什么作用?原理是什么?
- 10. 过滤器的作用,如何实现一个过滤器
- 11.vue-router的两种模式
- 12. 对 React 和 Vue 的理解,它们的异同
- 13. route 和 router 的区别
- 14. Vue2和Vue3的区别
- 15. Vue的响应式原理
- 16. 虚拟DOM
- 17. vue的生命周期?
- 18. 组件渲染过程
- 19. Vue中如何做样式穿透
- 20. scoped原理
- 21. 描述下Vue自定义指令
- 22. $nextTick 原理及作用
- 23. v-model 是如何实现的,语法糖实际是什么?
- 24. 如何保存页面的当前的状态
- 25. Vue的基本原理
- 26. Vue中key的作用
- 27. 为什么不建议用index作为key?
- 28. router-link 和 $router.push 实现跳转的原理
- 29. vue 的生命周期有哪些? 使用场景?
- 30. vue 获取数据在哪个周期函数
- 31. vue 之 keep-alive
1. 谈谈对vue的双向绑定原理的理解?
双向绑定主要指修改数据时,无须操作DOM,视图会自动刷新。操作视图时绑定的数据也会跟随变动。
数据 => 视图
vue在初始化实例时,会用Object.defineProperty方法,给所有的数据添加setter函数,实现对数据变更的监听。当数据被修改时,生成新的虚拟DOM树,跟老的虚拟DOM对比,根据对比结果找出需要更新的节点进行更新。
视图 => 数据
从视图到数据较为简单,视图变化后触发监听如oninput等,在绑定的方法中修改数据。
2. v-if和v-show区别?
v-if控制Dom是否存在,v-show控制样式
1. 用途不同:
v-if
:用于根据表达式的真假值来决定是否渲染或销毁元素。当表达式为true
时,元素会被渲染到 DOM 中,当表达式为false
时,元素会被从 DOM 中移除。v-for
:用于循环渲染列表数据,根据提供的数据源遍历生成多个元素或组件。
2. 对应数据类型不同:
v-if
:可以接收任意类型的表达式作为条件进行判断。v-for
:必须使用遍历数组或对象的语法来迭代数据。
3. 循环次数不同:
v-if
:在条件为真时渲染一次元素。如果条件变为假,则元素将被销毁。v-for
:根据数据源的长度或键值对数量,循环渲染多次元素。
使用时的注意点:
- 当需要根据条件动态显示或隐藏一个元素或组件时,使用
v-if
。 - 当需要根据数据源循环渲染多个元素或组件时,使用
v-for
。
3. 关于Vuex的内容
在 Vuex 中,数据的流动是单向的
vuex是一个状态管理工具,集中式的管理所有组件的状态数据。统一的去管理组件,将组件的状态抽象为一个store文件,通过commit方法触发mutation里的函数来改变组件属性。
组件中可以使用computed属性监听数据的变化控制组件显隐等。如下举个loading组件的栗子
loading组件中根据Loading数据,控制DOM显隐
<template>
<div class="cover" v-show="Loading">
<div>加载中</div>
</div>
</template>
<script>
import Store from '../../store'
export default {
name: "Loading",
computed:{
Loading(){
return Store.state.Loading;
}
}
}
</script>
vuex集中管理状态,创建一个叫store的js文件
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// Loading组件
Loading:false,
},
mutations: {
// Loading组件
ChangeLoading:function (State,Value) {
State.Loading = Value;
}
},
});
使用loading的组件中,这样操作
import Store from '../../store'
Store.commit("changeFooter",true);
4. 单页面应用是什么?优缺点?如何弥补缺点
-
单页面对一个入口DOM通过路由去更改内容,整个应用只有一个html页面
-
SPA优点:用户体验好,没有页面切换就没有白屏情况;
-
SPA缺点:首屏加载慢,不利于SEO
-
SPA弥补:通过压缩、路由懒加载缓解首屏慢;通过SSR 服务器端渲染解决SEO问题;
5. 组件及通信方式有哪些?
- 1、什么是组件?
组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
声明组件
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
使用组件(把组件当作自定义元素)
<div id="components-demo">
<button-counter></button-counter>
</div>
引入组件
new Vue({ el: '#components-demo' })
2. 通信方式
(1) props /
e
m
i
t
父组件通过
p
r
o
p
s
向子组件传递数据,子组件通过
emit 父组件通过props向子组件传递数据,子组件通过
emit父组件通过props向子组件传递数据,子组件通过emit和父组件通信
6. vue优点?
- 1、轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
- 2、简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
- 3、双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
- 4、 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
- 5、视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
- 6、虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
- 7、运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
7. Computed 和 Watch 的区别
-
computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。
-
watch 侦听器 : 更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
8. Computed 和 Methods的区别
-
computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值;
-
method 调用总会执行该函数。
9. slot是什么?有什么作用?原理是什么?
slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。slot又分三类,默认插槽,具名插槽和作用域插槽。
- 默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插
槽。 - 具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽。
- 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲
染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插
槽
实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. slot中 , 默 认 插 槽 为slot.default,具名插槽为vm. , 为 插 槽 名 , 当 组 件 执 行 渲 染 函 数 时 候 , 遇 到 标 签 , 使 用 slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。
10. 过滤器的作用,如何实现一个过滤器
根据过滤器的名称,过滤器是用来过滤数据的,在Vue中使用filters来过滤数据,filters不会修改数据,而是过滤数据,改变用户看到的输出(计算属性 computed ,方法 methods 都是通过修改数据来处理数据格式的输出显
示)。
使用场景:
- 需要格式化数据的情况,比如需要处理时间、价格等数据格式的输出 / 显示。
- 比如后端返回一个 年月日的日期字符串,前端需要展示为 多少天前 的数据格式,此时就可以用fliters过滤器来
处理数据。
过滤器是一个函数,它会把表达式中的值始终当作函数的第一个参数。过滤器用在插值表达式 {{ }} 和 v-bind 表达
式 中,然后放在操作符“ | ”后面进行指示。
11.vue-router的两种模式
- hash模式:即地址栏 URL 中的 # 符号;
- history模式:window.history对象打印出来可以看到里边提供的方法和记录长度。利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)。
12. 对 React 和 Vue 的理解,它们的异同
-
相似之处:
- 都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库;
- 都有自己的构建工具,能让你得到一个根据最佳实践设置的项目模板;
- 都使用了Virtual DOM(虚拟DOM)提高重绘性能;
- 都有props的概念,允许组件间的数据传递;
- 都鼓励组件化应用,将应用分拆成一个个功能明确的模块,提高复用性。
-
不同之处 :
- 数据流
- Vue默认支持数据双向绑定,而React一直提倡单向数据流
- 虚拟DOM
- Vue2.x开始引入"Virtual DOM",消除了和React在这方面的差异,但是在具体的细节还是有各自的特点。
- Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
- 对于React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,这可以通过PureComponent/shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。
- 数据流
-
组件化: React与Vue最大的不同是模板的编写。
- Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。
- React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。
具体来讲:React中render函数是支持闭包特性的,所以import的组件在render中可以直接调用。但是在Vue中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以 import 一个组件完了之后,还需要在components 中再声明下。
-
监听数据变化的实现原理不同
-
Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
-
React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的vDOM的重新渲染。这是因为
Vue 使用的是可变数据,而React更强调数据的不可变。
-
-
高阶组件
- react可以通过高阶组件(HOC)来扩展,而Vue需要通过mixins来扩展。高阶组件就是高阶函数,而React的组件本身就是纯粹的函数,所以高阶函数对React来说易如反掌。相反Vue.js使用HTML模板创建视图组件,这时模板无法有效的编译,因此Vue不能采用HOC来实现。
-
构建工具 两者都有自己的构建工具:
-
React ==> Create React APP
-
Vue ==> vue-cli
-
-
跨平台
-
React ==> React Native
-
Vue ==> Weex
-
13. route 和 router 的区别
-
$route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数
-
$router 是“路由实例”对象包括了路由的跳转方法,钩子函数等
14. Vue2和Vue3的区别
Vue 2 和 Vue 3 是 Vue.js 框架的两个主要版本,它们有以下几个区别:
-
- 性能优化:Vue 3 在底层进行了一些架构上的优化,使用了 Proxy 对象重写了底层响应式系统,提高了性能和内存利用率。Vue 3 还引入了静态树提升(Static Tree Hoisting)和源码优化技术,进一步提高了渲染性能。
-
- 体积大小:Vue 3 的体积更小。通过移除不常用的特性、优化打包算法和引入按需加载等机制,Vue 3 的包大小相对于 Vue 2 有所减小,从而加快了页面加载速度。
-
- Composition API:Vue 3 引入了 Composition API,这是一种新的 API 风格,可以更好地组织和复用组件逻辑。相比于 Vue 2 的 Options API,Composition API 更加灵活,可以将逻辑关注点聚集在一起,并且可以在不同的组件之间共享和重用逻辑代码。
-
- TypeScript 支持:Vue 3 对 TypeScript 的支持更加友好。Vue 3 的源码基于 TypeScript 编写,并且提供了更好的类型推导和类型检查。
-
- Teleport:Vue 3 引入了 Teleport(传送门)功能,它允许开发者将组件的内容渲染到 DOM 树中的任何位置,而不仅仅局限于组件自身的模板中。这在处理弹出窗口、对话框等场景时非常有用。
-
- 其他改进:Vue 3 还带来了一些其他的改进,比如更好的 TypeScript 支持、更灵活的自定义指令、更好的虚拟滚动支持、优化的响应式系统等。
需要注意的是,尽管 Vue 3 带来了许多改进和新特性,但它并不完全兼容 Vue 2。在升级项目到 Vue 3 时,可能需要进行一些代码的修改和适配工作。因此,在决定是否升级到 Vue 3 之前,要对项目的需求和现有代码进行评估。
15. Vue的响应式原理
Vue 的响应式原理是通过使用 Object.defineProperty() 方法来实现的。当一个 Vue 实例被创建时,Vue 会遍历它的 data 对象的所有属性,并使用 Object.defineProperty() 方法将这些属性转换为 getter 和 setter。
在 Vue 中,每个被响应式监听的属性都有一个依赖收集器(Dep)和订阅者(Watcher)。当访问一个被监听的属性时,会触发它的 getter 方法,并在 getter 方法中进行依赖收集。依赖收集的过程会将当前正在计算的 Watcher(Watcher 是一个用于追踪依赖关系的对象)添加到该属性的依赖收集器中。
当被监听的属性发生变化时,会触发相应属性的 setter 方法,并在 setter 中通知依赖收集器中的所有 Watcher 执行更新操作。这样就实现了属性的变化能够触发依赖的更新。
总结一下 Vue 的响应式原理:
Vue 使用 Object.defineProperty() 方法将 data 对象中的属性转换为 getter 和 setter。
当访问一个被监听的属性时,会触发 getter 方法,在 getter 方法中进行依赖收集。
当被监听的属性发生变化时,会触发 setter 方法,并通知依赖收集器中的 Watcher 执行更新操作。
通过这种响应式原理,Vue 能够自动追踪属性之间的依赖关系,并在属性发生变化时,自动更新与之相关的视图,从而实现了数据驱动的视图更新。
16. 虚拟DOM
虚拟dom是当前前端最流行的两个框架(vue和react)都用到的一种技术,都说他能帮助vue和react提升渲染性能,提升用户体验。那么今天我们来详细看看虚拟dom到底是个什么鬼?
什么是虚拟dom
大家一定要记住的一点就是,虚拟dom就是一个普通的js对象。是一个用来描述真实dom结构的js对象,因为他不是真实dom,所以才叫虚拟dom。
虚拟dom的作用
- 1、我们都知道,传统dom数据发送变化的时候,我们都需要不断的去操作dom,才能更新dom的数据,虽然后面出现了模板引擎这种东西,可以让我们一次性去更新多个dom。但模板引擎依旧没有一种可以追踪状态的机制,当引擎内某个数据发生变化时,他依然要操作dom去重新渲染整个引擎。
而虚拟dom可以很好的跟踪当前dom状态,因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发送变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验 - 2、因为虚拟dom是一个普通的javascript对象,故他不单单只能允许在浏览器端,渲染出来的虚拟dom可同时在node环境下或者weex的app环境下允许。有很好的跨端性
什么是diff算法
diff算法就是用于比较新旧两个虚拟dom之间差异的一种算法。具体详情,后面我们会说
17. vue的生命周期?
Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。
- beforeCreate(创建前) : 数据观测和初始化事件还未开始,此时 data 的响应式追踪、event/watcher 都还没有被设置,也就是说不能访问到data、computed、watch、methods上的方法和数据。
- created(创建后) :实例创建完成,实例上配置的 options 包括 data、computed、watch、methods 等都配置完成,但是此时渲染得节点还未挂载到 DOM,所以不能访问到 $el 属性。
- beforeMount(挂载前) :在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。此时还没有挂载html到页面上。
- mounted(挂载后) :在el被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配
置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html 页面中。此过程中进行ajax交互。 - beforeUpdate(更新前) :响应式数据更新时调用,此时虽然响应式数据更新了,但是对应的真实 DOM还没有被渲染。
- updated(更新后) :在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。此时 DOM 已经根据响
应式数据的变化更新了。调用时,组件 DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。 - beforeDestroy(销毁前) :实例销毁之前调用。这一步,实例仍然完全可用,this 仍能获取到实例。
- destroyed(销毁后) :实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务端渲染期间不被调用。
另外还有 keep-alive 独有的生命周期,分别为 activated 和 deactivated 。用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执行 activated 钩子函数
18. 组件渲染过程
-
解析模板:Vue组件通常使用模板(Template)来描述组件的结构和内容。在渲染过程中,Vue会先解析组件的模板,将其编译为渲染函数。
-
创建实例:当有组件需要被渲染时,Vue会创建一个组件实例。这个实例会包含组件的各种属性和方法,并与模板进行关联。
-
挂载实例:通过调用实例的 m o u n t 方法,将组件实例挂载到真实的 D O M 元素上。如果没有手动调用 mount方法,将组件实例挂载到真实的DOM元素上。如果没有手动调用 mount方法,将组件实例挂载到真实的DOM元素上。如果没有手动调用mount方法,Vue也可以自动将组件实例挂载到指定的DOM元素上。
-
渲染函数执行:当组件实例被挂载后,Vue会执行之前编译的渲染函数来生成虚拟DOM树(Virtual DOM Tree)。
-
Diff算法:在每次数据发生变化时,Vue会通过对比新旧虚拟DOM树,找出需要更新的部分,并生成一系列DOM操作指令。
-
执行DOM更新:根据Diff算法的结果,Vue会执行相应的DOM操作,将变化应用到实际的DOM元素上。这些操作可能包括插入、删除、替换等。
-
数据响应式更新:当数据发生变化时,Vue会根据数据的依赖关系自动更新相应的DOM元素,从而保持视图和数据的同步。
-
销毁组件:当不再需要某个组件时,可以通过手动销毁实例或者组件被卸载时自动销毁实例。在销毁过程中,Vue会执行一些清理工作,释放相关的资源。
通过以上步骤,Vue能够将组件的模板转换为可交互的页面,并提供响应式的数据绑定,使得应用的状态和视图能够自动保持同步。这种渲染过程的优化和性能提升是Vue框架的核心特点之一。
19. Vue中如何做样式穿透
一、为什么需要穿透scoped?
引用了第三方组件后,需要在组件中局部修改第三方组件的样式,而又不想去除scoped属性造成组件之间的样式污染。此时只能通过特殊的方式,穿透scoped。
二、样式穿透的方法
样式穿透的写法有三种:>>>、/deep/、::v-deep
>>>
如果项目使用的是css原生样式,那么可以直接使用 >>> 穿透修改
/* 用法: */
div >>> .cla {
color: red;
}
/deep/
项目中用到了预处理器 scss 、sass、less 操作符 >>> 可能会因为无法编译而报错 。可以使用 /deep/
注意:vue-cli3以上版本不可以
/* 用法: */
div /deep/ .cla {
color: red;
}
::v-deep
/* 用法: */
div ::v-deep .cla {
color: red;
}
20. scoped原理
一、什么是scoped,为什么要用
在vue文件中的style标签上,有一个特殊的属性:scoped。
当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,通过该属性,可以使得组件之间的样式不互相污染。
二、scoped的原理
为组件实例生成一个唯一标识,给组件中的每个标签对应的dom元素添加一个标签属性,data-v-xxxx给
21. 描述下Vue自定义指令
Vue 自定义指令是一种扩展 Vue 模板语法的方式,用于封装可重用的 DOM 操作和行为。通过自定义指令,我们可以在模板中直接使用指令,并在指令中定义相应的逻辑。
自定义指令可以在模板中使用 v-xxx 的形式进行绑定,如:
<div v-myDirective="value"></div>
其中 “myDirective” 是指令名,“value” 是传递给指令的值。在指令的钩子函数中,可以通过 el 参数获取元素对象,通过 binding.value 获取传递给指令的值。
自定义指令的应用场景广泛,可以用于处理 DOM 操作、封装常用行为、与第三方库集成等。比如,可以创建一个自定义指令来实现表单验证、实现特定效果(如水波纹点击效果)、集成第三方插件等。
22. $nextTick 原理及作用
Vue 的 nextTick 其本质是对 JavaScript 执行原理 EventLoop 的一种应用。
nextTick 的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JavaScript 方法来模拟对应的微/宏任务的实现,本质是为了利用 JavaScript 的这些异步回调任务队列来实现 Vue 框架中自己的异步回调队列。
nextTick 不仅是 Vue 内部的异步队列的调用方法,同时也允许开发者在实际项目中使用这个方法来满足实际应用中对 DOM 更新数据时机的后续逻辑处理
nextTick 是典型的将底层 JavaScript 执行原理应用到具体案例中的示例,引入异步更新队列机制的原因∶
- 如果是同步更新,则多次对一个或多个属性赋值,会频繁触发 UI/DOM 的渲染,可以减少一些无用渲染
- 同时由于 VirtualDOM 的引入,每一次状态发生变化后,状态变化的信号会发送给组件,组件内部使用 VirtualDOM 进行计算得出需要更新的具体的 DOM 节点,然后对 DOM 进行更新操作,每次更新状态后的渲染过程需要更多的计算,而这种无用功也将浪费更多的性能,所以异步渲染变得更加至关重要。
Vue采用了数据驱动视图的思想,但是在一些情况下,仍然需要操作DOM。有时候,可能遇到这样的情况,DOM1的数据发生了变化,而DOM2需要从DOM1中获取数据,那这时就会发现DOM2的视图并没有更新,这时就需要用到了nextTick了。
由于Vue的DOM操作是异步的,所以,在上面的情况中,就要将DOM2获取数据的操作写在$nextTick中。
this.$nextTick(() => {
// 获取数据的操作...
})
所以,在以下情况下,会用到nextTick:
- 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的DOM结构的时候,这个操作就需要方法在nextTick()的回调函数中。
- 在vue生命周期中,如果在created()钩子进行DOM操作,也一定要放在nextTick()的回调函数中。
因为在created()钩子函数中,页面的DOM还未渲染,这时候也没办法操作DOM,所以,此时如果想要操作DOM,必须将操作的代码放在nextTick()g的回调函数中。
23. v-model 是如何实现的,语法糖实际是什么?
- v-model 是 Vue 提供的一个用于实现双向数据绑定的指令。它是 v-bind 和 v-on 的语法糖,用于简化常见的表单输入元素(如 input、textarea、select 等)与数据的双向绑定。
在使用 v-model 时,Vue 会根据不同的表单元素类型自动为其绑定适当的事件以及更新数据的行为。它实际上是以下两种指令的结合:
v-bind:用于将数据绑定到表单元素的 value、checked、selected 等属性上。当数据发生变化时,表单元素会反映这些变化。
v-on:用于监听表单元素的输入事件(如 input、change、click 等),并将新的值更新到所绑定的数据上。
举个例子,使用 v-model 实现双向绑定可以简化下面的代码:
<input v-bind:value="message" v-on:input="message = $event.target.value">
等价于:
<input v-model="message">
这里的 message 是 Vue 实例的一个数据属性,使用 v-model 可以直接将该属性与 input 元素的值进行双向绑定。
需要注意的是,v-model 默认情况下使用的是 input 事件,对于某些表单元素(如多行文本框)可能需要手动指定 input 事件,或者使用 .lazy 修饰符实现在失去焦点时才进行数据更新。
总结来说,v-model 是 Vue 提供的语法糖,是 v-bind 和 v-on 的结合,用于简化表单输入元素与数据的双向绑定。它实际上是通过事件监听和数据绑定来实现数据的同步更新。
24. 如何保存页面的当前的状态
问题 : 在vue项目中,刷新页面之后,之前的登录信息, 打开的所有菜单,都消失, 如何实现刷新之后页面仍然是刷新之前的状态
解决 : 使用vuex状态管理, 搭配 , webstorage本地存储. 将vuex里面的数据同步更新到 localStorage/sessionStorage里存储
25. Vue的基本原理
Vue.js是一种用于构建用户界面的JavaScript框架。它基于MVVM(Model-View-ViewModel)模式,具有响应式数据绑定和组件化的特性。
Vue的基本原理如下:
-
数据驱动:Vue使用数据驱动的方式来管理应用的状态。通过将数据与DOM进行关联,当数据发生变化时,Vue会自动更新对应的DOM元素,从而保持视图与数据的同步。
-
响应式系统:Vue通过利用底层的观察者模式来实现数据的响应式。当数据发生改变时,Vue能够自动追踪这些变化,并通知相关的DOM元素进行更新。
-
模板引擎:Vue使用基于HTML的模板语法来声明应用的视图。这些模板可以被解析为虚拟DOM(Virtual DOM)树,然后通过与实际DOM进行比较,只更新需要变化的部分,以提高性能。
-
组件化开发:Vue将应用拆分为多个独立的组件,每个组件包含了自己的模板、逻辑和样式。这种组件化的开发方式使得代码可以复用,并且可以更好地维护和组织应用的结构。
-
生命周期钩子:在组件的生命周期中,Vue提供了一些特定的钩子函数,允许开发者在不同的阶段插入自己的逻辑代码。例如,在组件挂载到DOM之前或之后执行一些操作。
总体而言,Vue通过其简洁易用的API和强大的功能,使得开发人员能够更轻松地构建交互性强、高效的前端应用程序。
26. Vue中key的作用
vue 中 key 值的作用可以分为两种情况来考虑:
- 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。
如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。因此可以通过使用 key 来唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识
一个独立的元素。 - 第二种情况是 v-for 中使用 key。用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM。
key 是为 Vue 中 vnode 的唯一标记,通过这个 key,diff 操作可以更准确、更快速
- 更准确:因为带 key 就不是就地复用了,在 sameNode 函数a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。
- 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快
27. 为什么不建议用index作为key?
使用index 作为 key和没写基本上没区别,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2…这样排列,导致 Vue会复用错误的旧子节点,做很多额外的工作。
28. router-link 和 $router.push 实现跳转的原理
-
router-link
默认会渲染为 a 标签. 可以通过 tag 属性修改为其他标签
自动为 a 标签添加 click 事件. 然后执行 $router.push() 实现跳转 -
$router.push
根据路由配置的 mode 确定使用 HTML5History 还是 HashHistory 实现跳转
HTML5History : 调用 window.history.pushState() 跳转
HashHistory : 调用 HashHistory.push() 跳转
29. vue 的生命周期有哪些? 使用场景?
加载时
- beforeCreate : 开始创建
- data 和 methods 都未创建, 此处不能使用
- created : 创建完毕
- data 和 methods 创建完毕, 最早的可以使用处
- beforeMount : 开始挂载
- 内存中已编译好所有内容, 准备显示到页面
- mounted : 挂载完毕
- 组件脱离创建阶段, 真正显示到页面上. 操作页面的DOM 最早可以在这里进行
更新
- 组件脱离创建阶段, 真正显示到页面上. 操作页面的DOM 最早可以在这里进行
- beforeUpdate : 更新前
- updated : 更新完毕
keep-alive相关 - activated : 被 keep-alive keep-alive 缓存的组件激活时调用。
- deactivated : 被 keep-alive keep-alive 缓存的组件停用时调用。
销毁 - beforeDestory : 销毁前
- destroyed : 销毁完毕
- data 和 methods 此处已消失, 无法使用
30. vue 获取数据在哪个周期函数
理论上, 应该在 created 周期中进行网络请求. 因为这是最早的的 methods 与 data 加载完毕的时机.
在 created 发送请求, 可以比 mounted 周期发送请求, 提前几毫秒 提前几毫秒的时间拿到数据.
而实际开发中, 几毫秒的提前对用户来讲, 没有任何差异. 所以 created 和 mounted 发送请求都可以.
31. vue 之 keep-alive
keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
keep-alive
是 Vue.js 中的一个内置组件,用于缓存组件实例,避免多次创建和销毁。它主要用于那些需要频繁切换、但切换时状态保持的组件,可以提升应用的性能和用户体验。