Recommended development environment

  • Node: Recommended version >= 12.0.0 download link

  • Git: version management tool

  • Visual Studio Code: Latest version

  • Vetur-vue development requirements

  • Eslint- Script code checking

  • Prettier – Code formatting

  • Stylelin-css formatting

Create a Vite2 project

Official documentation: Vite2, compatibility note: Vite requires node.js >= 12.0.0.


npm init @vitejs/app #or yarn create @vitejs/app

Copy the code

We can directly specify the project name and the template you want to use through the additional command line option. We can directly generate the project


# npm 6.x

npm init @vitejs/app my-vue-app --template vue



#NPM 7+, requires additional double lines:

npm init @vitejs/app my-vue-app -- --template vue



# yarn

yarn create @vitejs/app my-vue-app --template vue

Copy the code

Install Element-Plus

Official document address: element-plus, specific configuration: Quick start


npm install element-plus -S #or yarn add element-plus -S

Copy the code

A complete introduction

Write to main.js


import { createApp } from 'vue'

import ElementPlus from 'element-plus';

import 'element-plus/lib/theme-chalk/index.css';

import App from './App.vue';


const app = createApp(App)

app.use(ElementPlus)

app.mount('#app')

Copy the code

According to the need to load

First, install viet-plugin-style-import:


#npm

npm install vite-plugin-style-import -D

# yarn

yarn add vite-plugin-style-import -D

Copy the code

Then, change the viet.config.js to:

Introduce the.scSS style


import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

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


