vite + vue3 + setup + pinia + бой проекта ts

внешний интерфейс Vue.js
vite + vue3 + setup + pinia + бой проекта ts

представлять

один используетvite + vue3 + pinia + ant-design-vue + typescriptПроект разработан по полному техническому маршруту, начинается обновление разработки второго уровня, новыйvue3 composition apiкомбинироватьsetupПобалуйте себя плавным процессом разработки, новымpiniaГосударственные менеджеры и большой опыт проектирования (1kразмер),antdБеспроблемные переходы с использованием библиотеки компонентов пользовательского интерфейсаant-design-vue, безопасный и эффективныйtypescriptПоддержка типов, проверка спецификации кода, многоуровневое управление разрешениями~

предисловие

Я получил запрос два дня назад, то есть извлечь основные функциональные модули и систему разрешений пользовательских модулей исходного проекта, чтобы сделать новый фоновый проект, и итеративно добавить некоторые новые функции, похоже, нечего.

Я получил исходный код и посмотрел на проект, молодец, исходный проект - это проект микроприложения, а основной пользовательский модуль приложения -reactСтек технологий, модули подприложенийvue2Технологический стек, похоже прямое резюме Дафа не получится 👀, ведь то, что я хочу сделать, это одностраничное приложение, просто определить технический маршрут, посмотреть логику кода и запустить его, чтобы увидеть

Запустите его и попробуйте. Оба проекта в основном запускаются примерно за 1 минуту. Глядя на код, весь код бизнес-логики проекта vue написан одним куском.

Я думал, что когда я раньше спрашивал у босса исходники, он говорил, что это старый проект, и надо быстрее собрать новый.

В этом нет ничего плохого, мне нечего сказать, просто начните все это, на этот раз я пойду прямоvite + vue3

emoji

характеристика

  • ✨ Инструмент для строительных лесов: эффективный и быстрыйVite
  • 🔥Front-end framework: самое модное сейчасVue3
  • 🍍Менеджер статуса:vue3новобранецPinia, как будтоreact zustandнравится опыт, дружественный API и асинхронная обработка
  • 🏆Язык разработки: ПолиткорректностьTypeScript
  • 🎉 Компоненты пользовательского интерфейса:antdБезбарьерный переход для разработчиковant-design-vue, Знакомый рецепт Знакомый вкус
  • 🎨стиль css:less,postcss
  • 📖Спецификация кода:Eslint,Prettier,Commitlint
  • 🔒Управление разрешениями: уровень страницы, уровень меню, уровень кнопок, уровень интерфейса
  • ✊ Зависимости загружаются по требованию:unplugin-auto-import, может автоматически импортировать использованныеvue,vue-routerи т.д. зависимый
  • 💪Комплектующие импортируются под заказ:unplugin-vue-components, будь то сторонний компонент пользовательского интерфейса или пользовательский компонент, могут быть автоматически импортированы по запросу иTSподсказки по грамматике

каталог проекта

├── .husky                              // husky git hooks配置目录
    ├── _                               // husky 脚本生成的目录文件
    ├── commit-msg                      // commit-msg钩子,用于验证 message格式
    ├── pre-commit                      // pre-commit钩子,主要是和eslint配合
├── config                              // 全局配置文件
    ├── vite                            // vite 相关配置
    ├── constant.ts                     // 项目配置
    ├── themeConfig.ts                  // 主题配置
├── dist                                // 默认的 build 输出目录
├── mock                                // 前端数据mock
├── public                              // vite项目下的静态目录
└── src                                 // 源码目录
    ├── api                             // 接口相关
    ├── assets                          // 公共的文件(如image、css、font等)
    ├── components                      // 项目组件
    ├── directives                      // 自定义 指令
    ├── enums                           // 自定义 常量(枚举写法)
    ├── hooks                           // 自定义 hooks
    ├── layout                          // 全局布局
    ├── router                          // 路由
    ├── store                           // 状态管理器
    ├── utils                           // 工具库
    ├── views                           // 页面模块目录
        ├── login                       // login页面模块
        ├── ...
    ├── App.vue                         // vue顶层文件
    ├── auto-imports.d.ts               // unplugin-auto-import 插件生成
    ├── components.d.d.ts               // unplugin-vue-components 插件生成
    ├── main.ts                         // 项目入口文件
    ├── shimes-vue.d.ts                 // vite默认ts类型文件
    ├── types                           // 项目type类型定义文件夹
