Vite2 + Vue3 + TypeScript + Pinia build an enterprise level development scaffold [worth collecting]

Posted by limitedreality on Thu, 03 Mar 2022 17:45:21 +0100

Hello, everyone. I'm xy???. It has been a year since I first came into contact with vue3 version. Due to vue3 With the release of version 2, the experimental mark of < script setup > has been removed, and many companies have started to use vue3 2 development project. This article is to help you how to quickly use vue3 x. typeScript, vite build a set of enterprise level development scaffolding??. Don't talk too much nonsense, just start doing it??

Preparation before construction

  1. Vscade: a necessary code writing artifact for front-end people
  2. Chrome: a developer friendly browser (I rely on it anyway)
  3. Nodejs & npm: configure the local development environment. After installing Node, you will find that npm will be installed together
  4. Vue.js devtools: Browser debugging plug-in
  5. Vue language features (vol): the vue3 essential plug-in developed by vscade provides syntax highlighting tips, which is very easy to use
  6. Vue 3 Snippets: vue3 quick input

Due to Vue JS devtools needs to be extended to Google expansion store. The intimate xy has already prepared crx files for everyone. The official account reply: VueDevTools can automatically get it?

The difference between Vue2 and Vue3

Because Vue3 is completely rewritten by TS, it has a strong performance in the definition and use of type judgment in applications. Multiple key return values of the same object must be typed by defining the corresponding interface. Otherwise, an error will be reported in ESLint.

The bidirectional data binding of vue2 uses an API object of ES5 Defineproperty () hijacks data in combination with publish subscribe mode. Vue3 uses the ProxyAPI of es6 for data broker.

Vue3 supports fragments

The biggest difference between Vue2 and Vue3: Vue2 uses the Options API while Vue3 uses the Composition API

Life cycle hook changes:

Vue2 ~~~~~~~~~~~ vue3
beforeCreate  -> setup()
created       -> setup()
beforeMount   -> onBeforeMount
mounted       -> onMounted
beforeUpdate  -> onBeforeUpdate
updated       -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed     -> onUnmounted
activated     -> onActivated
deactivated   -> onDeactivated

Introduce vite

Vite: the next generation front-end development and construction tool

  • ?? Fast development server startup
  • Lightweight and fast thermal module overload (HMR)
  • ?? Rich functions
  • ?? Built in optimization
  • ?? Universal plug-in interface
  • ?? Fully typed API

Vite (French for "fast", pronounced / vit /) is a new front-end construction tool that greatly improves the front-end development experience.

It mainly consists of two parts:

  • A development server that provides rich built-in functions based on native ES modules, such as amazing module hot update (HMR).

  • A set of build instructions that use Rollup to package your code, and it is pre configured to output optimized static resources for the production environment.

  • Vite provides a high degree of extensibility and configurability of JavaScript plug-ins.

Using vite to quickly create scaffolding

Compatibility Note: Vite requires node JS version > = 12.0.0.

  1. Step 1: open cmd in the directory where the project file needs to be created and run the following command

    npm 6.x

    npm init @vitejs/app vite_vue3_ts --template

    npm 7 +, additional double horizontal lines are required:

    npm init @vitejs/app vite_vue3_ts – --template


    yarn create @vitejs/app vite_vue3_ts --template

Here I use yarn to install

  1. Step 2: select vue enter = > vue TS enter

  1. Step 3: cd to the project folder, install dependencies, and start the project

    Enter project folder

    cd vite_vue3_ts

    Installation dependency



    yarn dev

Constraint code style

Eslint support

# eslint installation
yarn add eslint --dev
# eslint plug-in installation
yarn add eslint-plugin-vue --dev

yarn add @typescript-eslint/eslint-plugin --dev

yarn add eslint-plugin-prettier --dev

# typescript parser
yarn add @typescript-eslint/parser --dev

Note: if the eslint installation reports an error:

You can try the following command:

yarn config set ignore-engines true

After successful installation, run the linkest command again

New under project eslintrc.js

