Skip to content

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 ​

ts
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 ​

ts
export default defineNuxtRouteMiddleware(async (to, from) => {
  const nuxtApp = useNuxtApp();
});

defineNuxtRouteMiddleware 中可以通过 useNuxtApp 获取 nuxtApp 对象

defineNuxtPlugin 内部访问 useAppService ​

ts
export default defineNuxtPlugin(nuxtApp => {
  // xxx
});

defineNuxtPlugin 中可以直接获取 nuxtApp

utils 工具方法中访问 useAppService ​

第 1 种方案是手动把 utils 方法转为 service,然后利用依赖注入能力直接注入想要的服务即可。

第 2 种方案则是需要集中管理 vue app 实例对象。

ts
let vueApp = null;
function setVueApp(app) {
  vueApp = app;
}
function getVueApp() {
  return vueApp;
}

这样只需要在合适的时机调用setVueApp方法初始化一下 vueApp 变量即可。后续就可以随时调用getVueApp获取 vueApp 实例了。