├── .editorconfig                       // IDE格式规范
├── .env                                // 环境变量
├── .eslintignore                       // eslint忽略
├── .eslintrc                           // eslint配置文件
├── .gitignore                          // git忽略
├── .npmrc                              // npm配置文件
├── .prettierignore                     // prettierc忽略
├── .prettierrc                         // prettierc配置文件
├── index.html                          // 入口文件
├── LICENSE.md                          // LICENSE
├── package.json                        // package
├── pnpm-lock.yaml                      // pnpm-lock
├── postcss.config.js                   // postcss
├── README.md                           // README
├── tsconfig.json                       // typescript配置文件
└── vite.config.ts                      // vite

развивать

Инициализация проекта

Если вы используете редактор vscode для разработки vue3, обязательно установите плагин Volar для лучшей работы с vue3 (не совместим с оригинальным Vetur)

использоватьvite cliБыстро создавайте проекты

yarn create vite project-name --template vue-ts

Установить связанные зависимости

Рекомендуется использовать новое поколениеpnpmинструменты управления пакетами, производительность и скорость иnode_modulesУправление зависимостями отлично

Рекомендуется к сотрудничеству.npmrcНастроить с помощью

# 提升一些依赖包至 node_modules
# 解决部分包模块not found的问题
# 用于配合 pnpm
shamefully-hoist = true

# node-sass 下载问题
# sass_binary_site="https://npm.taobao.org/mirrors/node-sass/"

спецификация кода

инструмент:husky,eslint,prettier

В интернете есть много специфических способов использования, я уже упоминал об этом в другой статье, поэтому не буду повторяться здесь~

a Vite2 + Typescript + React + Antd + Less + Eslint + Prettier + Precommit template

В основном концепция автоматизации для выполнения предписанных действий в подходящее время.

  • В сочетании с редактором VsCode (форматирование выполняется автоматически при сохранении:editor.formatOnSave: true)
  • Сотрудничайте с перехватчиками Git (выполните перед фиксацией или перед фиксацией:pre-commit => npm run lint:lint-staged)

Уведомление:

для разных системcommitlintУстановка отличаетсяcommitlint, ошибка установки может быть недействительной ~

# Install commitlint cli and conventional config
npm install --save-dev @commitlint/{config-conventional,cli}
# For Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli

Функция

поддержка возможностей vue

шаблонсинтаксическая координацияjsxСинтаксис очень удобен и гибок в использовании~

некоторые необходимые плагины

{
    // "@vitejs/plugin-legacy": "^1.6.2", // 低版本浏览器兼容
    "@vitejs/plugin-vue": "^1.9.3", // vue 支持
    "@vitejs/plugin-vue-jsx": "^1.2.0", // jsx 支持
}

Государственный управляющий Пиния

Новое поколение менеджера состояний Vue, используемоеreact zustandстуденты должны чувствовать себя знакомыми

Pinia — это оболочка для Vue 3 Composition API. Поэтому вам не нужно инициализировать его как плагин, если вам не нужна поддержка Vue DevTools, поддержка SSR и сегментация кода WebPack.

  • Очень легкий, всего 1 КБ
  • Интуитивное использование API, интуитивно понятное и простое в освоении
  • Модульная конструкция, легко разделяемое состояние
  • Полная поддержка ТС
// ... 引入相关依赖

interface IUserInfoProps{
  name: string;
  avatar: string;
  mobile: number;
  auths: string[]
}

interface UserState {
  userInfo: Nullable<IUserInfoProps>;
}