export default defineConfig({

plugins: [

vue(),

styleImport({

libs: [{

libraryName: 'element-plus'.esModule: true.ensureStyleFile: true.resolveStyle: (name) = > {

name = name.slice(3)

return `element-plus/packages/theme-chalk/src/${name}.scss`;

},

resolveComponent: (name) = > {

return `element-plus/lib/${name}`; },}]})Copy the code

Import the required components in main.js:


import { createApp } from 'vue'

import { ElButton, ElSelect, ElRow, ElCol } from 'element-plus';

// If you want to use the.scss style file, you need to import the base.scss file

import 'element-plus/packages/theme-chalk/src/base.scss'

import App from './App.vue'

const app = createApp(App)

app.component(ElButton.name, ElButton);

app.component(ElSelect.name, ElSelect);

app.component(ElRow.name, ElRow);

app.component(ElCol.name, ElCol);


app.mount('#app')

Copy the code

Eelement Plus is optimized for on-demand loading

Create the plugin file in the SRC directory and create the Element on-demand load file el-comp.js


import {

ElAlert,

ElAside,

ElButton,

ElSelect,

ElRow,

ElCol,

ElForm,

ElFormItem,

ElInput,

ElTabs,

ElTabPane,

ElCheckbox,

ElIcon,

ElDivider,

} from 'element-plus';


// The required components

export const components = [

ElAlert,

ElAside,

ElButton,

ElSelect,

ElRow,

ElCol,

ElForm,

ElFormItem,

ElInput,

ElTabs,

ElTabPane,

ElCheckbox,

ElIcon,

ElDivider,

];



/ / register

export default (app) => {

components.forEach((component) = > {

app.component(component.name, component);

});

};

Copy the code

It is then used in main.js to remove the code that Element loaded on demand


// main.js

import { createApp } from 'vue';

import elementPlus from './plugin/el-comp';

import 'element-plus/packages/theme-chalk/src/base.scss';

import App from './App.vue';

const app = createApp(App);

// Register elementPlus components/plug-ins

elementPlus(app);

Copy the code

Install sASS precompile

The Element-Plus style is based on Sass, so it is recommended to install Sass to be consistent


# npm

npm install sass -S

# or yarn

yarn add sass -S

Copy the code

Create a styles folder in the SRC directory to store the style files.

| - SRC | - styles. | - common SCSS / / public style file | -- variable. SCSS file | -- index. / / style variables SCSS / / import merge file | -- reset. SCSS / / Reset the browser default style fileCopy the code

Where index. SCSS code reference


@import './common.scss';

@import './reset.scss';

@import './variable.scss';

Copy the code

SCSS files are imported globally

Some common styles or variables will be used in normal development, which will be troublesome to introduce separately for each page. You can use the following methods to solve this problem. If there are other methods, find them by yourself

Add the following code to the viet.config. js file


export default defineConfig({

// ...

css: {

preprocessorOptions: {

// Introduce common styles

scss: {

// styles/index.scss style files are in the SRC directory

additionalData: `@use "@/styles/index.scss" as *; `}}}}Copy the code
Styles are prefixed automatically

Install Autoprefixer and PostCSS


# npm

npm install autoprefixer postcss -D

# yarn

yarn add autoprefixer postcss -D

Copy the code

Then create the postcss.config.js file


// postcss.config.js

module.exports = {

plugins: [

require('autoprefixer')]}Copy the code

Modify the vite. Config. js code


// vite.config.js

export default defineConfig({

css: {

postcss: {

plugins: [

require('autoprefixer')]}}})Copy the code

The code specification EsLint

For detailed configuration, click Detailed Configuration document address

We use ESLint to standardize project code, aspect multiplayer development, and read code. First install the dependencies


# npm

npm install eslint babel-eslint eslint-plugin-prettier eslint-plugin-vue prettier @vue/eslint-config-prettier -D

# yarn

yarn add eslint babel-eslint eslint-plugin-prettier eslint-plugin-vue prettier @vue/eslint-config-prettier -D

Copy the code

Then create the.eslintrc.js file in the project root directory with the following contents:


module.exports = {

root: true.env: {

node: true,},extends: ['plugin:vue/vue3-essential'.'eslint:recommended'.'@vue/prettier'].parserOptions: {

parser: 'babel-eslint',},rules: {

'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off'.'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'.'prettier/prettier': [

'warn',

{

printWidth: 80.// Length per line (default 80)

tabWidth: 2.// How many Spaces per TAB (default: 2)

useTabs: false.// Whether to indent with TAB (default false)

semi: false.// Use single quotes (default false)

singleQuote: true.// Declaration ends with a semicolon (default true)

quoteProps: 'as-needed'.jsxSingleQuote: false.trailingComma: 'es5'.// Use trailing commas for multiple lines (default none)

bracketSpacing: true.// Use Spaces between braces for object literals (default true)

jsxBracketSameLine: false.// In multi-line JSX, the > is placed at the end of the last line instead of starting on another line (default false)

arrowParens: 'avoid'.// Avoid parentheses for arrow functions with only one argument (default: avoid)

htmlWhitespaceSensitivity: 'ignore'.vueIndentScriptAndStyle: true.endOfLine: 'lf',},],},}Copy the code

If some files do not require ESLint validation, we need to create.eslintignore files in the root directory to ignore those files


src/assets

src/icons

public

dist

node_modules

Copy the code

V. Install vue-router 4.x


# npm

npm install vue-router@next -S

# or yarn

yarn add vue-router@next -S

Copy the code

Create the SRC /router/index.js route configuration file in the SRC directory

Note: complete file name (.vue) is required. It is not recommended to ignore the suffix of vite. For alias configuration, refer to the viet-config. js file for alias configuration


import { createRouter, createWebHashHistory } from 'vue-router';


const router = createRouter({

history: createWebHashHistory(),

routes: [{path: '/'.redirect: '/index'

},

{

path: '/index'.name: 'Index'.// Note the introduction of full file names (.vue), vite does not recommend ignoring the suffix

component: () = > import('views/index/index.vue'),

meta: {

title: 'home'}}},]);export default router

Copy the code

Vi. Install Vex4.x


# npm

npm install vuex@next -S

# or yarn

yarn add vuex@next -S

Copy the code
Vuex engineering configuration

Create the store folder in SRC directory as follows:

| - SRC | - store | - modules / / modules folder | -- user. | js / / the user module -- getters. | js / / getter file -- index. Js / / vuex file entryCopy the code

Use case

  • store/modules/user.jsUser module, definitionstate.mutations.actions

const state = {

userInfo: {},

token: 'VUEX_TOKEN'

}

const mutations = {

SET_USERINFO: (state, userInfo) = > {

state.userInfo = userInfo

}

}

const actions = {

setUserInfo: ({commit}, userInfo) = > {

commit('SET_USERINFO', userInfo)

}

}


export default {

state,

mutations,

actions

}

Copy the code
  • store/getters.js, requires global variables to be obtained through getters

const getters = {

    userInfo: (state) = > state.user.userInfo,

    token: (state) = > state.user.token,

};

export default getters;

Copy the code
  • store/index.js, vuEX entry file, passimport.meta.globEagerTo obtainmodulesUnder all module files, do not need to import each file separately

import { createStore } from 'vuex'

import getters from './getters.js'


// https://vitejs.dev/guide/features.html#glob-import

const modulesFiles = import.meta.globEager('./modules/*.js')


let modules = {}

for (const path in modulesFiles) {

const moduleName = path.replace(/(.*\/)*([^.]+).*/gi.'$2')

modules[moduleName] = modulesFiles[path].default

}


const store = new createStore({

modules,

getters,

})


export default store

Copy the code

Use in main.js


import store from "@/store";

import App from './App.vue'

import store from "@/store";


const app = createApp(App)

app.use(store)

app.mount('#app')

Copy the code

Install AxiOS


# npm

npm install axios -S

# yarn

yarn add axios -S

Copy the code

After the installation is complete, create the SRC /config/net.config.js file in the SRC directory

Vite export default {} export const netConfig = {const netConfig = {… }


// net.config.js

/ * * *@description Configure axiOS request base information *@author hu-snail 1217437592@qq.com

*/


export const netConfig = {

// The base URL of axios

baseURL:

process.env.NODE_ENV === 'development'

? 'https://xxx/api'

: 'https://xxx/api'.// Configure CORS for the development server. Any source is enabled and allowed by default, passing an option object to adjust behavior or set to false to indicate disabled

cors: true.// Define the configuration according to the backend

contentType: 'application/json; charset=UTF-8'.// When the message box disappears

messageDuration: 3000.// Maximum request time

requestTimeout: 10000.// The operation is normal. The value can be String, Array, and int

successCode: [200.0].// Login invalid code

invalidCode: -1.// No permission code

noPermissionCode: -1,}Copy the code
Axios encapsulates processing

import axios from 'axios';

import { netConfig } from '@/config/net.config';

const {

baseURL,

contentType,

invalidCode,

noPermissionCode,

requestTimeout,

successCode } = netConfig;

import store from '@/store/index.js';

import router from '@/router/index.js';

import { ElMessageBox, ElMessage } from 'element-plus';

// eslint-disable-next-line no-unused-vars

let tokenLose = true;

/ * * * *@description Handle code exception *@param {*} code

* @param {*} msg* /

const handleCode = (code, msg) = > {

switch (code) {

case invalidCode:

tokenLose = false;

ElMessageBox.confirm('You have been disconnected, or access error, please log in again! '.'Log in again', {

confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning',

})

.then(async() = > {// Handle the re-login logic

})

.catch(() = > {

tokenLose = true;

});

break;

case noPermissionCode:

router.push({ path: '/ 401' }).catch(() = > {});

break;

default:

console.log(msg);

/ / Vue. Prototype. $baseMessage (MSG | | ` backend interface ${code} abnormal `, "error");

break; }};const instance = axios.create({

baseURL,

timeout: requestTimeout,

headers: {

'Content-Type': contentType,

},

});


instance.interceptors.request.use(

(config) = > {

// Process token header information

if (store.getters.token) {

// config.headers['Authorization'] = ''

}

return config;

},

(error) = > {

return Promise.reject(error); }); instance.interceptors.response.use((response) = > {

const res = response.data;

const { data } = response;

const { code, msg } = data;

// The operation succeeded

if(successCode.indexOf(code) ! = = -1) {

return res;

} else {

handleCode(code, msg);

return Promise.reject(); }},(error) = > {

const { response, message } = error;

if (error.response && error.response.data) {

const { status, data } = response;

handleCode(status, data.msg || message);

return Promise.reject(error);

} else {

let { message } = error;

if (message === 'Network Error') {

message = 'Back-end interface connection is abnormal';

}

if (message.includes('timeout')) {

message = 'Backend interface request timed out';

}

if (message.includes('Request failed with status code')) {

const code = message.substr(message.length - 3);

message = 'Back end Interface' + code + 'abnormal';

}

ElMessage(message || 'Back-end interface unknown exception'.'error');

return Promise.reject(error); }});export default instance;

Copy the code

Eight. Vite packaging problem

  • Vite package after page blank page solution

// vite.config.js

export default defineConfig({

base: '/',})Copy the code
  • Vite is packaged to access resources across domain solutions

Vite itself relies on ESModule for module loading, and ESModule does not support file:// local access (in fact, it is not required in production at all).

For local access, there are two ways

  • Method 1: Installserve

# npm

npm i serve -g

# yarn

yarn add serve -g

Copy the code

Then go to the root directory of the packaged file (dist, for example) and run the serve command to quickly start the Web service


Serving!

Local: http://localhost:54698

Copy the code
  • Method 2: Executenpm run preview

// package.json

[

"scripts": {

"build": "vite build --mode production"."preview": "vite build && vite preview"},]Copy the code

Automatically adds the compatibility prefix to the CSS

Plug-ins to install

  • Autoprefixe – Parses CSS and adds vendor prefixes to rules via Can I Use

  • Postcss – Use the JS plugin to convert the sample

Installing a plug-in


# npm

npm install autoprefixe postcss -D

# yarn

yarn add autoprefixe postcss -D

Copy the code

Create postcss.config.js in the project root directory


module.exports = {

plugins: {

// Compatible browser, add prefix

autoprefixer: {

overrideBrowserslist: [

'the Android 4.1'.'iOS 7.1'.'Chrome > 31'.'ff > 31'.'ie >= 8'.//'last 2 versions', // All major browsers have the latest 2 versions].grid: true,}}};Copy the code

Install byteDance IconPark library and Element SvgIcon library

Iconpark documentation: github.com/bytedance/I…

Icon library: iconpark.oceanengine.com/official

Install IconPark


# npm

npm install @icon-park/vue-next -S

# yarn

yarn add @icon-park/vue-next -S

Copy the code

Install SvgIcon


# npm

npm install @element-plus/icons -S

# yarn

yarn add @element-plus/icons -S

Copy the code

Register the icon on demand

Create the icon-park.js file in the SRC /plugin directory


// icon-park.js

/** * bytedance icon library: https://iconpark.oceanengine.com/official * and vue3 https://github.com/bytedance/IconPark/tree/master/packages/vue-next  * element-plus icon: https://element-plus.gitee.io/#/zh-CN/component/icon *@description Icon library registration on demand *@author hu-snail

* @example <icon-user theme="outline" size="16" fill="#999" />

* @example <el-icon :size="20"> <edit /> </el-icon>

*/


// iconpark

import { User, Lock, Alipay, Wechat, Github, Twitter, Google } from '@icon-park/vue-next';

// el-icon

import { Edit } from '@element-plus/icons';


// The required components

export const components = [User, Lock, Alipay, Edit, Wechat, Github, Twitter, Google];


/ / register

export default (app) => {

components.forEach((component) = > {

app.component(component.name.replace('icon-'.' '), component);

});

};

Copy the code

Then use it in main.js and add the following code


// main.js

import iconPark from './plugin/icon-park';

// Register bytedance icon

iconPark(app);

Copy the code

Used in template


<template>

<div class="icon">

<! -- iconpark -->

<user theme="outline" size="16" fill="# 999" />

<! -- element-plus icon -->

<el-icon :size="20"> <edit /> </el-icon>

</div>

</template>

Copy the code