网站keywords,艺商网站,好听的房地产公司名字,网站需要怎么做的vue3有选项式API#xff08;和vue2一样保留this用法#xff09;和组合式API#xff08;没有了this的概念#xff09;#xff1b;选项式 API 是在组合式 API 的基础上实现的#xff01; 增加了组合式api#xff0c;利于代码逻辑的组合#xff0c;相关联的逻辑汇集在一处… 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
templatep refpElementRefhello/p
/templatevue3中的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.countvue3的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 watchEffectwatch 和 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 更新后执行 */
})