Nuxt3从入门到实战之插件机制&模块使用
2023-04-10 本文已影响0人
硅谷干货
前言
上一篇写了Nuxt3状态共享,本篇我们研究nuxt3的插件系统。通过插件系统,我们可以获取nuxt实例以及vue实例,这样我们有机会扩展nuxt或vue,比如引入一个UI库。
plugins目录
Nuxt3会自动读取plugins目录下的文件并加载它们。我们可以在文件名上使用.server或者.client前缀使他们仅作用于服务端或者客户端。
创建插件
使用defineNuxtPlugin()注册一个插件:
import { defineNuxtPlugin } from '#app'
// 唯一的参数是nuxt实例
export default defineNuxtPlugin(nuxtApp => {
// Doing something with nuxtApp
})
插件用例:自动提供帮助方法
一个常见应用是给NuxtApp实例提供一些额外的帮助方法,我们可以通过编写一个插件,返回一个对象,在里面设置provide
key,比如:
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin(() => {
return {
provide: {
hello: () => 'world'
}
}
})
使用这个helper,index.vue:
// 会自动加上$前缀
const { $hello } = useNuxtApp();
console.log($hello())
插件用例:访问Vue实例
如果想要扩展Vue,我们通常要访问Vue实例,引入Vue插件。在nuxt3中可以通过插件访问nuxtApp.vueApp.use(xxx)
做到。
我们引入vue-devui
试一下,前面我们曾经试图自动导入失败了,这里我们手动导入:
npm i vue-devui
创建一个插件vue-devui-plugin.ts:
import { defineNuxtPlugin } from "#app";
import { Button } from "vue-devui";
import 'vue-devui/button/style.css'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Button);
});
使用组件测试一下:
<d-button>按钮</d-button>
扩展
引入其他组件库尝试结果:
- naive-ui按官方方式在SFC中直接使用组件 引入就报错,参见:https://github.com/TuSimple/naive-ui/issues/1427又找到了这个回答:https://github.com/TuSimple/naive-ui/issues/636#issuecomment-945990935不过这个解决方案关闭了
vite
,不是我喜欢的风格,仅供大家可以参考!
import { NButton } from 'naive-ui'
<n-button>button</n-button>
- vant是可以的,不过暂时不知道样式如何按需引入,编写如下插件:可以看一下有赞官方有计划做一个next3+vant的demo
import { defineNuxtPlugin } from "#app";
import { Button } from 'vant';
import 'vant/lib/index.css'
// 这里如果引入 vant/lib/button/index.css是没有效果的
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Button)
});
-
element-plus官方有个starter项目:
https://github.com/element-plus/element-plus-nuxt-starter
只可惜也是全量引入,按需引入没交代,也明确了自动引入暂时支持不了。
使用模块
我们就使用一下pinia
,做一下项目的状态管理。
首先安装@pinia/nuxt
模块
npm i @pinia/nuxt
其次配置nuxt,添加到buildModules
中,nuxt.config.ts
export default {
buildModules: [['@pinia/nuxt', { disableVuex: true }]],
}
下面我们在项目中使用以下:
我们首先创建一个名为counter
的状态模块,stores/counter.ts
:
import { defineStore } from 'pinia'
// useStore 可以任意,比如 useUser, useCart
// 参数1是整个应用中唯一的store id
export const useStore = defineStore('counter', {
state() {
return {
count: 100
}
},
})
然后在组件中可以使用了,app.vue
const store = useStore();
使用数据:
<button @click="store.$patch({count: count-1})">-</button>
<p>{{ store.count }}</p>
<button @click="counter++">+</button>