likes
comments
collection

vite 脚手架使用教程(四)- NaiveUI 的安装

作者站长头像
站长
· 阅读数 86

vite 脚手架使用教程(一)-新建项目

vite 脚手架使用教程(二)-vue-router使用

vite 脚手架使用教程(三)-Pinia的使用&环境配置

建议按序观看

我们把基本的全家桶安装完成之后,就该开始配置 UI 组件库了。那么作为一个脚手架安装 UI 组件库,有以下几种方式。

全局安装(不推荐)

import { createApp } from 'vue'
import naive from 'naive-ui'

const app = createApp(App)
app.use(naive)

然后在全局直接使用

<template>
  <n-button>naive-ui</n-button>
</template>

缺点: 当你去使用一个 UI 组件库的时候,你会发现有很多的组件,其实你本没有使用,但是这样引入的话,会导致,整体打出来的包很大。

使用 UMD

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/vue"></script>
    <!-- 会使用最新版本,你最好指定一个版本 -->
    <script src="https://unpkg.com/naive-ui"></script>
  </head>
  <body>
    <div id="app">
      <n-button>{{ message }}</n-button>
    </div>
    <script>
      const App = {
        setup() {
          return {
            message: 'naive'
          }
        }
      }
      const app = Vue.createApp(App)
      app.use(naive)
      app.mount('#app')
    </script>
  </body>
</html>

在页面中直接加载 umd 版本,好处就是利用了 http的多个下载线程,直接下载 UI 组件库的包,速度比全局要快。缺点就是依旧包很大,整体下载的意义不大。

按需全局安装

import { NInput , useMessage } from 'naive-ui'

export const setupUi = (app: App): void => {
    const components = [NInput]

    components.forEach((component) => {
        app.component(component.name, component)
    })

    app.config.globalProperties.$message = useMessage
}

按照前文的说法,可以做一个创建,然后再 main.ts种引入,最后做到按需部分加载,这样的设计在 webpack 中很常见,可以省去在.vue页面中的直接引用。

页面中按需引用

<template>
  <n-button>naive-ui</n-button>
</template>

<script setup lang='ts'>
import { NButton } from 'naive-ui'
    
</script>

自动引入

我个人学习的时候,发现这种方式可能是 vite 中的一大特色,他可以做到直接使用,并且直接处理对应管理,已达到项目中,即不用再页面中引入,又可以按需加载。

按需自动加载UI组件:   unplugin-vue-components

安装

pnpm i -D unplugin-auto-import

该插件主要作用是省去每次使用一个自定义组件,或UI组件库的组件时对组件的引入。兼容不同UI组件库,需要在安装对应UI组件库的前提下,并引入对应UI组件库的 resolvers

改组件提供各种 UI 组件库的resolvers

// 当引入 "unplugin-vue-components/vite 组件之后,页面中需要引入组件的地方就都不需要引入了
import Components from "unplugin-vue-components/vite";
// 引入对应 UI库的 resolver,则对应UI组件库的组件也不需要单独引入了
import {
    AntDesignVueResolver,
    ElementPlusResolver,
    VantResolver,
    NaiveUiResolver,
} from "unplugin-vue-components/resolvers";

AutoImport

// 实现 Vue及Vue相关的库、api的 按需加载
import AutoImport from "unplugin-auto-import/vite";
AutoImport({
    imports: ["vue", "vue-router", "pinia"],
})

举一个例子

<script setup> 
   <!-- ref 也不需要引入 -->
     const counter = ref(0);
     const add = () => counter.value++;
</script>
<template>
      <div>{{ counter }}</div>
      <button @click="add">counter+1</button>
    <!-- 以下组件都可以直接引入 -->
    <Foo></Foo>
    <el-button>elmentplus button</el-button>
    <n-button>naiveui button</n-button>
</template>

处理 vite.config.ts文件

通常看到的config文件

export default defineConfig({
   plugins: [vue()]
})

这样写的缺点就是在未来,我想要配置多的 mode (模式) 的时候就会有一些问题

import { loadEnv } from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'

const CWD = process.cwd();
export default ({ mode }: ConfigEnv): UserConfig => {
 const { VITE_NODE_ENV } = loadEnv(mode, CWD)
 const isProd = ['development', 'test', 'production'].includes(VITE_NODE_ENV)
 
 return {
   plugins: [vue()]
 }
}

配置自动导入

import vue from "@vitejs/plugin-vue";

// 当引入 "unplugin-vue-components/vite 组件之后,页面中需要引入组件的地方就都不需要引入了
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { NaiveUiResolver } from "unplugin-vue-components/resolvers";
import type { UserConfig, ConfigEnv } from "vite";

const CWD = process.cwd();
export default ({ mode }: ConfigEnv): UserConfig => {
  const { VITE_NODE_ENV } = loadEnv(mode, CWD);
  const isProd = ["development", "test", "production"].includes(VITE_NODE_ENV);
  console.log(isProd);
  
  return {
    plugins: [
      vue(),
      AutoImport({
        imports: [
          "vue",
          "vue-router",
          "pinia",
          {
            "naive-ui": [
              "useDialog",
              "useMessage",
              "useNotification",
              "useLoadingBar",
            ],
          },
        ],
      }),
      Components({
        resolvers: [NaiveUiResolver()],
      }),
    ],
  };
};

写一个页面测试一下

<template>
  <n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />

  <n-layout has-sider>
    <n-layout-sider content-style="padding: 24px;"> 海淀桥 </n-layout-sider>
    <n-layout>
      <n-layout-header>颐和园路</n-layout-header>
      <n-layout-content content-style="padding: 24px;">
        <router-view />
      </n-layout-content>
      <n-layout-footer>成府路</n-layout-footer>
    </n-layout>
  </n-layout>
</template>

<script lang="ts" setup>
import type { MenuOption } from "naive-ui";
import { RouterLink } from "vue-router";

const options: MenuOption[] = [
  {
    label: () =>
      h(
        RouterLink,
        {
          to: {
            name: "Home",
            params: {
              lang: "zh-CN",
            },
          },
        },
        { default: () => "回家" }
      ),
    key: "hear-the-wind-sing",
  },
  {
    label: () =>
      h(
        RouterLink,
        {
          to: {
            name: "About",
            params: {
              lang: "zh-CN",
            },
          },
        },
        { default: () => "About" }
      ),
    key: "a-wild-sheep-chase",
  },
];

const activeKey = ref<string | null>(null);
const menuOptions = reactive(options);
</script>

<style scoped>
.n-layout-header,
.n-layout-footer {
  background: rgba(128, 128, 128, 0.2);
  padding: 24px;
}

.n-layout-sider {
  background: rgba(128, 128, 128, 0.3);
}

.n-layout-content {
  background: rgba(128, 128, 128, 0.4);
}
</style>

页面成果

vite 脚手架使用教程(四)- NaiveUI 的安装