vue3学习记录
-
vue3有选项式API(和vue2一样保留this用法)和组合式API(没有了this的概念);选项式 API 是在组合式 API 的基础上实现的!
-
增加了组合式api,利于代码逻辑的组合,相关联的逻辑汇集在一处,易于代码的维护;
-
增加setup的语法,组合式 API 通常会与 setup 搭配使用;
-
vue3模板代码支持多个根节点(vue2只有一个根节点);
-
vue3组合式API增加ref和reactive声明响应式数据
-
ref在js中需要使用.value方式获取值,在模板中,ref 会自动解包则不需要.value获取值;
-
ref在模板中解包的注意事项:在模板渲染上下文中,只有顶级的 ref 属性才会被解包
const count = ref(0) const object = { id: ref(1) } // 模板代码 // 可以正常工作 {{ count + 1 }} // 下面的无非正常工作(会输出[object Object]1),因为在计算表达式时 object.id 没有被解包,仍然是一个 ref 对象 {{ object.id + 1 }} // 可以利用结构来解决该问题 const { id } = object {{ id + 1 }} // 输出2 // 另一个需要注意的点是,如果 ref 是文本插值的最终计算值 (即 {{ }} 标签),那么它将被解包,因此以下内容将渲染为 1 // 该特性仅仅是文本插值的一个便利特性,等价于 {{ object.id.value }} {{ object.id }}
-
reactive() 只适用于对象 (包括对象、数组和内置类型,如 Map 和 Set)。而另一个 API ref() 则可以接受任何值类型
-
reactive不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失,例如下面的例子:
let state = reactive({ count: 0 }) // 上面的 ({ count: 0 }) 引用将不再被追踪 // (响应性连接已丢失!) state = reactive({ count: 1 })
-
reactive对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接
const state = reactive({ count: 0 }) // 当解构时,count 已经与 state.count 断开连接 let { count } = state // 不会影响原始的 state count++ // 该函数接收到的是一个普通的数字 // 并且无法追踪 state.count 的变化 // 我们必须传入整个对象以保持响应性 callSomeFunction(state.count)
-
-
vue3组合式与TS更好的适配;
-
vue3增加hooks;
-
生命周期重命名beforeDestroy->beforeUnmount、destroyed->unmounted
-
声明ref例子(单文件组件的setup语法)
<script setup> import { ref, onMounted } from 'vue' // 注意这个 ref 使用 null 值来初始化。这是因为当 <script setup> 执行时,DOM 元素还不存在。模板引用 ref 只能在组件挂载后访问 const pElementRef = ref(null) onMounted(() => { pElementRef.value.textContent = 'mounted!' }) </script> <template> <p ref="pElementRef">hello</p> </template>
-
vue3中的watch函数,watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:
const x = ref(0) const y = ref(0) // 单个 ref watch(x, (newX) => { console.log(`x is ${newX}`) }) // getter 函数 watch( () => x.value + y.value, (sum) => { console.log(`sum of x + y is: ${sum}`) } ) // 多个来源组成的数组 watch([x, () => y.value], ([newX, newY]) => { console.log(`x is ${newX} and y is ${newY}`) }) const obj = reactive({ count: 0 }) // 错误,因为 watch() 得到的参数是一个 number watch(obj.count, (count) => { console.log(`count is: ${count}`) }) // 正确,提供一个 getter 函数 watch( () => obj.count, (count) => { console.log(`count is: ${count}`) } ) // 深层侦听器,慎用,监听的数据过大时,会有性能问题 const obj = reactive({ count: 0 }) watch(obj, (newValue, oldValue) => { // 在嵌套的属性变更时触发 // 注意:`newValue` 此处和 `oldValue` 是相等的 // 因为它们是同一个对象! }) obj.count++
-
vue3的watchEffect():
// 繁琐示例: const todoId = ref(1) const data = ref(null) watch( todoId, async () => { const response = await fetch( `https://jsonplaceholder.typicode.com/todos/${todoId.value}` ) data.value = await response.json() }, { immediate: true } ) // 利用watchEffect重写上面例子,回调会立即执行,不需要指定 immediate: true。 // 在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。 // 每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。 watchEffect(async () => { const response = await fetch( `https://jsonplaceholder.typicode.com/todos/${todoId.value}` ) data.value = await response.json() }) // 对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。 // 但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。 // 此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
- watch vs watchEffect?,watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
-
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch
会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。 -
watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。
- watch和watchEffect的回调的触发时机,默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: ‘post’ 选项:
watch(source, callback, { flush: 'post' }) watchEffect(callback, { flush: 'post' }) // 后置刷新的 watchEffect() 有个更方便的别名 watchPostEffect(): import { watchPostEffect } from 'vue' watchPostEffect(() => { /* 在 Vue 更新后执行 */ })
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!