对于vue3新增特性,可以先看下这篇。vue3对比vue2新增特性 本文进行进一步补充
setup
在 Vue 3 中,setup是一个新的组件选项,它是组合式 API 的入口点。组合式 API 允许开发者以函数的形式组织组件逻辑,让代码更具复用性和可维护性。
<template>
<div>
<p>{{ message }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
// 使用 ref 创建响应式数据
const message = ref("Hello, Vue 3!");
const count = ref(0);
// 定义方法
const increment = () => {
count.value++;
};
// 返回需要在模板中使用的属性和方法
return {
message,
count,
increment,
};
},
};
</script>
在实际开发中,通常使用语法糖形式
<template>
<div>
<p>message:{{ message }}</p>
<p>count:{{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref } from "vue";
// 使用 ref 创建响应式数据
const message = ref("Hello, Vue 3!");
const count = ref(0);
// 定义方法
const increment = () => {
count.value++;
};
</script>
运行效果是一样的
readonly和shallowReadonly
readonly创建一个只读的响应式对象,对该对象的属性进行修改操作不会生效,可用于防止数据被意外修改。
shallowReadonly与 readonly类似,但仅对对象的顶层属性设置为只读,深层嵌套的对象仍然可以修改。
<template>
<div>
<p>readInfo: {{ readInfo.name }} --{{ readInfo.detail.age }}</p>
<p>shadollInfo: {{ shadollInfo.name }} --{{ shadollInfo.detail.age }}</p>
<button @click="changeInfo">changeInfo</button>
<button @click="changeShadollInfo">changeShadollInfo</button>
</div>
</template>
<script setup>
import { isReactive, readonly, shallowReadonly } from 'vue';
const readInfo=readonly({name:'zs',detail:{age:11}});
const changeInfo=()=>{
readInfo.name='aaaa';
readInfo.detail.age=22;
console.log('readInfo',readInfo);
}
const shadollInfo=shallowReadonly({name:'ls',detail:{age:33}})
const changeShadollInfo=()=>{
shadollInfo.name='bbbb';
shadollInfo.detail.age=66;
console.log('shadollInfo',shadollInfo,isReactive(shadollInfo.detail.age));
}
</script>
在方法里打印了修改后的值,可以看到readInfo的值完全没有被修改。shallowReadonly只会对第一层对象生效设置为只对,修改detail里面的age从打印结果看已经被修改了且可以看到它并不是响应式的所以视图也没有更新
toRaw和markRaw
在某些情况下,对数据的操作可能会触发大量不必要的响应式更新,导致性能下降。
toRaw用于返回一个响应式对象的原始对象。
markRaw用于标记一个对象,使其永远不会被转换为响应式对象。
<template>
<div>
<p>{{ state.message }}</p>
<button @click="updateWithToRaw">Update with toRaw</button>
<button @click="updateWithMarkRaw">Update with markRaw</button>
</div>
</template>
<script setup>
import { reactive, toRaw, markRaw, } from "vue";
const state={message: "Hello, Vue 3!"}
const reactiveState = reactive(state);
// 使用 toRaw 操作
const updateWithToRaw = () => {
// toRaw(reactiveState)返回了原始对象,所以值为true
console.log(toRaw(reactiveState)===state);
};
// 使用 markRaw 操作
const nonReactiveObj = markRaw({
message: "message不是响应式的",
});
const updateWithMarkRaw = () => {
nonReactiveObj.message = "尝试更新nonReactiveObj.message";
// 由于是非响应式对象,页面不会更新
console.log('nonReactiveObj.message:',nonReactiveObj.message);
};
</script>
片段(Fragments)
在 Vue 2 中,组件必须有一个根元素,而在 Vue 3 中,组件可以返回多个根元素,形成片段。
<template>
<div class="box">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
</template>
<style>
.box{
width: 200px;
height: 100px;
border: 1px solid red;
}
.box2{
border: 1px solid blue;
}
.box3{
border: 1px solid orange;
}
</style>
watch和watchEffect
watch和watchEffect都是用于响应式地执行副作用的 API,但它们在使用方式、依赖追踪、触发时机等方面存在一些区别
<template>
<div class="box">
<p @click="num++"> num:{{num}}</p>
<p @click="num2++"> num2:{{num2}}</p>
</div>
</template>
<script setup>
import { ref,watch, watchEffect} from 'vue';
const num=ref(0);
const num2=ref(0);
// wacth监听需要指定监听数据源,可以是一个响应式引用(ref)、计算属性(computed)、响应式对象的属性等。
// 需要手动指定依赖,只有指定的依赖发生变化时,回调函数才会执行。
// 默认情况下,只有在依赖的值发生变化时才会触发回调函数。可以通过 immediate 选项设置为 true 来让回调函数在初始渲染时也执行一次
// 回调函数接收两个参数,分别是新值和旧值,可以方便地对比变化前后的值
watch(num, (newValue, oldValue) => {
console.log(`num 从 ${oldValue} 变为 ${newValue}`);
},{immediate:true});
watch(num2, (newValue, oldValue) => {
console.log(`num2 从 ${oldValue} 变为 ${newValue}`);
},{immediate:true});
// watchEffect不需要显式指定依赖,它会自动追踪其回调函数中所使用的所有响应式数据。
// 自动收集回调函数中使用的所有响应式依赖,只要这些依赖中的任何一个发生变化,回调函数就会重新执行
// 回调函数会在初始渲染时立即执行一次,并且在依赖发生变化时也会重新执行
// 回调函数不接收任何参数,因为它主要关注副作用的执行,而不是值的变化
watchEffect(()=>{
console.log(`num:${num.value} | num2:${num2.value}`);
})
</script>
<style>
.box{
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
点击p标签的时候分别让num,num2++,由于设置了{immediate:true},watchEffect回调函数会在初始渲染时立即执行一次。当页面渲染完成后会立即打印
点击num,num++,watch监听到num的变化执行了回调,num的值发生了变化watchEffect也执行了回调。点击num2同理
end
如有误欢迎指正