// 创建 store
export const useUserStore = defineStore({
  id: 'app-user', // 唯一 ID,可以配合 Vue devtools 使用
  state: (): UserState => ({
    // userInfo
    userInfo: null,
  }),
  getters: {
    getUserInfo(): Nullable<IUserInfoProps> {
      return this.userInfo || null;
    },
  },
  actions: {
    setUserInfo(info: Nullable<IUserInfoProps>) {
      this.userInfo = info ?? null;
    },
    resetState() {
      this.userInfo = null;
    },

    /**
     * @description: fetchUserInfo
     */
    async fetchUserInfo(params: ReqParams) {
      const res = await fetchApi.userInfo(params);
      if (res) {
        this.setUserInfo(res);
      }
    },
  },
})

используемые компоненты

// TS 类型推断、异步函数使用都很方便
import { useHomeStore } from '/@/store/modules/home';

const store = useHomeStore();
const userInfo = computed(() => store.getUserInfo);

onMounted(async () => {
  await store.fetchInfo(); // 异步函数
  // ...
});

Компоненты пользовательского интерфейса загружаются по требованию и импортируются автоматически.

Поймите основные понятия: vite поставляется с загрузкой по требованию (для js), здесь мы в основном выполняем загрузку по требованию для стилей.

Вариант 1: vite-plugin-style-import

import styleImport from 'vite-plugin-style-import'

// 
plugins:[
  styleImport({
    libs: [
      {
        libraryName: 'ant-design-vue',
        esModule: true,
        resolveStyle: (name) => {
          return `ant-design-vue/es/${name}/style/index`
        },
      }
    ]
  })
]

Вариант 2: unplugin-vue-components

Рекомендуемое использованиеunplugin-vue-componentsплагин

Плагину нужно только добавить соответствующий в плагин viteAntDesignVueResolverДа, также поддерживает пользовательскиеcomponentsАвтоматическая регистрация, очень удобно

import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
import Components from 'unplugin-vue-components/vite';

// vite.config.ts plugins 添加如下配置
export default defineConfig({
  plugins: [
    Components({
      resolvers: [
        AntDesignVueResolver(), // ant-design-vue
        // ElementPlusResolver(), // Element Plus
        // VantResolver(), // Vant
      ]
    })
  ]
})

Конечно, если здесь нет соответствующего UI-фреймворка, который вы используете.ResolverЗагрузчик, не беда, тоже поддерживает кастомную настройку

Components({
  resolvers: [
    // example of importing Vant
    (name) => {
      // where `name` is always CapitalCase
      if (name.startsWith('Van'))
        return { importName: name.slice(3), path: 'vant' }
    }
  ]
})

Еще одна мощная функция: плагин не только поддерживает импорт компонентов фреймворка пользовательского интерфейса по запросу, но также поддерживает автоматический импорт компонентов проекта по запросу.

Конкретная производительность: если мы используем компонент карты ant-design-vue или другие компоненты, такие как наши собственные определенные компоненты / значок, нам не нужно его импортировать, просто используйте его напрямую, плагин автоматически импортирует это для нас по запросу, в сочетании с подсказками синтаксиса TS, эффективность разработки велика ~

Конфигурация выглядит следующим образом:

Components({
  // allow auto load markdown components under `./src/components/`
  extensions: ['vue'],

  // allow auto import and register components
  include: [/\.vue$/, /\.vue\?vue/],

  dts: 'src/components.d.ts',
})

нуждаться вsrcдобавить в каталогcomponents.d.tsфайл, файл будет автоматически обновлен плагином

  • components.d.tsэффект

Прямой эффект: генерировать соответствующие в рамках проекта.d.tsтип файла типа, используемый для синтаксических подсказок и прохода определения типа

  • Уведомление

"unplugin-vue-components": "^0.17.2"

Известные проблемы текущей версии:issues 174

дляant-design-vueизnotification / messageкомпоненты, когда вjsПри использовании в , плагин не будет выполнять функцию автоматического импорта (стили не будут импортированы)

Конечный эффект:message.success('xx')может создатьDOMэлемент, но без связанного кода стиля

Потому что конструкция основана на принципе plug-vue.templateКомпоненты шаблона используются для обработки, плагин вызова функции не может найти

решение:

  • использовать вместо этогоvite-plugin-style-importплагин
  • Вручную ввести стиль компонента сообщения глобально,import 'ant-design-vue/es/message/style'
  • Вручную добавьте его в шаблон компонента vue<a-message />Используется для зависимостей индекса плагина

