Some time ago I used Vite + Typescript + Ant Design Vue to build a project

The configuration is based on the actual project situation

1. Perform initial configuration for the Vite project

Initialize the

Vite is very, very fast compared to vue-CLI (based on Webpack) ❤!

Vite official Chinese documentation: cn.vitejs.dev/guide/

Personally, I prefer yarn. The commands are simple and unified

  • Install vite

    yarn create vite
    Copy the code

    Follow the prompts to enter ok

  • Open the browser to view the result: http://localhost:3000/

Configure an alias

Modify the vite. Config. ts configuration file

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
const resolve = (dir: string) = > path.join(__dirname, dir);

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@ /": resolve("src/*"),
      comps: resolve("src/components"),
      store: resolve("src/store"),}}});Copy the code
  • Error: module ‘PATH’ or its corresponding type declaration could not be found Could not find name ‘__dirname’

    yarn add @types/node --save-dev
    Copy the code
  • Cannot find module ‘store/index’ or its corresponding type declarations

    Configure baseUrl and Paths in tsconfig.json

    {
      "compilerOptions": {
        "baseUrl": ". /"."paths": {
          "@": ["src/*"]."comps/*": ["src/components/*"]."store/*": ["src/store/*"]}}}Copy the code

2. Clear the default file

Create a new public/ CSS /reset. CSS file, clear the browser default styles, and introduce import ‘.. /public/css/reset.css’

html.body.div.span, applet, object.iframe.h1.h2.h3.h4.h5.h6.p.blockquote, pre,
a.abbr, acronym, address, big, cite.code.del.dfn.em.img.ins.kbd.q, s, samp,
small, strike, strong, sub, sup, tt, var.b, u, i, center,
dl.dt.dd.ol.ul.li.fieldset.form.label.legend.table.caption.tbody.tfoot.thead.tr.th.td.article.aside.canvas.details, embed, 
figure.figcaption.footer.header.hgroup.menu.nav, output, ruby, section.summary.time.mark.audio.video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article.aside.details.figcaption.figure.footer.header.hgroup.menu.nav.section {
	display: block;
}
body {
	line-height: 1;
}
ol.ul {
	list-style: none;
}
blockquote.q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: ' ';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
Copy the code

Delete all files in the SRC /assets and SRC/Components directories

Open the app. vue file, delete all the code, and use the shortcut vue to generate the template

  • Vscode sets the template

    [File] -> [Preferences] -> [User snippet] -> [New global snippet file] -> Enter the filename vue-ts-less -> Paste the following code

    {
    	"Print to console": {
    		"prefix": "vue-ts-less"."body": [
    			"<template></template>".""."<script lang=\"ts\">"."import { defineComponent } from \"vue\";"."export default defineComponent({"." components: {},"." setup() {"." return {};"."},"."});"."</script>".""."<style lang=\"less\" scoped>"."</style>"."$2"]."description": "Vue - ts - less template"}}Copy the code

    Enter vuE-ts-less in the vue file and press Tab to generate the corresponding code block

3. Vuex configuration

Vuex is a state management mode + library developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of an application and rules to ensure that the state changes in a predictable way.

  • Multiple components using the same data
  • Components are deeply nested

In these cases, vuEX is more appropriate

Vuex official document: next.vuex.vuejs.org/

  • Install Vuex using version 4.x

    yarn add vuex@next --save
    Copy the code
  • Create store/index.ts in the SRC directory

    import { InjectionKey } from "vue";
    import { createStore, useStore as baseUseStore, Store } from "vuex";
    import type { App } from "vue";
    
    // Import the corresponding module
    import { users } from "./modules/users";
    
    // Manually declare the state type
    export interface State { } 
    
    // Define the injection type
    const key: InjectionKey<Store<State>> = Symbol(a);const store = createStore<State>({
      state(){},mutations: {},
      actions: {},
      // Use the module
      modules: { users },
    });
    
    // Inject the type into useStore. All references in the project are custom ones, overwriting the useStore provided by Vuex
    export function useStore() {
      return baseUseStore(key);
    }
    
    export function setupStore(app: App<Element>) {
      app.use(store, key);
    }
    
    export default store;
    
    Copy the code
  • Create a store/ Modules folder where you can create each module file

    For example, the user. Ts

    import { createStore } from "vuex";
    
    export interface State { }
    
    export const users = createStore<State>({
        state: () = > ({}),
        getters: {},
        mutations: {},
        actions: {},})Copy the code
  • Add in main.ts

    import { createApp } from "vue";
    import { setupStore } from "./store"; 
    import App from "./App.vue";
    
    const app = createApp(App);
    
    setupStore(app);
    
    app.mount("#app");
    Copy the code

4. Vue Router 4

Features include:

  • Nested routines are mapped
  • Dynamic routing
  • Modular, component-based routing configuration
  • Route parameters, queries, and wildcards
  • Show the transition effects provided by vue.js transition system
  • Detailed navigation control
  • Automatically activate links to CSS classes
  • HTML5 History mode or Hash mode
  • Customizable scrolling behavior
  • Correct encoding of the URL

Vue Router official Chinese document: next.router.vuejs.org

  • The installation

    yarn add vue-router@4
    Copy the code
  • Modify the app. vue file

    Adding the router-view tag will do the trick

    <template>
      <router-view></router-view>
    </template>
    
    <script lang="ts">
      export default {
        name: "App",
      };
    </script>
    
    <style></style>
    
    Copy the code
  • Create router/index.ts in the SRC directory

    import { createRouter, createWebHistory } from "vue-router";
    import type { App } from "vue";
    
    // Import the corresponding module
    const Home = () = > import(".. /view/home.vue");
    const Login = () = > import(".. /view/login.vue");
    
    / / write routing
    const routes = [
      { path: "/".component: Home },
      { path: "/login".component: Login },
    ];
    
    const router = createRouter({
      // createWebHashHistory (Hash route)
      // createWebHistory (history path, requires server configuration support)
      // createMemoryHistory With the cache history route
      // Add baseUrl createWebHistory(baseUrl)
      history: createWebHistory(),
      routes,
    });
    
    export function setupRouter(app: App<Element>) {
      app.use(router);
    }
    
    export default router;
    
    Copy the code

    If the project is large, the routing module can be pulled out

  • The main ts change

    import { createApp } from "vue";
    import { setupStore } from "./store";
    import router, { setupRouter } from "./router"; 
    import App from "./App.vue";
    
    const app = createApp(App);
    
    setupRouter(app);
    setupStore(app); 
    
    router.isReady().then(() = > {
      app.mount("#app");
    });
    
    Copy the code

5. Scass/Scss/Less preprocessor

Antd uses less

yarn add less
Copy the code

6. Ant Design of Vue installation and configuration

Liverpoolfc.tv: 2 x.antdv.com/docs/vue

  • The installation

    yarn add ant-design-vue@next --save
    Copy the code
  • Full introduction in main.ts (not recommended)

    import { createApp } from 'vue';
    import Antd from 'ant-design-vue';
    import App from './App';
    import 'ant-design-vue/dist/antd.css'; // It has to be introduced to have a style
    
    const app = createApp();
    app.config.productionTip = false;
    
    app.use(Antd);
    Copy the code
  • The local import

    import { createApp } from 'vue';
    import { Button } from 'ant-design-vue';
    import 'ant-design-vue/es/button/style'; // Also introduce less styles
    import "ant-design-vue/es/button/style/css"; / / load the CSS
    
    import App from './App';
    
    const app = createApp(App);
    
    app.use(Button).mount('#app');
    Copy the code
  • == Import on demand (recommended) ==

    Install vite – plugin – imp

    yarn add vite-plugin-imp -D
    Copy the code

    Modify the vite. Config. ts file

    import { defineConfig } from "vite";
    import vitePluginImp from "vite-plugin-imp";
    
    export default defineConfig({
      plugins: [
        vue(),
        vitePluginImp({
          libList: [{libName: "ant-design-vue"./ / style: (name) = > ` ant - design - vue/es / ${name} / style/CSS `, / / load the CSS
              style: (name) = > `ant-design-vue/es/${name}/style`./ / load less},],}),],css: {
        preprocessorOptions: {
          less: {
            // Create a custom theme
            modifyVars: { "primary-color": "#1188ff" },
            javascriptEnabled: true,},},},});Copy the code

    Add the libs/ antDV. ts file in the SRC directory

    import type { App } from "vue";
    // Add components here
    import { Button, Radio, Checkbox } from "ant-design-vue";
    const components = [Button, Radio, Checkbox];
    
    export function setupAntd(app: App<Element>) :void {
      components.forEach((component: any) = > {
        app.use(component);
      });
    }
    
    Copy the code

    Modify the main.ts file

    import { createApp } from "vue";
    import { setupStore } from "./store"; 
    import router, { setupRouter } from "./router"; 
    import { setupAntd } from "./libs/antdv";  // ++
    import App from "./App.vue";
    
    const app = createApp(App);
    
    setupRouter(app);
    setupStore(app);
    setupAntd(app);  // ++
    
    router.isReady().then(() = > {
      app.mount("#app");
    });
    
    Copy the code

7. Element-plus installation and configuration

Here is only about the use of plug-ins on demand import, other can go to the official website to see, and the above antD similar

Official document: Element-plus.gize. IO/zh-cn /

  • The installation

    yarn add element-plus
    Copy the code
  • Automatic import

    yarn add unplugin-vue-components unplugin-auto-import
    Copy the code
  • Modify the vite. Config. Ts

    import AutoImport from 'unplugin-auto-import/vite'
    import Components from 'unplugin-vue-components/vite'
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
    
    export default {
      plugins: [
        // ...
        AutoImport({
          resolvers: [ElementPlusResolver()],
        }),
        Components({
          resolvers: [ElementPlusResolver()],
        }),
      ],
    }
    Copy the code
  • Likewise, add the libs/ em.ts file to the SRC directory

    import type { App } from "vue";
    import { ElButton } from 'element-plus'
    
    const components = [ElButton];
    
    export function setupElem(app: App<Element>) :void {
        components.forEach((component: any) = > {
          app.use(component);
        });
      }
    Copy the code

    Modify the main.ts file

    import { createApp } from "vue";
    import { setupStore } from "./store"; 
    import router, { setupRouter } from "./router"; 
    import { setupElem } from "./libs/element-plus";  // ++
    import App from "./App.vue";
    
    const app = createApp(App);
    
    setupRouter(app);
    setupStore(app);
    setupElem(app);  // ++
    
    router.isReady().then(() = > {
      app.mount("#app");
    });
    
    Copy the code

8. Axios installation and secondary packaging

Axios is a PROMISE based HTTP library that simply lets you send get, POST, and other requests

  • XMLHttpRequests can be sent in the browser
  • HTTP requests can be sent from Node.js
  • Supporting Promise API
  • Intercept requests and responses
  • Transform request data and response data
  • Ability to cancel requests
  • Automatically convert JSON data
  • Client support protects security from XSRF attacks

Github is at github.com/axios/axios

  • The installation

    yarn add axios
    Copy the code
  • Create SRC /service/request.ts in the SRC directory

    Secondary encapsulation of AXIos

    import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
    import { message } from 'ant-design-vue'
    import { useRouter } from "vue-router"
    
    const router = useRouter()
    
    export function request(config: AxiosRequestConfig) {
        // 1 Create an instance
        const instance = axios.create({
            baseURL: "xxx".timeout: 5000.headers: {
                "Content-Type": "application/json",}});// 2 interceptor
        // Request interception
        instance.interceptors.request.use(
            (config) = > {
                message.loading();
                return config;
            },
            (err) = > {
                console.log(err); });// Response interception
        instance.interceptors.response.use((response: AxiosResponse<any>) = > {
            message.destroy();
            return response.data;
        }),
            (error: any) = > {
                if(error? .response) {switch (error.response.status) {
                        case 400: message.error('Request error (400)'); break;
                        case 401: router.push({ name: 'login' }); break;
                        case 403: message.error('Access denied (403)'); break;
                        case 404: message.error('Request error (404)'); break;
                        case 408: message.error('Request timed out (408)'); break;
                        case 500: message.error('Server error (500)'); break;
                        case 501: message.error('Service Not realized (501)'); break;
                        case 502: message.error('Network Error (502)'); break;
                        case 503: message.error('Service unavailable (503)'); break;
                        case 504: message.error('Network Timeout (504)'); break;
                        case 505: message.error('HTTP version not supported (505)'); break;
                        default: message.error('Connection error (${error.response.status})! `); }}else {
                    message.error('Failed to connect to server! ');
                }
                message.destroy();
                console.log(error);
            };
        // 3 Returns the instance, which is itself a pormise
        return instance(config);
    }
    Copy the code
  • Use:

    Create a new API folder in the Service folder and write API modules in this folder

    import { request } from ".. /request";
    
    export function xxxx() {
        return request({
            url: `xxx`.method: 'get'.data: {},
            params: {}}); }Copy the code

    Just import it in a file that uses the API

    <template> <el-button @click="test"> test </el-button> </template> <script lang="ts"> import {defineComponent} from "vue";  import { getSometings } from ".. /service/api/user"; export default defineComponent({ setup() { const test = async () => { await getSometings().then((res: any) => { console.log(res.data); }); }; return { test }; }}); </script> <style> </style>Copy the code

Thanks to the author: Time Footprints link: juejin.cn/post/697391… Source: Rare earth nuggets