1.v-for的key的作用
快速查找到节点,减少渲染次数,提升渲染性能
2.v-show和v-if区别
都是隐藏功能
3.vue组件生命周期
1.beforeCreate(创建前)。在这个阶段,vue实例的挂载元素和数据对象data都为undefined,还未初始化。145
2.created(创建后)。在这个阶段,vue实例的数据对象data已经有了,但el还没有初始化。
3.beforeMount(载入前)。在这个阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点。
4.mounted(载入后)。在这个阶段,vue实例挂载完成,data的数据已经成功渲染。
5.beforeUpdate(更新前)。当data变化时,会触发beforeUpdate和updated方法。
6.updated(更新后)。当data变化时,会触发beforeUpdate和updated方法。
7.beforeDestroy(销毁前)。在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。
8.destroyed(销毁后)。在这个阶段,vue实例已经完全销毁。
4. vue含有子组件加载过程
1、父子组件的加载顺序为:
父beforeCreated ->父created ->父beforeMounted ->子beforeCreated ->子created ->子beforeMounted ->子mounted -> 父mounted
2、父组件更新顺序为:
父beforeUpdate->父updated
3、子组件更新顺序为:
父beforeUpdate->子beforeUpdate->子updated->父updated
4、父子组件销毁顺序为:
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
5.watch和computed区别及用法
computed计算属性:
1. 能够实时监听data里面绑定的数据(包括vueX),但是其余数据的改变是监听不到的。
2. 适用于需要计算的一个值被多个数据影响的情况,如果函数内所依赖的属性没有发生改变,就从缓存中读取,只有依赖数据发生改变,才会重新进行计算。
3. 必须有return返回值,函数名由自己取。
4. 其中有异步操作时无效。
5.多对一
watch监听器:
1. 其中的函数名必须与data中的被监听数据名一致。
2. 其中有两个参数,代表了新数据和旧数据,一般使用(val,oldVal)
3.一对一
4.不写deep: true时,代表不需要进行深度监听,其只会监听数据的值是否发生改变,而不去监听数据的地址是否发生改变。要想监听数据地址就必须采取深度监听
当一个值的变化引发多个属性的变化或改变后需要采取一些操作时使用watch;
当多个值影响一个值的变化时使用computed。
6.vue中v-if和v-for哪个优先级高
在vue2中,v-for的优先级高于v-if;在vue3中,v-if的优先级高于v-for。在vue中,永远不要把v-if和v-for同时用在同一个元素上,会带来性能方面的浪费(每次渲染都会先循环再进行条件判断);想要避免出现这种情况,可在外层嵌套template(页面渲染不生成dom节点),在这一层进行v-if判断,然后在内部进行v-for循环
7.谈谈你对 keep-alive 的了解
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,其有以下特性:
1.一般结合路由和动态组件一起使用,用于缓存组件;
2.提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;
3.对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。
8.组件中 data 为什么是一个函数
因为组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,
如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题
9.v-model 的原理
v-model 本质上是语法糖
<input v-model='something'>
的语法糖
<input v-bind:value="something" v-on:input="something = $event.target.value">
10.你使用过 Vuex 吗?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
主要包括以下几个模块:
-
State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。
-
Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
-
Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。
-
Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
-
Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
11.使用过 Vue SSR 吗?说说 SSR
1.SSR代表服务器端渲染(Server-Side Rendering),它是一种将页面的渲染工作从客户端转移到服务器端的技术。在传统的客户端渲染(CSR)中,页面的渲染是在浏览器中进行的,浏览器通过请求获取页面的HTML和JavaScript代码,然后在客户端进行页面的渲染和交互。
2.Vue.js 是一个用于构建客户端应用的框架。默认情况下,Vue 组件的职责是在浏览器中生成和操作 DOM。然而,Vue 也支持将组件在服务端直接渲染成 HTML 字符串,作为服务端响应返回给浏览器,最后在浏览器端将静态的 HTML“激活”(hydrate) 为能够交互的客户端应用。
3.一个由服务端渲染的 Vue.js 应用也可以被认为是“同构的”(Isomorphic) 或“通用的”(Universal),因为应用的大部分代码同时运行在服务端和客户端。
与客户端的单页应用 (SPA) 相比,SSR 的优势主要在于:
1)更快的首屏加载:这一点在慢网速或者运行缓慢的设备上尤为重要。服务端渲染的 HTML 无需等到所有的 JavaScript 都下载并执行完成之后才显示,所以你的用户将会更快地看到完整渲染的页面。除此之外,数据获取过程在首次访问时在服务端完成,相比于从客户端获取,可能有更快的数据库连接。这通常可以带来更高的核心 Web 指标评分、更好的用户体验,而对于那些“首屏加载速度与转化率直接相关”的应用来说,这点可能至关重要。
2)统一的心智模型:你可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。
3)更好的 SEO:搜索引擎爬虫可以直接看到完全渲染的页面
使用 SSR 时还有一些权衡之处需要考量:
1)开发中的限制。浏览器端特定的代码只能在某些生命周期钩子中使用;一些外部库可能需要特殊处理才能在服务端渲染的应用中运行。
2) 更多的与构建配置和部署相关的要求。服务端渲染的应用需要一个能让 Node.js 服务器运行的环境,不像完全静态的 SPA 那样可以部署在任意的静态文件服务器上。
3)更高的服务端负载。在 Node.js 中渲染一个完整的应用要比仅仅托管静态文件更加占用 CPU 资源,因此如果你预期有高流量,请为相应的服务器负载做好准备,并采用合理的缓存策略。
12.vue-router 路由模式有几种
vue-router 有 3 种路由模式:hash、history、abstract三种模式
-
hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
-
history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;
-
abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.
1)路由模式
-
URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;
-
hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换;
-
可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;
-
我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)
2)history路由模式
-
pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;
-
我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);
-
history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)
13.Vue 框架怎么实现对象和数组的监听
数据劫持:Vue通过使用Object.defineProperty()方法来劫持数据对象的属性,并使用getter和setter来监听属性的变化。当属性被修改时,setter方法会被调用,从而触发相应的监听函数。
发布订阅模式:Vue通过发布订阅模式来实现数据监听。当数据发生变化时,Vue会通知所有订阅该数据的监听器,并执行相应的回调函数。Vue使用一个事件队列来维护所有的订阅者和事件处理函数,当数据发生变化时,Vue会将变化事件添加到事件队列中,并逐个执行对应的处理函数
但是 Object.defineProperty() 只能对属性进行数据劫持,不能对整个对象或数组进行劫持。
/**
* Observe a list of Array items.
*/
observeArray (items: Array<any>) {
for (let i = 0, l = items.length; i < l; i++) {
observe(items[i]) // observe 功能为监测数据的变化
}
}
/**
* 对属性进行递归遍历
*/
let childOb = !shallow && observe(val) // observe 功能为监测数据的变化
我们就能知道 Vue 框架是通过遍历数组 和递归遍历对象,从而达到利用 Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听
14.vue中的Vue.set()和Vue.$set()
.set 和 Vue.$set 都是用于在 Vue 实例中动态添加响应式属性的方法。它们的作用是相同的,都可以实现给对象或数组添加新的属性或元素,并确保添加后的属性或元素是响应式的。
区别:
Vue.set 是全局方法,可以直接通过 Vue.set(obj, key, value) 的方式调用,其中 obj 是要添加属性的对象,key 是属性名,value 是属性值。例如:Vue.set(this.obj, 'name', 'John')。
Vue.$set 是实例方法,需要通过 Vue 实例来调用,即 this.$set(obj, key, value)。其中 this 是 Vue 实例的引用,obj 是要添加属性的对象,key 是属性名,value 是属性值。例如:this.$set(this.obj, 'name', 'John')。
总的来说,它们的作用和效果是相同的,只是调用方式略有不同。推荐在组件内使用 this.$set 来添加响应式属性,因为它直接绑定到当前组件实例上。而 Vue.set 则适用于在全局范围内添加响应式属性.
15.vue传参数的方法
1)父子组件传参:父子组件间利用“props”和“$emit”进行传参
2)$parent 和 $children,获取父组件和子组件参数
3)provide
/ inject
获取多级组件
4)ref
/ refs调取子组件方法获取
5)
eventBus 适合兄弟组件或者父子组件都可以
6)VUEX状态管理器
7)$attrs
与 $listeners方法:
$attrs继承所有的父组件属性(除了 prop 传递的属性、class 和 style 一般用在子组件的子元素上,$listeners属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,你就可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)
16.$nextTick()作用
1. 在下一个更新周期之后执行回调函数。这意味着当 vm.$nextTick() 执行完毕时,DOM 已经被更新。
2.在代码执行上下文中延迟回调的执行,直到所有同步的 DOM 更新完成。这可以避免一些异步问题或并发更新(例如修改父组件的数据,然后操作子组件中已更改的 Prop)
在大多数情况下,Vue.js 可以自动处理 DOM 更新并直接渲染到页面上,因此通常情况下不必手动使用 $nextTick() 方法。但对于一些需要在 DOM 更新后执行的操作,比如获取更新后的元素宽高或操作一些插件等,时则很有用。
17:vue代码组件的二次封装
$attrs
:通过向组件传参的方式,传给二次封装的组件
$listeners:通过监听子组件来继承子组件event
18.14 种Vue修饰符