Автоматическая важность

  • unplugin-auto-import

vue связанныеdefineComponent,computed,watchДругие зависимости модуля автоматически импортируются в соответствии с использованием, и вам не нужно заботиться об этом.import, вы можете использовать его напрямую

Плагин поддерживает по умолчанию:

  • vue
  • vue-router
  • vue-i18n
  • @vueuse/head
  • @vueuse/core
  • ...

Конечно, вы также можете настроить конфигурациюunplugin-auto-import

Использование заключается в следующем:

import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  // ...
  plugins: [
    AutoImport({
      imports: [
        'vue',
        'vue-router',
        'vue-i18n',
        '@vueuse/head',
        '@vueuse/core',
      ],
      dts: 'src/auto-imports.d.ts',
    })
  ]
})

нуждаться вsrcдобавить в каталогauto-imports.d.tsфайл, файл будет автоматически обновлен плагином

Конечный эффект:

Такие какrefМы можем использовать этот метод напрямую и иметь соответствующие подсказки синтаксиса TS без необходимости вручную переходить кimport { ref } from 'vue'

пользовательская тема

Для пользовательских настроек темы обратитесь к официальной документации по настройке.Существует два обычных метода.

  1. Загружать сопряжения по запросуwebpack/viteСвойство загрузчика изменяет переменную
  2. Полное введение, сотрудничествоvariables.lessПользовательские стили переопределяют стили тем фреймов

Здесь мы используем первый метод для загрузки и приема пищи по запросу через конфигурацию загрузчика.

В рамках проекта vite, пожалуйста, установите меньше вручную,pnpm add less -D

css: {
  preprocessorOptions: {
    less: {
      modifyVars: { 'primary-color': 'red' },
      javascriptEnabled: true, // 这是必须的
    },
  },
}

Уведомление: в использованииunplugin-vue-componentsПосле конфигурации загрузки по требованию необходимо синхронно активировать соответствующие менее изменчивые настройки.importStyle: 'less',unplugin-vue-components issues 160

AntDesignVueResolver({ importStyle: 'less' }) // 这里很重要

фиктивные данные

  • vite-plugin-mockплагин

настройка плагина vite

viteMockServe({
  ignore: /^\_/,
  mockPath: 'mock',
  localEnabled: true,
  prodEnabled: false,
  // 开发环境无需关心
  // injectCode 只受prodEnabled影响
  // https://github.com/anncwb/vite-plugin-mock/issues/9
  // 下面这段代码会被注入 main.ts
  injectCode: `
      import { setupProdMockServer } from '../mock/_createProductionServer';

      setupProdMockServer();
      `,
})

Создал в корневом каталоге_createProductionServer.tsдокумент

import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';

// 批量加载
const modules = import.meta.globEager('./**/*.ts');

const mockModules: any[] = [];
Object.keys(modules).forEach((key) => {
  if (key.includes('/_')) {
    return;
  }
  mockModules.push(...modules[key].default);
});

/**
 * Used in a production environment. Need to manually import all modules
 */
export function setupProdMockServer() {
  createProdMockServer(mockModules);
}

Таким образом, нетекст в фиктивном каталоге_Первый файл будет автоматически загружен как фиктивный файл.

Такие как:

import Mock from 'mockjs';

const data = Mock.mock({
  'items|30': [
    {
      id: '@id',
      title: '@sentence(10, 20)',
      account: '@phone',
      true_name: '@name',
      created_at: '@datetime',
      role_name: '@name',
    },
  ],
});

export default [
  {
    url: '/table/list',
    method: 'get',
    response: () => {
      const items = data.items;
      return {
        code: 0,
        result: {
          total: items.length,
          list: items,
        },
      };
    },
  },
];

Настройте прямой запрос прокси/api/table/listвы можете получить данные

Прокси

import proxy from './config/vite/proxy';

