你们有没有过这样的经历:在开发中突然需要使用 Vue3 的某些高级方法时,脑袋一片空白,感觉自己仿佛穿越到了另一个次元?
别担心,我也是这样过来的。不过幸运的是,今天我们要一起探讨 Vue3 的那些高阶方法和它们的使用场景,让你在未来的开发中游刃有余。
准备好了吗?让我们开始吧!
1. ref 和 reactive
首先,让我们从 Vue3 最基础也是最常用的两个方法开始:ref
和 reactive
。它们是管理状态的核心工具。
ref
ref
用于定义一个响应式的数据对象。它适用于单个基本类型或对象的场景。
import { ref } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++; }; return { count, increment }; } };
reactive
reactive
用于定义一个响应式的复杂对象。适用于包含多个属性的对象。
import { reactive } from 'vue'; export default { setup() { const state = reactive({ count: 0, name: 'Vue3' }); const increment = () => { state.count++; }; return { state, increment }; } };
2. toRefs
当我们使用 reactive
创建了一个复杂对象后,有时候需要将其解构为多个响应式的引用,这时候 toRefs
就派上用场了。
import { reactive, toRefs } from 'vue'; export default { setup() { const state = reactive({ count: 0, name: 'Vue3' }); return { ...toRefs(state) }; } };
3. watch 和 watchEffect
watch
watch
用于监听特定数据的变化并执行相应的回调函数。它可以用来监控一个或多个响应式数据。
import { ref, watch } from 'vue'; export default { setup() { const count = ref(0); watch(count, (newVal, oldVal) => { console.log(`Count changed from ${oldVal} to ${newVal}`); }); return { count }; } };
watchEffect
watchEffect
更为自动化,它会立即执行一次并响应任何依赖的变化。
import { ref, watchEffect } from 'vue'; export default { setup() { const count = ref(0); watchEffect(() => { console.log(`Count is now ${count.value}`); }); return { count }; } };
4. computed
computed
用于定义计算属性,它会根据依赖的变化自动更新。
import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubleCount = computed(() => count.value * 2); return { count, doubleCount }; } };
5. provide 和 inject
provide
provide
用于向下传递数据,通常在父组件中使用。
import { provide } from 'vue'; export default { setup() { provide('message', 'Hello from parent'); return {}; } };
inject
inject
用于在子组件中接收数据。
import { inject } from 'vue'; export default { setup() { const message = inject('message'); return { message }; } };
6. shallowRef 和 shallowReactive
shallowRef
shallowRef
仅对对象的第一层进行响应式处理。
import { shallowRef } from 'vue'; export default { setup() { const state = shallowRef({ count: 0 }); return { state }; } };
shallowReactive
shallowReactive
也是仅对对象的第一层进行响应式处理。
import { shallowReactive } from 'vue'; export default { setup() { const state = shallowReactive({ count: 0 }); return { state }; } };
7. customRef
customRef
允许你自定义对某个响应式对象的追踪逻辑。
import { customRef } from 'vue'; function useDebouncedRef(value, delay = 200) { let timeout; return customRef((track, trigger) => { return { get() { track(); return value; }, set(newValue) { clearTimeout(timeout); timeout = setTimeout(() => { value = newValue; trigger(); }, delay); } }; }); } export default { setup() { const debounced = useDebouncedRef(0); return { debounced }; } };
8. markRaw 和 isRef
markRaw
markRaw
用于标记一个对象永远不会成为响应式的。
import { markRaw } from 'vue'; const rawObject = markRaw({ count: 0 }); export default { setup() { return { rawObject }; } };
isRef
isRef
用于检查一个对象是否为 ref
。
import { ref, isRef } from 'vue'; export default { setup() { const count = ref(0); console.log(isRef(count)); // true return { count }; } };
9. getCurrentInstance
getCurrentInstance
可以用来获取组件实例,对于调试非常有用。
import { getCurrentInstance, onMounted } from 'vue'; export default { setup() { onMounted(() => { const instance = getCurrentInstance(); console.log(instance); }); return {}; } };
10. defineProps 和 defineEmits
defineProps
defineProps
用于在组合式 API 中定义接收的属性。
import { defineProps } from 'vue'; export default { setup() { const props = defineProps({ message: String }); return { props }; } };
defineEmits
defineEmits
用于在组合式 API 中定义发出的事件。
import { defineEmits } from 'vue'; export default { setup() { const emit = defineEmits(['update']); const updateMessage = () => { emit('update', 'New message'); }; return { updateMessage }; } };
11. teleport
teleport
允许你将内容渲染到指定的 DOM 元素中。
<template> <teleport to="#teleport-target"> <p>This will be teleported to another part of the DOM.</p> </teleport> </template> <script> export default { setup() { return {}; } }; </script>
12. Suspense
Suspense
用于处理异步组件的加载状态。
<template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <p>Loading...</p> </template> </Suspense> </template> <script> import { defineAsyncComponent } from 'vue'; const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue') ); export default { components: { AsyncComponent }, setup() { return {}; } }; </script>
13. v-model 的修饰符支持
Vue3 中 v-model
支持多个修饰符,比如 lazy
, number
, 和 trim
。
<template> <input v-model.lazy="text" /> </template> <script> import { ref } from 'vue'; export default { setup() { const text = ref(''); return { text }; } }; </script>
14. nextTick 函数
nextTick
用于在下次 DOM 更新循环结束后执行回调。
import { ref, nextTick } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++; nextTick(() => { console.log('DOM updated'); }); }; return { count, increment }; } };
15. defineAsyncComponent
defineAsyncComponent
用于定义异步组件。
import { defineAsyncComponent } from 'vue'; const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue') ); export default { components: { AsyncComponent }, setup() { return {}; } };
16. defineCustomElement
`define
CustomElement` 用于定义自定义元素。
import { defineCustomElement } from 'vue'; const MyCustomElement = defineCustomElement({ props: { message: String }, template: `<p>{{ message }}</p>` }); customElements.define('my-custom-element', MyCustomElement);
17. v-model 的定制
你可以自定义 v-model
的绑定和事件。
export default { props: { modelValue: String }, emits: ['update:modelValue'], setup(props, { emit }) { const updateValue = (event) => { emit('update:modelValue', event.target.value); }; return { updateValue }; } };
18. teleport 和 Fragment 的简写
在 Vue3 中,teleport
和 Fragment
的简写方式更加简洁。
<template> <Teleport to="#teleport-target"> <p>Teleported content</p> </Teleport> </template> <script> export default { setup() { return {}; } }; </script>
总结
通过这篇文章,我们深入探讨了 Vue3 的高阶方法及其使用场景。
希望这些内容能够帮助你在开发中更加得心应手。