Configure eslint verification rules:

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    es2021: true,
  parser: 'vue-eslint-parser',
  extends: [
    // Abbreviation for eslint config prettier
  parserOptions: {
    ecmaVersion: 12,
    parser: '@typescript-eslint/parser',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
  // Eslint plugin Vue @ typescript eslint / eslint plugin short for eslint plugin prettier
  plugins: ['vue', '@typescript-eslint', 'prettier'],
  rules: {
    '@typescript-eslint/ban-ts-ignore': 'off',
    '@typescript-eslint/no-unused-vars': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-var-requires': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    '@typescript-eslint/no-use-before-define': 'off',
    '@typescript-eslint/ban-ts-comment': 'off',
    '@typescript-eslint/ban-types': 'off',
    '@typescript-eslint/no-non-null-assertion': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    'no-var': 'error',
    'prettier/prettier': 'error',
    // Disable console
    'no-console': 'warn',
    // Disable debugger
    'no-debugger': 'warn',
    // Duplicate case labels are prohibited
    'no-duplicate-case': 'warn',
    // Empty statement blocks are prohibited
    'no-empty': 'warn',
    // Unnecessary parentheses are prohibited
    'no-extra-parens': 'off',
    // Re assignment of function declarations is prohibited
    'no-func-assign': 'warn',
    // Unreachable code is prohibited after return, throw, continue and break statements
    'no-unreachable': 'warn',
    // Force all control statements to use a consistent bracket style
    curly: 'warn',
    // The default branch is required in the switch statement
    'default-case': 'warn',
    // Force point numbers to be used whenever possible
    'dot-notation': 'warn',
    // Requires = = = and==
    eqeqeq: 'warn',
    // Disable else block after return statement in if statement
    'no-else-return': 'warn',
    // Null functions are prohibited
    'no-empty-function': 'warn',
    // Disable unnecessary nested blocks
    'no-lone-blocks': 'warn',
    // Multiple spaces are prohibited
    'no-multi-spaces': 'warn',
    // Multiple declarations of the same variable are prohibited
    'no-redeclare': 'warn',
    // Assignment statements are prohibited in return statements
    'no-return-assign': 'warn',
    // Disable unnecessary return await
    'no-return-await': 'warn',
    // Prohibit self assignment
    'no-self-assign': 'warn',
    // Prohibit self comparison
    'no-self-compare': 'warn',
    // Prohibit unnecessary catch clauses
    'no-useless-catch': 'warn',
    // Prohibit redundant return statements
    'no-useless-return': 'warn',
    // Prohibit variable declarations from having the same name as variables in the outer scope
    'no-shadow': 'off',
    // Allow delete variable
    'no-delete-var': 'off',
    // Force consistent spaces in array square brackets
    'array-bracket-spacing': 'warn',
    // Force consistent brace style in code blocks
    'brace-style': 'warn',
    // Enforce camel spelling naming conventions
    camelcase: 'warn',
    // Force consistent indentation
    indent: 'off',
    // Force the consistent use of double or single quotation marks in JSX properties
    // 'jsx-quotes': 'warn',
    // Forces the maximum depth of nested blocks 4
    'max-depth': 'warn',
    // Force maximum number of rows 300
    // "max-lines": ["warn", { "max": 1200 }],
    // The maximum number of lines of code for the forced function is 50
    // 'max-lines-per-function': ['warn', { max: 70 }],
    // Forces the maximum number of statements allowed for a function block to be 20
    'max-statements': ['warn', 100],
    // Force maximum nesting depth of callback function
    'max-nested-callbacks': ['warn', 3],
    // Forces the maximum number of parameters allowed in a function definition
    'max-params': ['warn', 3],
    // Force the maximum number of statements allowed in each row
    'max-statements-per-line': ['warn', { max: 1 }],
    // Each call in the method chain is required to have a newline character
    'newline-per-chained-call': ['warn', { ignoreChainWithDepth: 3 }],
    // Prohibit if from appearing in else statements as the only statement
    'no-lonely-if': 'warn',
    // Mixed indentation of spaces and tab s is prohibited
    'no-mixed-spaces-and-tabs': 'warn',
    // Multiple blank lines are prohibited
    'no-multiple-empty-lines': 'warn',
    // Prohibited;
    semi: ['warn', 'never'],
    // Force consistent spaces before blocks
    'space-before-blocks': 'warn',
    // Force a consistent space before the left parenthesis of function
    // 'space-before-function-paren': ['warn', 'never'],
    // Force consistent spaces within parentheses
    'space-in-parens': 'warn',
    // Space around operator is required
    'space-infix-ops': 'warn',
    // Force consistent spaces before and after unary operators
    'space-unary-ops': 'warn',
    // Force consistent spaces / / or / * in comments
    // "spaced-comment": "warn",
    // Force a space around the colon of the switch
    'switch-colon-spacing': 'warn',
    // Force the arrow function to use consistent spaces before and after the arrow
    'arrow-spacing': 'warn',
    'no-var': 'warn',
    'prefer-const': 'warn',
    'prefer-rest-params': 'warn',
    'no-useless-escape': 'warn',
    'no-irregular-whitespace': 'warn',
    'no-prototype-builtins': 'warn',
    'no-fallthrough': 'warn',
    'no-extra-boolean-cast': 'warn',
    'no-case-declarations': 'warn',
    'no-async-promise-executor': 'warn',
  globals: {
    defineProps: 'readonly',
    defineEmits: 'readonly',
    defineExpose: 'readonly',
    withDefaults: 'readonly',

New under project eslintignore

# eslint ignore the check (add it yourself according to the needs of the project)

prettier support

# Installing prettier
yarn add prettier --dev

Resolve eslint and prettier conflicts

Resolve the conflict between the style specification in ESLint and the style specification in prettier, and the style specification in prettier shall prevail, so that the style specification in ESLint will automatically become invalid

# Install the plug-in eslint config prettier
yarn add eslint-config-prettier --dev

New under project prettier.js

To configure prettier formatting rules:

module.exports = {
  tabWidth: 2,
  jsxSingleQuote: true,
  jsxBracketSameLine: true,
  printWidth: 100,
  singleQuote: true,
  semi: false,
  overrides: [
      files: '*.json',
      options: {
        printWidth: 200,
  arrowParens: 'always',

New under project prettierignore

# Ignore the format file (add it yourself according to the needs of the project)

package.json configuration:

  "script": {
    "lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
    "prettier": "prettier --write ."

After the above configuration is completed, you can run the following command to test the following code and check the formatting effect:

# eslint check
yarn lint
# prettier auto format
yarn prettier

Configure husky + lint staged

Use husky + lint staged to assist the team coding specification. mrm is recommended for husky & lint staged installation, which will be based on package JSON relies on the code quality tools in the to install and configure husky and lint staged, so make sure to install and configure all code quality tools, such as Prettier and ESlint, before doing so

Install mrm first

npm i mrm -D --registry=

husky is a tool for adding hooks to git clients. After installation, it will be automatically in the warehouse Add corresponding hooks in Git / directory; For example, the pre commit hook will trigger when you execute git commit.

Then we can implement some operations in pre commit, such as lint check, unit test, code beautification and so on. Of course, the speed of commands executed in the pre commit phase should not be too slow. It is not a good experience to wait for a long time for each commit.

Lint staged, a tool that only filters out Git code temporary storage files (files added by Git); This is very practical, because if we check the code of the whole project, it may take a long time. If it is an old project, we need to check and modify the code specification of the previous code, which may be troublesome and may lead to great changes in the project.

Therefore, this lint staged is a good tool for team projects and open source projects. It is a specification and constraint on the code to be submitted by individuals

Installing lint staged

mrm installation lint staged will automatically install husky together

npx mrm lint-staged

After successful installation, you will find package The following configurations are added to JSON:

Because we need to combine the prettier code format, modify the following configuration:

"husky": {
    "hooks": {
      "pre-commit": "lint-staged"
  "lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "yarn lint",
      "prettier --write",
      "git add"

Well, here's the code format configuration, basically completed!!!

You can modify some code and try git commit. You will find that the code will be formatted automatically:

Code before submission (found that the editor is red):

Execute the commit operation, and the console can see the following processes:

Has the code after commit been formatted

Configuration file reference alias

Directly modify vite config. TS file configuration:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),

Modify tsconfig json

  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "baseUrl": ".",
    "paths": {
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]

Configure css preprocessor scss

Although vite natively supports less/sass/scss/stylus, you must manually install their preprocessor dependencies


yarn add dart-sass --dev
yarn add sass --dev

Configure global scss style file

Add a new style folder under src/assets to store global style files

New main SCSS, set a color variable for testing:

$test-color: red;

How to globally inject this global style file into the project? Configure Vite:

        additionalData:'@import "@/assets/style/mian.scss";'

Used in components

There is no need to introduce any variables that can be defined directly using the global scss

  color: $test-color;


# Install routing
yarn add vue-router@4

Add a router folder under src file = > router TS file, as follows:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
    path: '/',
    name: 'Login',
    component: () => import('@/pages/login/Login.vue'), // Note that the file suffix should be added here vue

const router = createRouter({
  history: createWebHistory(),

export default router

Modify the entry file Mian ts :

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'

const app = createApp(App)



Here, the basic configuration of routing has been completed. For more configuration information, please see the official Vue router document:


vue-router4.x supports typescript. The type of configured route is RouteRecordRaw. Here, meta can give us more room to play. Here are some references:

  • title:string; Page title, usually required.
  • icon?:string; Icons are generally used with menus.
  • auth?:boolean; Whether login permission is required.
  • ignoreAuth?:boolean; Whether to ignore permissions.
  • roles?:RoleEnum[]; Accessible roles
  • keepAlive?:boolean; Whether to enable page caching
  • hideMenu?:boolean; For example, we don't want to display some routes in the edit menu.
  • order?:number; Menu sorting.
  • frameUrl?:string; Nested outer chain.

Only some ideas are provided here. There will be some differences in the business involved in each project. There will be no detailed explanation here. You can configure it according to your own business needs.

Unified request encapsulation

Used vue2 Students of X should be familiar with axios. Here we directly use axios for encapsulation:

# Install axios
yarn add axios
# Install nprogress to request loading
# You can also customize other loading according to project requirements
yarn add nprogress
# Type declaration, or add one containing ` declare module 'nprogress'
yarn add @types/nprogress --dev

In actual use, it can be modified according to the project. For example, put and delete requests can be added in the RESTful api, and the ResType can also be dynamically modified according to the general return value of the back end

Add a new service folder, and add http TS files and api folders:

http.ts: for axios packaging

import axios, { AxiosRequestConfig } from 'axios'
import NProgress from 'nprogress'

// Set request header and request path
axios.defaults.baseURL = '/api'
axios.defaults.timeout = 10000['Content-Type'] = 'application/json;charset=UTF-8'
  (config): AxiosRequestConfig<any> => {
    const token = window.sessionStorage.getItem('token')
    if (token) {
      config.headers.token = token
    return config
  (error) => {
    return error
// Response interception
axios.interceptors.response.use((res) => {
  if ( === 111) {
    sessionStorage.setItem('token', '')
    // token expiration operation
  return res

interface ResType<T> {
  code: number
  data?: T
  msg: string
  err?: string
interface Http {
  get<T>(url: string, params?: unknown): Promise<ResType<T>>
  post<T>(url: string, params?: unknown): Promise<ResType<T>>
  upload<T>(url: string, params: unknown): Promise<ResType<T>>
  download(url: string): void

const http: Http = {
  get(url, params) {
    return new Promise((resolve, reject) => {
        .get(url, { params })
        .then((res) => {
        .catch((err) => {
  post(url, params) {
    return new Promise((resolve, reject) => {
        .post(url, JSON.stringify(params))
        .then((res) => {
        .catch((err) => {
  upload(url, file) {
    return new Promise((resolve, reject) => {
        .post(url, file, {
          headers: { 'Content-Type': 'multipart/form-data' },
        .then((res) => {
        .catch((err) => {
  download(url) {
    const iframe = document.createElement('iframe') = 'none'
    iframe.src = url
    iframe.onload = function () {
export default http

api: the interfaces in the project are managed uniformly and divided according to modules

Add a login folder under the api file, which is used to store the request interface of the login module. Under the login folder, add login ts types. ts :


import http from '@/service/http'
import * as T from './types'

const loginApi: T.ILoginApi = {
        return'/login', params)

export default loginApi


export interface ILoginParams {
    userName: string
    passWord: string | number
export interface ILoginApi {
    login: (params: ILoginParams)=> Promise<any>

So far, a simple request encapsulation is completed!!!

In addition to manually encapsulating axios, we also recommend a vue3 request Library: VueRequest, which is very easy to use. Let's take a look at the easy-to-use functions of VueRequest!!!

  • ?? All data is responsive
  • ?? poll request
  • ?? Automatic error handling retry
  • ?? Built in request cache
  • ?? Throttling request and anti shake request
  • ?? Automatic re request when focusing on the page
  • Powerful paging extensions and loading more extensions
  • ?? Written entirely using Typescript, it has powerful type prompt
  • Compatible with Vite
  • ?? Lightweight
  • ?? Out of the box

Is it powerful??

Official website link:

Status management pinia

Because vuex 4's support for typescript is sad, state management abandoned vuex and adopted Pinia Pinia's author is a member of Vue's core team

Youda seems to say that pinia may replace vuex, so please rest assured.

Install pinia

The difference between Pinia and Vuex:

  • id is necessary to connect the used store to devtools.

  • Creation method: new vuex Store(...) (vuex3),createStore(...)(vuex4).

  • In contrast to vuex3, state is now a function return object.

  • Without changes, don't worry. state changes are still recorded in devtools.


    yarn add pinia@next

main. Added in TS

# introduce
import { createPinia } from "pinia"
# Create a root repository and pass it to the application

Add a new store folder under src folder, and then add main ts

Create a store, Mian ts :

import { defineStore } from 'pinia'

export const useMainStore = defineStore({
  id: 'mian',
  state: () =>({
    name: 'Super administrator'

Get the store in the build:


<script setup lang="ts">
import { useMainStore } from "@/store/mian"

const mainStore = useMainStore()


getters usage introduction

Getters in Pinia have the same functions as getter s in Vuex and calculation properties in components

store => mian.ts

import { defineStore } from 'pinia'

export const useMainStore = defineStore({
  id: 'mian',
  state: () => ({
    name: 'Super administrator',
  // getters
  getters: {
    nameLength: (state) =>,

Used in components:

  <div>user name:{{ }}<br />length:{{ mainStore.nameLength }}</div>
  <button @click="updateName">modify store Medium name</button>

<script setup lang="ts">
import { useMainStore } from '@/store/mian'

const mainStore = useMainStore()

const updateName = ()=>{
  // $patch modifies the data in the store
    name: 'The name has been changed,nameLength And it changed'


This is very different from Vuex. Pinia only provides a method to define the rules of how to change the state. Giving up changes and relying only on Actions is a major change.

Pinia makes Actions more flexible:

  • It can be called through components or other action s

  • It can be invoked from other store's action.

  • Called directly on the store instance

  • Support synchronous or asynchronous

  • There are any number of parameters

  • It can contain logic about how to change the state (that is, the function of vuex's changes)

  • The status of the $patch method can be changed directly

    import { defineStore } from 'pinia'

    export const useMainStore = defineStore({
    id: 'mian',
    state: () => ({
    name: 'super administrator',
    getters: {
    nameLength: (state) =>,
    actions: {
    async insertPost(data:string){
    //Can do asynchronous
    // await doAjaxRequest(data); = data;

Environment variable configuration

vite provides two modes: development mode with development server and production mode

New project root directory: env.development :



New project root directory: env.production :



Used in components:


Configure package json:

Packaging distinguishes between development environment and production environment

"build:dev": "vite build --mode development",
"build:pro": "vite build --mode production",

Using the Naive UI of the component library

Component library selection. Here we choose Naive UI. As for why we choose it? Can I just say what you recommend?

  • Official introduction:
    • A Vue 3 component library
    • Relatively complete, adjustable theme, using TypeScript, not too slow
    • I little interesting

The introduction is still modest. Since Youda recommends it, it must have its advantages!!!

Install Naive UI

# Install component library
yarn add naive-ui
# Install fonts
yarn add vfonts

How to use

import { NButton } from "naive-ui"

Global configuration Config Provider

Global configuration sets the theme, language of internal components and the class name of DOM in which components are unloaded in other locations.

<n-config-provider :locale="zhCN" :theme="theme">
    <!-- container -->

I really like the theme configuration function

There is no compulsion in the selection of component library. You can select the appropriate component library according to your project needs

Vite common basic configuration

Basic configuration

Run agent and packaging configuration

server: {
    host: '',
    port: 3000,
    open: true,
    https: false,
    proxy: {}

Remove console debugger in production environment

  terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true

Production environment generation gz file

Opening gzip can greatly compress static resources and play a significant role in the speed of page loading.

Use vite plugin compression to compress resources by gzip or brotli. This step requires the cooperation of the server, and vite can only help you package them gz file. This plug-in is easy to use. You can even import it without configuring parameters.

# install
yarn add --dev vite-plugin-compression

Add to plugins:

import viteCompression from 'vite-plugin-compression'

// gzip compressed production environment generation gz file
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'gzip',
      ext: '.gz',

Final vite config. ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import viteCompression from 'vite-plugin-compression'

export default defineConfig({
  base: './', //Packaging path
  plugins: [
    // gzip compressed production environment generation gz file
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'gzip',
      ext: '.gz',
  // Configure alias
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
        additionalData:'@import "@/assets/style/mian.scss";'
  //Start service configuration
  server: {
    host: '',
    port: 8000,
    open: true,
    https: false,
    proxy: {}
  // Production environment packaging configuration
  //Remove the console debugger
  build: {
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,

Common plug-ins

You can view official documents:

  • @Vitejs / plugin Vue provides Vue 3 single file component support
  • @Vitejs / plugin Vue JSX provides Vue 3 JSX support (through a dedicated Babel conversion plug-in)
  • @Vitejs / plugin legacy provides traditional browser compatibility support for packaged files
  • On demand automatic import of unplugin Vue components
  • Vite plugin compression uses gzip or brotli to compress resources
  • ...

Highly recommended hooks Library

Because vue3 X and react hooks are really similar, so they are called hooks


At first sight of this library, I immediately thought of react's ahooks

VueUse is a collection of practical functions based on the Composition API. Generally speaking, this is a tool function package, which can help you quickly realize some common functions, so as to avoid writing and solving repeated work contents by yourself. And packaging based on Composition API. Make you more handy in vue3.

?? If you want to get started vue3, learn quickly!!!

?? Finally, let's give you the warehouse address:

Write at the end

Official account: front-end developers love to share web front-end related technical articles, video tutorials, hot topics, etc. Click a like?? Or attention is my greatest support.

Welcome to add friends by long clicking on the picture. I will share front-end industry trends, interview resources, learning ways and so on with you for the first time.

The official account is on the front page.

  • Reply to the interview questions and obtain the latest interview data of large factories.
  • Reply resume and obtain 3200 resume templates.
  • Reply to the actual combat of React and get the latest actual combat tutorial of React.
  • Reply to the actual combat of Vue and get the latest actual combat tutorial of Vue.
  • Reply ts to get the TypeAcript intensive course.
  • Reply to vite for intensive courses.
  • Reply to uniapp and get the intensive courses of uniapp.
  • Reply to js books and get js advanced books.
  • Reply to Node and get the actual combat tutorial of Nodejs+koa2.
  • Reply to the data structure algorithm and get the data structure algorithm tutorial.
  • Reply to the architect and get the architect learning resource tutorial.
  • More tutorial resources and applications are available. Please pay attention to them

Topics: Javascript Front-end html