export default defineConfig({
  // server
  server: {
    hmr: { overlay: false }, // 禁用或配置 HMR 连接 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层
    // 服务配置
    port: VITE_PORT, // 类型: number 指定服务器端口;
    open: false, // 类型: boolean | string在服务器启动时自动在浏览器中打开应用程序;
    cors: false, // 类型: boolean | CorsOptions 为开发服务器配置 CORS。默认启用并允许任何源
    host: '0.0.0.0', // 支持从IP启动访问
    proxy,
  },
})

прокси выглядит следующим образом

import {
  API_BASE_URL,
  API_TARGET_URL,
} from '../../config/constant';
import { ProxyOptions } from 'vite';

type ProxyTargetList = Record<string, ProxyOptions>;

const ret: ProxyTargetList = {
  // test
  [API_BASE_URL]: {
    target: API_TARGET_URL,
    changeOrigin: true,
    rewrite: (path) => path.replace(new RegExp(`^${API_BASE_URL}`), ''),
  },
  // mock
  // [MOCK_API_BASE_URL]: {
  //   target: MOCK_API_TARGET_URL,
  //   changeOrigin: true,
  //   rewrite: (path) => path.replace(new RegExp(`^${MOCK_API_BASE_URL}`), '/api'),
  // },
};

export default ret;

переменная среды .env

Я помещаю конфигурацию системы здесьconfig/constant.tsудалось

Для облегчения управления интерфейсами и настройками параметров в различных средах можно использовать переменные среды..env,Такие как.env.development,.env.production

Сотрудничатьvite + import.meta.envДо сих пор очень удобно пользоваться

Подробное использование см.Резюме использования vite + vue3 + ts

Визуализация анализа зависимостей пакетов

Плагин:rollup-plugin-visualizer

import visualizer from 'rollup-plugin-visualizer';

visualizer({
  filename: './node_modules/.cache/visualizer/stats.html',
  open: true,
  gzipSize: true,
  brotliSize: true,
})

сжатие кода

Плагин:vite-plugin-compression

import compressPlugin from 'vite-plugin-compression';

compressPlugin({
  ext: '.gz',
  deleteOriginFile: false,
})

Распаковка чанка

Если вы хотите поставить что-то вродеant-design-vueТакие зависимости пакетов выделяются отдельно и также могут быть настроены вручную.manualChunksАтрибуты

// vite.config.ts
build: {
  rollupOptions: {
    output: {
      manualChunks: configManualChunk
    }
  }
}
// optimizer.ts
const vendorLibs: { match: string[]; output: string }[] = [
  {
    match: ['ant-design-vue'],
    output: 'antdv',
  },
  {
    match: ['echarts'],
    output: 'echarts',
  },
];

export const configManualChunk = (id: string) => {
  if (/[\\/]node_modules[\\/]/.test(id)) {
    const matchItem = vendorLibs.find((item) => {
      const reg = new RegExp(`[\\/]node_modules[\\/]_?(${item.match.join('|')})(.*)`, 'ig');
      return reg.test(id);
    });
    return matchItem ? matchItem.output : null;
  }
};

Совместимая обработка

Плагин:@vitejs/plugin-legacy

Совместимость не поддерживается<script type="module">обозреватель функций или обозреватель IE

// Native ESM
legacy({
  targets: ['defaults', 'not IE 11']
})

// IE11
// 需要 regenerator-runtime
legacy({
  targets: ['ie >= 11'],
  additionalLegacyPolyfills: ['regenerator-runtime/runtime']
})

визуализация

титульная страница

vite-vue3-4


Визуализация анализа зависимостей пакетов, несколько скриншотов

vite-vue3-2


Включите сжатие, включите совместимость и создавайте упакованные продукты

vite-vue3-1

Маршрутизация и макет

// router/index.ts
import { createRouter, createWebHashHistory } from 'vue-router'
import routes from './router.config'

const router = createRouter({
  history: createWebHashHistory(), //
  routes,
})

// main.ts
app.use(router); // 挂载后可全局使用实列,如模板中 <div @click="$router.push('xx')"></div>

Использование заключается в следующем:

// router.config.ts
import BasicLayout from '/@/layouts/BasicLayout/index.vue'; // 基本布局
import BlankLayout from '/@/layouts/BlankLayout.vue'; // 空布局
import type { RouteRecordRaw } from 'vue-router';

