VUE3学习手札
vue3成长之路学习笔记
文章目录
- VUE3学习手札
- 前言
- 一、markRaw
-
-
- [1.1 代码示例](#1.1 代码示例)
- [1.2 应用场景](#1.2 应用场景)
- [1.3 拓展(toRaw)](#1.3 拓展(toRaw))
- [1.4 实际应用](#1.4 实际应用)
-
- [二、ref 和 reactive](#二、ref 和 reactive)
前言
主要用于自己的一个备忘,对知识点的查缺补漏
一、markRaw
将一个对象标记为不可被转为代理。返回该对象本身。
从而使其不会被 reactive 包裹,也就不会成为 Vue3 中的响应式对象
1.1 代码示例
javascript
<template>
<div>
<p> 姓名: {{person.name}}</p>
<p> 性别: {{person.sex}}</p>
<p> 爱好: {{person.likes}}</p>
<el-button @click="change">按钮</el-button>
</div>
</template>
<script setup>
import { reactive, markRaw } from 'vue'
let person = reactive({
name: '张三',
sex: '男',
})
let likes = ['吃饭', '睡觉']
// 往响应式对象中新增一个likes属性,该属性是响应式
// 但是我们使用markRaw包裹后这个likes属性值是不具有响应式的
person.likes = markRaw(likes)
// 因此试图是不会更新的
let change = () => {
person.likes[0] = '我要吃饭'
person.likes[1] = '我要睡觉'
console.log(person.likes)
}
</script>
// 视图不会发生改变!!!
我们通过 markRaw 方法将 state.obj 标记为非响应式对象。这样做可以避免对 obj 的修改引起意外的响应式更新。
需要注意的是,一旦一个对象被标记为"非响应式",它就无法再被 reactive 进行包裹成为响应式对象。所以在使用 markRaw 方法时,我们需要确保这个对象在后续的代码中不需要作为响应式对象来使用或者监听其变化
1.2 应用场景
- 有些值不应被设置成响应式时,例如复杂的第三方类库等
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能
- 在动态渲染组件的时候我们就可以使用 markRaw 包裹。
1.3 拓展(toRaw)
markRaw 是声明(标记)一个不响应式的数据,
toRaw是将一个响应式的数据转化(还原)成不响应式的数据
代码示例
javascript
<template>
<div>
<el-button @click="change">自增</el-button>
数值变化:
<p>{{ state.count }}</p>
</div>
</template>
<script setup>
const state = reactive({
count: 0,
})
// 获取原始对象
const rawState = toRaw(state)
// 验证原始对象与包装后的对象是否相等
console.log(rawState === state) // false
function change() {
// 改变原始对象的值
rawState.count += 1
// 验证包装后的对象是否也受到了改变
console.log(state.count) // 1
}
</script>
// 视图不会发生改变!!!
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b2fef4e5513d4dc88c9f415d3efc49c9.png)
1.4 实际应用
代码示例:
javascript
<template>
<el-tabs v-model="tabName"
@tab-click="tabClick">
<el-tab-pane label="组件A"
name="a"></el-tab-pane>
<el-tab-pane label="组件B"
name="b"></el-tab-pane>
<el-tab-pane label="组件C"
name="c"></el-tab-pane>
<el-tab-pane label="组件D"
name="d"></el-tab-pane>
</el-tabs>
<component :is="currentComponent[tabName]"></component>
</template>
<script setup>
import ComponentA from './ComponentA'
import ComponentB from './ComponentB'
import ComponentC from './ComponentC'
import ComponentD from './ComponentD'
const tabName = ref('ComponentA')
const currentComponent = {
a: markRaw(ComponentA),
b: markRaw(ComponentB),
c: markRaw(ComponentC),
d: markRaw(ComponentD),
}
/* tab切换 */
function tabClick(val) {
console.log('val.paneName', val.paneName, currentComponent)
}
</script>
二、ref 和 reactive
从vue2到vue3,组合式api语法结构上,很重要一块data内的声明变量变成了,使用ref()或使用reactive()来进行包裹,以实现响应式变化,但是有时候在使用上会有一些心智负担,什么时候使用ref(),什么时候使用reactive(),官方文档的释义说明:响应式:核心
整个 data 这一部分的内容,你只需要记住下面这一点。
以前在 data 中创建的属性,现在全都用 ref() 声明。
在 template 中直接用,在 script 中记得加 .value
Vue3 里,还提供了一个叫做 reactive 的 api。
但是我的建议是,你不需要关心它。绝大多数场景下,ref 都够用了
对比
Ref
- 基本用法:Ref用于创建一个响应式的基本数据类型,如数字、字符串等。通过ref函数创建,访问和修改数据值需要使用.value。
- 在setup()中使用:在setup()函数中,我们可以使用ref来创建响应式数据,并在模板中使用。
- < script setup >语法:< script setup >语法是Vue3推荐的一种写法,可以在单文件组件中更简洁地使用ref。
- 为何使用ref:Ref适用于管理简单的基本数据类型,如数字、字符串等。
示例:
javascript
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => {
count.value++;
};
</script>
Reactive
- 基本概念:Reactive用于创建一个响应式对象,可以包含多个属性。通过reactive函数创建,对象的任何属性变化都会被检测到。
- 在模板中使用Reactive:在模板中可以直接使用响应式对象,对对象的属性进行访问和修改。
- 深层响应式:Reactive会递归地将对象的所有嵌套属性都变成响应式。
- 与ref区别:Ref适用于简单数据类型,而Reactive适用于对象,可以处理对象的多个属性。
- 为何使用Reactive:Reactive适用于管理复杂对象,使整个对象都变成响应式。
示例:
javascript
<template>
<div>
<p>User Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
<p>Order ID: {{ order.orderId }}</p>
</div>
</template>
<script setup>
import { reactive } from 'vue';
const user = reactive({
name: 'Alice',
age: 30
});
const order = reactive({
orderId: '123456'
});
</script>
比较和选择
性能和适用场景:Ref比Reactive轻量,适合简单数据;Reactive适合处理复杂对象。根据具体场景选择。
对象的处理:Ref处理单一数据,Reactive处理对象及其嵌套属性。
局限性和注意事项:Ref不能直接处理对象,Reactive在处理大型数据对象时可能影响性能。
总结:使用Ref处理简单数据类型,Reactive处理复杂对象