Vue 特殊 API
这里所谓特殊 API 是指这些 API 只能在 setup script 中使用。而不能在任意的自定义服务中随意使用。
defineProps
强制要求只能在 setup script 中使用
defineEmits
强制要求只能在 setup script 中使用
defineModel
强制要求只能在 setup script 中使用
defineExpose
强制要求只能在 setup script 中使用
defineOptions
强制要求只能在 setup script 中使用
defineSlots
强制要求只能在 setup script 中使用
useSlots
依赖 setupContext,否则抛出 warning 信息
useAttrs
依赖 setupContext,否则抛出 warning 信息
useModel()
依赖 setupContext,否则抛出 warning 信息
官方文档不推荐使用这个 API,应该优先使用 defineModel
useTemplateRef()
依赖 setupContext,否则抛出 warning 信息
useId()
依赖 setupContext,否则抛出 warning 信息
useRootService vs useAppService
如果是在多 vue app 实例的项目中,或者在服务器端渲染的项目中。建议使用 useAppService 代替 useRootService。
如果是 CSR 项目,且只有一个 vue app 实例,那么就可以无脑使用 useRootService,不用考虑 useAppService 的问题。
从 API 使用角度来看 useRootService 不依赖具体 vue app 实例,可以直接在任意地方使用。
但是 useAppService 需要依赖具体的 vue app 实例,所以需要考虑如何获取指定的 vue app 实例对象。
在 nuxtjs 项目中,可以通过useNuxtApp
获取当前的 nuxtApp 实例,再通过nuxtApp.vueApp
获取 vue app 实例。
其中useNuxtApp
可以在这些地方直接使用:plugin, Nuxt hook, Nuxt middleware, or Vue setup function
vue 指令中访问 useAppService
import { defineNuxtPlugin } from '#imports';
import authDirective from '~/directives/auth';
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.directive('auth', authDirective(nuxtApp.vueApp));
});
实际上单纯在指令内部是不能直接访问到 vue app 实例的,目前可行的方案就是利用 js 闭包来访问 vue app 实例对象。
middleware 中访问 useAppService
export default defineNuxtRouteMiddleware(async (to, from) => {
const nuxtApp = useNuxtApp();
});
defineNuxtRouteMiddleware 中可以通过 useNuxtApp 获取 nuxtApp 对象
defineNuxtPlugin 内部访问 useAppService
export default defineNuxtPlugin(nuxtApp => {
// xxx
});
defineNuxtPlugin 中可以直接获取 nuxtApp
utils 工具方法中访问 useAppService
第 1 种方案是手动把 utils 方法转为 service,然后利用依赖注入能力直接注入想要的服务即可。
第 2 种方案则是需要集中管理 vue app 实例对象。
let vueApp = null;
function setVueApp(app) {
vueApp = app;
}
function getVueApp() {
return vueApp;
}
这样只需要在合适的时机调用setVueApp
方法初始化一下 vueApp 变量即可。后续就可以随时调用getVueApp
获取 vueApp 实例了。