const routerMap: RouteRecordRaw[] = [
  {
    path: '/app',
    name: 'index',
    component: BasicLayout,
    redirect: '/app/home',
    meta: { title: '首页' },
    children: [
      {
        path: '/app/home',
        component: () => import('/@/views/home/index.vue'),
        name: 'home',
        meta: {
          title: '首页',
          icon: 'liulanqi',
          auth: ['home'],
        },
      },
      {
        path: '/app/others',
        name: 'others',
        component: BlankLayout,
        redirect: '/app/others/about',
        meta: {
          title: '其他菜单',
          icon: 'xitongrizhi',
          auth: ['others'],
        },
        children: [
          {
            path: '/app/others/about',
            name: 'about',
            component: () => import('/@/views/others/about/index.vue'),
            meta: { title: '关于', keepAlive: true, hiddenWrap: true },
          },
          {
            path: '/app/others/antdv',
            name: 'antdv',
            component: () => import('/@/views/others/antdv/index.vue'),
            meta: { title: '组件', keepAlive: true, breadcrumb: true },
          },
        ],
      },
    ]
  }
  ...
]

разрешение

  • Поддержка управления правами на уровне страниц и меню, управление маршрутизацией
  • Поддержка управления разрешениями на уровне кнопок
  • Поддержка управления правами на уровне интерфейса

Несколько ключевых слов:router.addRoutesдинамическая маршрутизация,v-authИнструкция,axiosперехватывать

использоватьrouter.beforeEachхук глобальной маршрутизации

Основная логика выглядит следующим образом, подробности см. в коде хранилища.router/permission.ts

// 没有获取,请求数据
await permissioStore.fetchAuths();
// 过滤权限路由
const routes = await permissioStore.buildRoutesAction();
// 404 路由一定要放在 权限路由后面
routes.forEach((route) => {
  router.addRoute(route);
});
// hack 方法
// 不使用 next() 是因为,在执行完 router.addRoute 后,
// 原本的路由表内还没有添加进去的路由,会 No match
// replace 使路由从新进入一遍,进行匹配即可
next({ ...to, replace: true });

использоватьv-authКоманды управляют разрешениями на уровне кнопок

function isAuth(el: Element, binding: any) {
  const { hasPermission } = usePermission();

  const value = binding.value;
  if (!value) return;
  if (!hasPermission(value)) {
    el.parentNode?.removeChild(el);
  }
}

axiosперехватывать

существуетaxiosперехватчик запросовinterceptors.request.useДобавить к

// 接口权限拦截
const store = usePermissioStoreWithOut();
const { url = '' } = config;
if (!WhiteList.includes(url) && store.getIsAdmin === 0) {
  if (!store.getAuths.includes(url)) {
    return Promise.reject('没有操作权限');
  }
}

Суммировать

Начинаяvite + vue3В то время это тоже был процесс обучения и развития, наступая на яму, к счастью, сейчас сообщество активизировалось, и многие проблемы имеют соответствующие решения.github issueВ принципе, можно есть вместе, этот проект также является эталоном.vue-vben-adminНекоторая реализация и управление кодом этой статьи какvue3Используйте учебные записи~

Вы найдете после использованияvue3а такжеvue2имеют совсем другой опыт разработки, нынешнийvue3правильноTSБлагодаря отличной поддержке эффективность и качество разработки поднялись до уровня, а также поддерживается синтаксис JSX, аналогичныйReactВозможна и форма разработки.Конечно, при использовании шаблона VUE также имеется большая гибкость, вы можете настроить свой собственный код в соответствии со сценой, в сочетании с текущимscript setupРазвитие, прямо круто взлететь~

В использованииvue3изcomposition apiПри разработке режима обязательно откажитесь от предыдущегоoptions apiлогика развития, сопоставлениеhooksКод можно свободно комбинировать и разделять, с высокой гибкостью, удобным обслуживанием и управлением, и он больше не появится.vue2Вся эпоха кода свинчена

В одном предложении:vite + vue3 + setup + ts + vscode volarПлагины, кто использует кто знает, классная партия~

Адрес склада:GitHub.com/JS-банан/V…

emoji

Ссылаться на