文章目录
- 1、生命周期(单个组件)?
- 基本使用
- 2、computed 和 watch?
- 2、v-show 和 v-if 的区别?
- 3、v-for 和 v-if 不能一起使用?
- 2、如果用自定义事件进行vue组件通讯(兄弟或者毫无关系的组件间通讯)?
- 3、vue 有哪些高级特性?
- - 自定义v-model
- - ```$nextTick ```:DOM渲染完之后调用, 因为vue是异步渲染,data改变之后,DOM不会立即改变.如果想要及时获取准确的DOM结构,就需要使用```$nextTick```,注意:页面渲染时,会将data的修改做整合,多次改变data```$nextTick```只会调用一次。
- -refs :跟ref配合使用,html结构中使用ref定义的属性,可用```this.$refs.dom名字```来获取dom结构。
- - slot:插槽,父组件往子组件中插入一段内容。
- - 动态组件:一个盒子内不知道要渲染哪个组件。场景:一个弹窗根据不同的值,弹出不同的组件,这时就可以使用动态组件来解决
- - 异步组件:当这个组件很大的时候,我们需要按需加载,使用的时候才加载,这个时候我们可以采用import的方式引入.
- - keep-alive:缓存组件,在频繁切换,不需要重复渲染的组件,可使用keep-alive 。优化vue性能,场景tab切换,比较复杂的时候使用keep-alive 比使用v-show要好些。keep-alive 可以不让组件销毁,切换到下一个的时候,原来的组件不会销毁,在点击回来就不用重复渲染。
- - mixin:多个组件有相同的逻辑,抽离出来。但是会出现一些问题
- 4、 vuex
- 5、vue-router
- 6、如何理解mvvm?
- 7、监听data的核心api是什么?
- 8、虚拟DOM?
- 9、diff 算法?
- 10、模板编译
- 11、 vue组件是如何渲染和更新的?
- 12、vue 组件是异步渲染的
- 13、 Hash路由 ?
- 14、H5 history 路由?
- 16、vue的真题演练哈哈哈
- 17、vue3比vue2有什么优势?
- 18、vue3 的生命周期?
- 19、compontion Api 带了啥?
- 19、ref的用法?
- 20、toRef是什么?
- 21、toRefs 是什么?
- 22、vue3升级了哪些重要功能?
- 23、Compontions API如何实现代码逻辑的复用?
- 24、proxy 的使用
- 25、vue3 如何实现响应式?
- 26、vue3 v-model参数的用法?
- 26、watch 和 watchEffect的区别?
- 27、setup中如何获取组件的实例(vue3中composition API中没有this)
- 28、为什么vue3 比vue2 快?
- 29、为什么Vite 启动特别快?
- 30、vue3 中使用JSX语法?
- 31 vue3中的JSX 和 template有什么区别?
- 32、vue3 中使用script setup简写
- 33、Vue3 中script-setup中的属性和事件如何写?
1、生命周期(单个组件)?
挂载阶段:
- beforeCreate(创建前): 这时数据监测和事件初始化还未开始,data、watcher、methods 还不存在,但
$route
已存在,可以根据路由信息进行重定向。 - created(创建后):在实例创建之后被调用,该阶段可以访问data,使用watcher、events、methods,也就是说 数据观测(data observer) 和event/watcher 事件配置 已完成。但是此时dom还没有被挂载。该阶段允许执行http请求操作。
- beforeMount(挂载前):将HTML解析生成AST节点,再根据AST节点动态生成渲染函数。相关render函数首次被调用(划重点)。
- mounted(挂载后):在挂载完成之后被调用,执行render函数生成虚拟dom,创建真实dom替换虚拟dom,并挂载到实例。可以操作dom,比如事件监听.
更新阶段
- beforeUpdate:v m . d a t a 更 新 之 后 , 虚 拟 d o m 重 新 渲 染 之 前 被 调 用 。 在 这 个 钩 子 可 以 修 改 vm.data更新之后,虚拟dom重新渲染之前被调用。
- updated:虚拟dom重新渲染后调用,若再次修改$vm.data,会再次触发beforeUpdate、updated,进入死循环。
卸载阶段
- beforeDestroy:实例被销毁前调用,也就是说在这个阶段还是可以调用实例的。(这里可以销毁定时器或者组件)
- destroyed:实例被销毁后调用,所有的事件监听器已被移除,子实例被销毁。
如果是父子组件,那么生命周期是怎样呢?:
挂载阶段:父(beforeCreate)->子(beforeCreate)->父(created)->子(created)->子(mounted)->父(mounted)
** 更新阶段**:父(beforeUpdate)->子(beforeUpdate)->子(updated)-》父(updated)
卸载阶段:父(beforeDestroy)-》子(beforeDestroy)-》子(destroyed)-》父(destroyed)
基本使用
- 文本插值:
<p> {{message}} </p>
- JS表达式:
<p> {{flag ? 'yes':'no'}}</p>
;只能放js表达式,不能放js语句 - 动态属性:
<p :id="pId"> 动态属性</p>
- 常用指令:
- v-if: 结构显示or隐藏,会触发页面重新渲染;v-if可以单独使用,而v-else-if,v-else必须与v-if组合使用
- v-show:结构显示or隐藏,,使用display属性来控制显示隐藏,不会触发页面重新渲染,如果需要频繁的切换,可用v-show,减少渲染带来的开销
- v-model: 数据双向绑定指令,限制在 、、、components中使用
- v-for: 遍历数组、对象、字符串
- v-bind: 动态属性
<p v-bind:name="name">动态属性 </P>
// 简写
<p :name="name">动态属性</p>
- v-on: 事件绑定简写@
<p v-on:click="handelClick">提交 </P>
// 简写
<p @click="handelClick">提交</p>
- v-html:渲染html,
<div v-html="<p>我是v-html</p>"> 使用v-html之后会覆盖子元素</div>
,会有xss的风险。 - v-text: 渲染字符串,会覆盖之前的字符串
<p v-text="嘿嘿"> 哈哈哈</p>
- v-once: 指会执行一次渲染,当数据发生改变时,不会在变化
<p v-once>{{message}}</p>
2、computed 和 watch?
- computed有缓存,data不变则不会重新计算
- watch 监听data 中的属性,如果属性是引用类型,则监听不到。
2、v-show 和 v-if 的区别?
- v-show是通过display:none来控制dom的显示隐藏,是加载了dom
- v-if是控制dom是否加载,也是显示隐藏。这个不适用于dom频繁切换的场景
3、v-for 和 v-if 不能一起使用?
- v-for 比 v-if 的计算优先级高一些,回显循环熏染再进行v-if的判断,性能不好,不建议一起使用。可在循环的父级使用v-if
2、如果用自定义事件进行vue组件通讯(兄弟或者毫无关系的组件间通讯)?
首先创建一个vue的实例文件,vue本身就有$emit
、$on()
、$off()
等自定义事件的能力
event.js
import Vue from 'vue'
export default new Vue()
然后自定义一个事件a组件:
import event from './event'
mounted(){
event.$on('自定义事件名',this.add)
}
// 在组件销毁的时候,一定要销毁自定义事件,否则可能造成内存泄露
beforeDestory (){
// 销毁自定义事件
event.$off('自定义事件名',this.add)
}
触发自定义事件,b组件
import event from './event'
methods:{
addClick(){
event.$emit('自定义事件名',title)
}
}
3、vue 有哪些高级特性?
- 自定义v-model
<template>
<!-- 例如:vue 颜色选择 -->
<input type="text"
:value="text1"
@input="$emit('change1', $event.target.value)"
>
<!--
1. 上面的 input 使用了 :value 而不是 v-model
2. 上面的 change1 和 model.event1 要对应起来
3. text1 属性对应起来
-->
</template>
<script>
export default {
model: {
prop: 'text1', // 对应 props text1
event: 'change1'
},
props: {
text1: String,
default() {
return ''
}
}
}
</script>
- $nextTick
:DOM渲染完之后调用, 因为vue是异步渲染,data改变之后,DOM不会立即改变.如果想要及时获取准确的DOM结构,就需要使用$nextTick
,注意:页面渲染时,会将data的修改做整合,多次改变data$nextTick
只会调用一次。
this.$nextTick(()=>{
// 获取dom结构
const ulElem=this.$refs.ulDom
})
-refs :跟ref配合使用,html结构中使用ref定义的属性,可用this.$refs.dom名字
来获取dom结构。
<div ref="divName"></div>
mounted(){
console.log(this.$refs.divName) // <div ref="divName"></div>
}
- slot:插槽,父组件往子组件中插入一段内容。
基本使用:
// 父组件
<children>
<div>传一个结构进去</div>
</children>
// 子组件
<template>
<div>
<slot>如果啥都没传,我就显示这行字</slot>
</div>
</template>
作用域插槽: 父组件可以获取子组件里的数据
// 父组件 father
<childrenComp >
<template v-slot="slotProps">
{{slotProps.slotData.name}}
</template>
</childrenComp>
// 子组件
<div>
<slot :slotData="info">{{info.title}}</slot>
</div>
data(){
info:{id:1,title:'hahah',name:'张三'}
}
具名插槽:
// 父组件
<children>
<template v-slot:header>
<div>这是头部</div>
</template>
</children>
// 子组件
<header>
<slot name="header"></slot>
</header>
- 动态组件:一个盒子内不知道要渲染哪个组件。场景:一个弹窗根据不同的值,弹出不同的组件,这时就可以使用动态组件来解决
// 父组件
<component :is="activeCom" />
<script>
export default{
components :{
oneCom,
twoCom
},
data(){
activeCom:'oneCom'
}
methods:{
showCom (type) {
this.activeCom = type==='one'? 'oneCom':'twoCom'
}
}
mounted(){
showCom('two') // 此时页面就会显示twoCom组件的内容
}
}
</script>
- 异步组件:当这个组件很大的时候,我们需要按需加载,使用的时候才加载,这个时候我们可以采用import的方式引入.
FormDemo.vue 这个组件需要异步加载,看来一下代码
<FormDemo v-if="showForm"/>
<button @click="showForm=true">点击展示</button>
<script>
export default{
components :{
FormDemo:()=>import('../FormDemo.vue')
},
data(){
showForm:false
}
}
</script>
- keep-alive:缓存组件,在频繁切换,不需要重复渲染的组件,可使用keep-alive 。优化vue性能,场景tab切换,比较复杂的时候使用keep-alive 比使用v-show要好些。keep-alive 可以不让组件销毁,切换到下一个的时候,原来的组件不会销毁,在点击回来就不用重复渲染。
// A、B、C 组件的切换
<keep-alive>
<A v-if="state==='A'" />
<B v-if="state==='B'" />
<C v-if="state==='C'" />
</keep-alive>
- mixin:多个组件有相同的逻辑,抽离出来。但是会出现一些问题
mixin.js
export default {
data () {
return {
name:'杭州'
}
},
methods:{
showName (){
console.log(this.name)
}
}
}
index.vue
<template>
<div>年龄:{{age}}</div>
<button @click="showName"> 点击</button>
</template>
<script>
import myMixin from './mixin'
export default {
mixins:[myMixin], // 可引入多个mixin
data(){
return {
age:15
}
},
methods:{}
}
</script>
mixin就是将vue中的js部分整合到一块,引入mixin文件就会有相同变量和方法等的代码。
mixin 的问题
- 变量来源不明确,不利于阅读(因为使用mixin整合之后,按住ctrl点击变量不会跳转到变量的来源,但是当前页面又没有,只能通过全局搜索,效率就很慢)
- 多mixin可能会造成变量命名冲突
- mixin和组件可能会出现多对多的关系,复杂度较高
4、 vuex
基本概念:
- state:存储状态变量的地方
- getters:对获取state数据之前进行一些操作,可以理解为state的计算属性
- action:如果state的数据是通过调接口获取,异步操作这里进行,组件中就可用this.$store.dispath(‘aciton名字’)
- mutations: 修改state,只有通过这个才能修改state的值,使用$store.commit(‘’,params)来修改状态
- modules: 将state分成模块,在store中引入
在组件中如何使用?
- dispath : 通过dispath派发action请求
- mapState:在组件中获取state数据,写在computed中
- commit:通过commit来通知mutaions修改state数据
- mapGeeters :在组件中获取state数据,都写在computed
- mapAction: 执行异步操作,写在methods中
- mapMutations: 修改state数据,写在methods中
5、vue-router
- 路由模式
(1)、hash模式,url带#
(2)、histroy模式,需要服务器的支持,这里要跟后端商量好
- 路由的配置,动态路由
路由配置就是有path ,component,
动态路由之后在path后面加上:id,在组件中使用$route.params.id
就可获取到到动态路由后面的id
- 路由懒加载,就是使用动态加载 import方式
6、如何理解mvvm?
- 组件化、数据驱动视图、mvvm
当数据修改,通过viewModel 操作,view 层就直接渲染。当view发生变化,viewModel进行操作,修改model层数据。不用去操作dom,viewmodel已经帮我们处理好了
7、监听data的核心api是什么?
- Object.defineProperty(监听的对象,属性,对象里含有get,set方法)来监听数据的变化
Object.defineProperty()的缺点?
- 因为做了深度监听,需要递归到底,一次性计算量大,如果对象层级特别多,就会导致性能问题
- 无法监听到data上的新增和删除属性。如果想要新增或删除的话,使用Vue.set 、Vue.delete
- 无法原生监听数组,需要特殊处理
8、虚拟DOM?
- 用JS模拟DOM结构,新的虚拟DOM和旧的虚拟DOM进行对比,得出需要修改的dom结构去更新真实DOM。工具(snabbom)
9、diff 算法?
- diff算法是虚拟DOM中最核心的部分
- 概述: 两个虚拟DOM,只比较同一层级,不跨级比较。节点不相同,则直接删掉重建,不在深度比较;节点和key,两者都相同,则认为是相同节点,不在深度比较.
10、模板编译
- 内部主要语法是with语法
- vue-template-complier将模板编译成render函数,执行render函数,返回虚拟dom
- 基于虚拟dom再执行patch和diff算法
- 使用webpack ,vue-loader ,会在开发环境打包编译模板
11、 vue组件是如何渲染和更新的?
- (1)组件初次渲染
* 解析模板为render函数(或在开发环境下编译和打包vue-loader就已经编译为render函数了)
* 触发响应式,监听data数据getter和setter
* 执行render函数,生成虚拟dom,使用patch(ele,vnode)函数渲染组件
(2) 组件更新时?
* 修改data,触发setter函数(此前已在getter已被监听)
* 重新执行render函数,生成新的虚拟dom ,
* 然后执行patch(vnode,newVnode),更新组件
12、vue 组件是异步渲染的
- 目的:页面渲染时,会data的修改做整合,多次修改data也就只会渲染一次,一次性更新视图,能减少dom渲染次数,提高性能
- $nextTick()
待渲染完再回调,可获取dom元素
13、 Hash路由 ?
使用window.onhashchange 监听路由的跳转
特点:
- hash变化会触发网页的调转,浏览器的前进后退,但是页面不会刷新 ,url上会有#号
- hash 永远不会提交到服务端,路由完全由前端控制
14、H5 history 路由?
特点:
- 是规范的url 路由,没有#号,跳转不会刷新页面
- history.pushState({name:‘page’,‘’,‘page’}) , 跳转页面
- history.onpopstate() 监听浏览器前进后退
- 需要后端配合
16、vue的真题演练哈哈哈
(1) 、为什么在v-for中使用key
- 必须要用key,要不然vscode会报错,并且key 不能使用index,可使用id,或唯一的标识
- diff算法是通过tage和key来进行判断新旧虚拟dom是否相同的重要值
- 有key值之后就可以减少dom的渲染次数,提升渲染性能
(2)、vue组件间的通讯
- 父子组件props 和
$emit
- 组件间: 自定义事件
event.$on() 、event.$emit()、event.$off()
来进行通讯
import event from './event.js';
/**
* event 文件就是vue 的实例,new Vue();
*/
// 组件1
mounted(){
// 绑定自定义事件
event.$on('eventName',this.change)
}
beforeDestory(){
// 销毁自定义事件
event.$off('eventName名',this.change);
}
// 组件2
// 触发自定义事件
event.$emit('addName',this.name);
- 组件间: vuex
** (3)、双向数据v-mode绑定的原理?**
- 因为模板编译的时候就已经给元素绑定了一个input事件,将
$event.target.value
赋值给v-model绑定的变量。当input的值发生改变的时候就会触发input事件,将input的值给v-model的变量,v-model绑定的变量发生了改变,就会重新触发render函数,页面就会重新渲染。
(4)、computed有何特点?
- 缓存,相关的data不变的话不会重新计算,可以提高性能
(5)、为何组件data必须是一个函数?
- 函数return一个数据,创建多个实例,实例一方修改数据其他实例是不受影响的,就相当于每个实例在堆中的指针是不同的。而vue组件是可以复用的,为了 让每个复用的组件中的数据不会相互影响,所以data必须是函数。
function fn (){
return {name:'a'}
}
const obj1 = fn()
const obj2 = fn()
obj1.name = 'b'
console.log('obj1,obj2',obj1,obj2) // {name:'b'} {name:'a'}
(6)、ajax应该放在哪个生命周期?
- 如果请求的数据跟DOM没有关系的话,最好是在created里面请求接口,因为在created里就已经可以获取data的数据,能进行异步请求,尽早的获取数据,有利于页面渲染,避免数据没有页面乱的情况。
- 如果跟dom有逻辑关系的话,就在mounted里进行接口请求。此时dom已经加载完成。
(7)、beforeDestory 在啥时候使用?
- 解除自定义事件,
$event.off()
- 清除定时器
- 解绑自定义的dom事件,如window. scroll 事件
(8)、vue 如何监听数组的变化?
- Object.definedProperty()不能监听数据的变化
- 重新定义原型,重写push、pop等数组方法,实现监听
- Proxy 原生可以支持监听数组的变化
** (9)、请描述响应式原理?**
- 主要说监听data的变化
- 组件初次渲染和更新的过程
(10)、vue常见的性能优化?
- 合理使用v-show和v-if
- 合理使用computed
- v-for中必须加key,以及避免和v-for一块使用
- 自定义事件和dom事件要及时销毁
- 合理使用异步组件
- 合理使用keep-alive 组件,避免多次渲染
- data 的层级不要太深
- 使用vue-loader 在开发环境下做模板编译
- webpack 的优化
- 使用ssr服务器端渲染
- 前端通用的性能优化,如图片懒加载等
17、vue3比vue2有什么优势?
- 性能更好了
- 体积更小
- 更好的ts支持
- 更好的代码组织
- 更好的逻辑抽离
- 更多的新功能
18、vue3 的生命周期?
vue3有两种生命周期,一种是vue2的options API的生命周期,一种是comp
- options 生命周期,将beforeDestory 改成beforeUnmount ,将destoryed改为unmounted,其他沿用vue2的生命周期
beforeCreate 、created、beforeMount、mounted、beforeUpate、updated、beforeUnmount、unmounted - composition API 生命周期:
setup() 相当于vue2的beforeCreat和created ;
onBeforeMount: 挂在前 ,等同于beforeMount
onMounted:挂在后,等同于 mounted
onBeforeUpdate:更新前,等同于beforeUpate
onUpdated: 更新后,等同于updated
onBeforeUnmount: 卸载前
onUnmounted: 卸载后
注意: 两种生命周期在一个vue文件中只能使用一种,不能同时使用。
19、compontion Api 带了啥?
- 更好的代码组织
- 更好的逻辑复用
- 更好的类型推导
19、ref的用法?
- 生成值类型的响应式数据
- 可以获取dom节点
- 可使用在reactive
- 通过.value修改值
用法
<template>
<p>我是:{{nameRef}}{{state.age}}</p>
<div ref="eleRef">这是一段文字</div>
</tempalte>
<script>
import {ref,active , onMounted} from 'vue'
export default {
name:'refDemo',
setup () {
const nameRef = ref('张三')
const ageRef = ref(20)
const eleRef = ref(null)
const state = active({
age:ageRef
})
setTimout(()=>{
nameRef.value('李四')
},1000)
onMounted(()=>{
console.log('获取dom',eleRef.value.innerHTML)
})
return {
nameRef,
state
}
}
}
</script>
20、toRef是什么?
- 将一个reactive创建的对象,要对对象的某个属性进行响应式,及可使用toRef
- 如果是个普通对象,不用reactive创建的,那么使用toRef,结果不具备响应式
<template>
<p>我是:{{ageRef}}-{{state.age}}</p>
</tempalte>
<script>
import {ref,toRef,active } from 'vue'
export default {
name:'refDemo',
setup () {
const state = active({
age:20,
name:'张三'
})
const ageRef = toRef(state,'age')
setTimout(()=>{
ageRef.value(25)
},1000)
return {
state,
ageRef
}
}
}
</script>
21、toRefs 是什么?
- 将影响式对象(reactive创建),变成普通对象
- 对象的每个prop都对应每个ref,就可以直接使用响应式里的属性
- 如果不是reactive创建的对象,使用普通对象,那么不具备响应式的特点,你改变值,页面不发生改变
<template>
<p>我是:{{ageRef}}-{{age}}</p>
</tempalte>
<script>
import {ref,toRefs,active } from 'vue'
export default {
name:'refDemo',
setup () {
const state = active({
age:20,
name:'张三'
})
const ageAsRefs = toRefs(state)
setTimout(()=>{
state.age.value(25)
},1000)
return ageAsRefs
}
}
</script>
toRefs 的最佳使用?
toRefs和toRef 的最佳使用
- 用reactive 做对象的响应式,是ref 做值类型的响应式
- setup中返回toRef(state,‘xx’)或toRefs(state),这样子就可直接使用变量
- ref的变量命名都用xxxRef
- 合成函数返回响应式对象时,使用toRefs,有利于对数据进行结构
为什么需要ref?
- 因为如果直接返回值类型的话,是不具备响应式的
- 而且在很多业务逻辑中,是需要返回值类型,使用reactive的话不太好
- 如果没有ref,用户会自己创建ref,到时候代码会更加混乱
为何需要.value?
- ref是一个对象,为了不丢失响应式,value存储值
- 通过.value属性的getter 和setter 实现响应式
- 用于template和reactive 时,不需要.value,其他情况都需要
为什么需要toRef和toRefs?
- 初衷: 在不丢失响应式的情况下,把对象数据解构
- 前提是:针对响应式对象(reactive)非普通对象
- 注意:不是创造响应式,而是延续响应式
22、vue3升级了哪些重要功能?
-
createAPP:创建vue实例跟vue2不一样了
-
emits:子传父的时候,子组件需要emits 声明父组件传过来的事件/值,然后再setup中有一个{emit}参数
-
多事件处理
-
fragment: 模板不需要使用一个大的div包裹起来了,可以有多个根节点
-
移除.sync,用v-model替代,父组件向子组件中传入变量,在子组件中可改变父组件传入的值,达到数据双向绑定的效果。
-
异步组件,引用defineAsyncComponent
-
teleport : 将结构插入body中去,比如将自定义弹窗插入body里
-
Suspense : 组件还没加载完之前的loading内容,一般用于异步组件。其实就是使用solt 封装的一个组件
-
Composition API:是一个高阶功能,应对项目中复杂的场景。
- reactive 创建响应式对象
- ref、toref、torefs
- readonly 只读
- watch 和watchEffact
- setup 相当于beforeCteat\created,也是compotions API的入口函数
- 生命周期
23、Compontions API如何实现代码逻辑的复用?
- 抽离逻辑代码到一个函数
- 函数命名约定为useXxx (react hooks 也是)
- 在setup中引用useXxx函数
24、proxy 的使用
- 创建一个new Proxy 实例
- 含有getter(只处理本身的属性)和setter(重复的数据不做处理)和deleteProperty(删除属性) 来监听数据的属性以及监听数组
- Reflect 的作用
- 和Proxy 配套使用
- 标准化、规范化、函数化
- 替代Object 上的工具函数
25、vue3 如何实现响应式?
- 深度监听,性能更好,(什么时候用到了再去监听)
- 可监听新增/删除属性
- 可监听数组的变化
缺点:
- 无法兼容所有浏览器,无法polyfill
26、vue3 v-model参数的用法?
- 父组件给子组件传递一个参数,子组件中修改这个参数,父组件的这个参数也跟着改变
// 父组件
<template>
<p>{{age}} {{name}}</p>
<Child v-model:age=‘age’. v-model:name=‘name’ />
</template>
// 子组件
<input :value=‘age’ @input=‘$emits(‘change:age’,$event.target.value)’ />
<input :value=‘name’ @input=‘$emits(‘change:name’,$event.target.value)’ />
26、watch 和 watchEffect的区别?
- 两者都可以监听data属性的变化
- watch 是需要明确监听哪个属性
- watchEffect会看执行的函数中有哪些属性,自动去监听这些属性的变化
27、setup中如何获取组件的实例(vue3中composition API中没有this)
- 在setup中和composition API 中没有this
- 可通过getCurrentInstance 获取当前实例
- 若使用optionsAPI 可以照常使用this
28、为什么vue3 比vue2 快?
-
Proxy 响应式
-
PatchFlag:流程的优化,在模板编译的时候就开始优化,使得diff算法也有优化的空间
- 编译模板时,动态节点做标记
- 标记分为不同的类型,如text、props
- diff算法时,可以区分静态节点,以及不同类型的动态节点,优化diff算法(针对动态节点的标记进行对比,静态节点不需要对比)
-
hoistStatic
- 将静态节点的定义,提升到父作用域缓存起来
- 多个相邻的静态节点会被合并起来
- 典型的拿空间换时间的策略
-
cacheHandler:缓存事件
-
SSR优化
- 静态节点直接输出,烧过虚拟dom
- 动态节点还是需要动态渲染
-
tree-shaking
- 编译的时候会根据不同的情况,引入不同的API
29、为什么Vite 启动特别快?
- Vite 是一个前端打包工具,是尤雨溪开发的项目;借助vue的影响力,发展较快,和webpack竞争;
- 优势:开发环境下无需打包,启动快
原因: - 开发环境使用es6 Module,无需打包,所以很快
- 生产环境使用rollup ,并不会快很多
30、vue3 中使用JSX语法?
定义一个.jsx的文件,引入defineComponent
import {defineComponent,ref } from 'vue';
export default defineComponent(()=>{
const numRef = ref(12);
const render =()=>{
return <>
<p>{numRef.value}</p>
</>
}
return render;
})
31 vue3中的JSX 和 template有什么区别?
- 语法有很大的区别
- JSX 本质是js代码,可以使用js的任何能力
- template只能嵌入简单的js表达式,其他需要的指令,如v-if
- jsx已经成为ES的规范,template还只是vue的规范
- 本质相同
- 两者都会编译成js代码(render函数)
32、vue3 中使用script setup简写
版本需在3.2以上才可用
33、Vue3 中script-setup中的属性和事件如何写?
-
defineProps
父组件中:
子组件中:
-
defineEmits