v-bind 绑定的值是 null 或者 undefined
v-bind 如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。
当attribute 为布尔型时, 行为略有不同。
<button :disabled="isButtonDisabled">Button</button>
当 isButtonDisabled 为真值或一个空字符串 (即 <button disabled="">) 时,元素会包含这个 disabled attribute。而当其为其他假值时 attribute 将被忽略。
计算属性副作用
计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。
在计算属性中使用 reverse() 和 sort() 的时候务必小心!这两个方法将变更原始数组,计算函数中不应该这么做。
- return numbers.reverse()
+ return [...numbers].reverse()
在内联事件处理器中访问事件参数
有时我们需要在内联事件处理器中访问原生 DOM 事件。你可以向该处理器方法传入一个特殊的 $event 变量,或者使用内联箭头函数:
<!-- 使用特殊的 $event 变量 -->
<button @click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
<!-- 使用内联箭头函数 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">
Submit
</button>
生命周期函数
并不意味着对 onMounted 的调用必须放在 setup() 或 <script setup> 内的词法上下文中。onMounted() 也可以在一个外部函数中调用,只要调用栈是同步的,且最终起源自 setup() 就可以。

- https://cn.vuejs.org/guide/essentials/lifecycle.html
侦听器 watch/watchEffect
// 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}`)
})
注意,不能直接侦听响应式对象的属性值。这里需要用一个返回该属性的 getter 函数:
// 提供一个 getter 函数
watch(
() => state.someObject,
(countsomeObject => {
console.log(someObject)
}
)
直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发。
返回响应式对象的 getter 函数,只有在返回不同的对象时,才会触发回调,你也可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器:
watch(
() => state.someObject,
(newValue, oldValue) => {
// 注意:`newValue` 此处和 `oldValue` 是相等的
// *除非* state.someObject 被整个替换了
},
{ deep: true }
)
watchEffect() 允许我们自动跟踪回调的响应式依赖
watchEffect(async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
})
它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。
- 对于有多个依赖项的侦听器来说,使用
watchEffect()可以消除手动维护依赖列表的负担。 - 需要侦听一个嵌套数据结构中的几个属性,
watchEffect()可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
回调的触发时机
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: 'post' 选项:
watch(source, callback, {
flush: 'post'
})
watchEffect(callback, {
flush: 'post'
})
后置刷新的 watchEffect() 有个更方便的别名 watchPostEffect().
ref
只可以在组件挂载后才能访问模板引用。如果你想在模板中的表达式上访问 input,在初次渲染时会是 null。这是因为在初次渲染前这个元素还不存在呢!如果你需要侦听一个模板引用 ref 的变化,确保考虑到其值为 null 的情况:
const input = ref(null)
watchEffect(() => {
if (input.value) {
input.value.focus()
} else {
// 此时还未挂载,或此元素已经被卸载(例如通过 v-if 控制)
}
})
除了使用字符串值作名字,ref attribute 还可以绑定为一个函数,会在每次组件更新时都被调用。该函数会收到元素引用作为其第一个参数:
<input :ref="(el) => { /* 将 el 赋值给一个数据属性或 ref 变量 */ }">
注意我们这里需要使用动态的 :ref 绑定才能够传入一个函数。当绑定的元素被卸载时,函数也会被调用一次,此时的 el 参数会是 null。
组件上的 ref
使用了 <script setup> 的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露:
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
a,
b
})
</script>














![[CVPR 2023] Imagic:使用扩散模型进行基于文本的真实图像编辑](https://img-blog.csdnimg.cn/img_convert/5c990ea9f7674e7e1bab2c127615339c.png)




