Use Vite to quickly create scaffolding
1. Run the installation command using YARN
Install yarn create @vitejs/app vue3_ts_vite_pinia
2. Choosevue
vue-ts
Complete the installation
3. Go to the vue3_ts_vite_pinia project and run the yarn command to install dependencies. After the dependencies are installed, use yarn dev to start the project
Start the project yarn dev
2. Route Configuration (vue-router@4)
The basic configuration
1. Use YARN to install vue-router@4
Install yarn add vue-router@4
2. Create a router folder under the SRC folder and create index.ts under the router folder
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/'.name: 'Index'.component: () = > import('@/pages/index/Index.vue'),}]const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
Copy the code
Note :RouteRecordRaw is a built-in type
3. Import and register the router in main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
const app = createApp(App)
app.use(router)
app.mount('#app')
Copy the code
<template>
// <img alt="Vue logo" src="./assets/logo.png" />
// <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
<router-view></router-view>
</template>
Copy the code
Routing guard
Add router/index.ts router/index.ts router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/'.name: 'Index'.component: () = > import('@/pages/index/Index.vue'),}]const router = createRouter({
history: createWebHistory(),
routes,
})
router.beforeEach((to,from) = >{
if(pass){
console.log('pass')
// No further release with next()
}else{
return false}})export default router
Copy the code
(2) The routing guard within the component
New composite API can replace the original component inside guard, onBeforeRouteLeave(triggered when leaving the current page route), onBeforeRouteUpdate(triggered when route update)
onBeforeRouteLeave((to,form) = >{})Copy the code
Page using
1. Basically use (1) jump within the page
import { useRouter,useRoute } from 'vue-router';
const go=() = >{
const Router=useRouter()
const Route=useRoute()
Router.push({
name:'/login'.query: {id:'123456'}})}Copy the code
3. State Management (Pinia configuration)
Js state management library Pinia is a lightweight state management library recommended by the Vue core team. As Pinia is also a product of Vuex R&D team and supported by Vue, it is highly likely to replace Vuex. Even if the promotion of Pinia is not smooth, we don’t need to worry too much. Many of its uses will most likely be ported to VEX5. Compared to Vuex,Pinia is easier to get started, mutations, and Actions support synchronous or asynchronous.
The basic configuration
1. Use YARN to install pinia@next
Install yarn add pinia@next
2. Create a store folder in the SRC folder and create main.ts folder in the store folder
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user'.state: () = > ({
name: 'Username'
}),
getters: {
nameLength: (state) = > state.name.length,
},
actions: {
updataUser(data: any) {
console.log(data)
}
}
})
Copy the code
Note :RouteRecordRaw is a built-in type
3. In main.ts, introduce createPinia
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
Copy the code
The basic use
1. Access to the state
- Direct access to
<template>
<div>{{userStore.name}}</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
const userStore = useUserStore()
</script>
Copy the code
- The computed for
<template>
<div>{{name}}</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
const userStore = useUserStore()
const name=computed(() = >{
userStore.name
})
</script>
Copy the code
- Structure, but will not be responsive, need to use storeToRefs
<template>
<div>{{name}}</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
import {storeToRefs} from 'pinia'
const userStore = useUserStore()
const name=storeToRefs(userStore)
</script>
Copy the code
2. Set up the state
- Directly modifying
<template>
<div>{{userStore.name}}</div>
<div @click="updateName">Modify the name</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
const userStore = useUserStore()
const updateName = () = > {
userStore.name = 'Directly modified name'
}
</script>
Copy the code
- $patch Modifies data in the store
<template>
<div>{{userStore.name}}</div>
<div @click="updateName">Modify the name</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
const userStore = useUserStore()
const updateName = () = > {
userStore.$patch({
name: '$patch modified name '})}</script>
Copy the code
- Actions Modifies data in the store
<template>
<div>{{userStore.name}}</div>
<div @click="updateName">Modify the name</div>
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/user.ts"
const userStore = useUserStore()
const updateName = () = > {
userStore.updataUser('Actions changed name')}</script>
Copy the code
Use this in actions to modify state data
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user'.state: () = > ({
name: 'Username'
}),
getters: {
nameLength: (state) = > state.name.length,
},
actions: {
updataUser(newName: string) {
this.name=newName
}
}
})
Copy the code
3. Use Getters
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user'.state: () = > ({
name: 'Username'
}),
getters: {
nameLength: (state) = > state.name.length,
},
})
Copy the code
<template>
<div>{{userStore.nameLength}}</div>
</template>
Copy the code
4. Use the Actions
- Sync actions using
If you use the same method in setting state, you can directly use this to set the data in state
- Use asynchronous actions
Support async await. This can be used between actions in the same store. Hooks can be used between actions in different stores
import { defineStore } from 'pinia'
import {userOtherStore} from './otherStore'
export const useUserStore = defineStore({
id: 'user'.state: () = > ({
name: 'Username'
}),
actions: {
async login(params){
const {data}=await api.login(params)
this.updataUser(data) // This can be used between actions in the same store
},
updataUser(newName: string) {
this.name=newName
const otherStore=userOtherStore() // Actions in different stores can be called using hooks
otherStore.setName(newName)
}
}
})
Copy the code
4. Unified Request Encapsulation (Axios Encapsulation)
1. Use yarn to install axiOSCopy the code
Install yarn add axios
2. Under the SRC folder, create the service folder, and under the service folder, create http.ts
import axios, { AxiosRequestConfig } from 'axios'
// Set the request header and request path
axios.defaults.baseURL = '/api';
// Now, all requests using this instance will wait 2.5 seconds before they time out
axios.defaults.timeout = 2500;
axios.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8';
// Add request interceptor
axios.interceptors.request.use(function (config) :AxiosRequestConfig<any> {
// What to do before sending the request
config.headers.token = 'your token'
return config;
}, function (error) {
// What to do about the request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
// all status codes in the 2xx range trigger this function.
// What to do with the response data
return response;
}, function (error) {
// Any status code outside the 2xx range triggers this function.
// Do something about the response error
return Promise.reject(error);
});
interface ResType<T> {
code: number data? : Tmsg: 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) = > {
axios
.get(url, { params })
.then((res) = > {
resolve(res.data)
})
.catch((err) = > {
reject(err.data)
})
})
},
post(url, params) {
return new Promise((resolve, reject) = > {
axios
.post(url, JSON.stringify(params))
.then((res) = > {
resolve(res.data)
})
.catch((err) = > {
reject(err.data)
})
})
},
upload(url, file) {
return new Promise((resolve, reject) = > {
axios
.post(url, file, {
headers: { 'Content-Type': 'multipart/form-data' },
})
.then((res) = > {
resolve(res.data)
})
.catch((err) = > {
reject(err.data)
})
})
},
download(url) {
const iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = url
iframe.onload = function () {
document.body.removeChild(iframe)
}
document.body.appendChild(iframe)
},
}
export default http
Copy the code
3. Create an API folder under the service folder to manage requests in a unified manner. Create login under API and login.ts and type.ts under login
- The directory structure
- login.ts
import http from '@/service/http'
import { ILoginApi } from './type'
const loginApi: ILoginApi = {
login(params) {
return http.post('/login', params)
}
}
Copy the code
- type.ts
export interface DataType {
name: string
}
export interface ResType<T> {
code: number data? : Tmsg: string err? : string }export interface ILoginApiParams {
id: number
}
export interface ILoginApi {
login: (params: ILoginApiParams) = > Promise<ResType<DataType>>
}
Copy the code
5. UI Component Library (Naive UI, Ant Design Vue, Element Plus)
At present, there are many choices of UI component libraries. Naive UI is a component library recommended by Naive UI. The content style is beautiful and novel, but it is a new component library after all. Some of the most popular open source backend, vben-Admin, use Ant Design Vue. As for Element Plus, it has just been developed, so it is more reasonable to choose Ant Design Vue.
The basic configuration
1. Use YARN to install ant-design-vue@next
Install yarn add ant-design-vue@next
2. Global registration in main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(Antd);
app.mount('#app')
Copy the code
3. Use within components
<template>
<div :style="{ background: 'rgb(190, 200, 200)', padding: '26px 16px 16px' }">
<a-button type="primary" ghost>Primary</a-button>
<a-button ghost>Default</a-button>
<a-button type="dashed" ghost>Dashed</a-button>
<a-button danger ghost>Danger</a-button>
<a-button type="link" ghost>Link</a-button>
</div><! --<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />-->
</template>
Copy the code
Vi. Environment variable configuration and vite basic configuration
Environment Variable Configuration
- The outermost file location is created
.env.development
and.env.production
file
.env.development
NODE_ENV=development
VITE_APP_WEB_URL= 'YOUR WEB URL'
Copy the code
.env.production
NODE_ENV=production
VITE_APP_WEB_URL= 'YOUR WEB URL'
Copy the code
2. Console. Log (import.meta.env.vite_app_web_URL)
Vite environment configuration
1. Configure the type alias
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
The '@': path.resolve(__dirname, 'src'),}}})Copy the code
If path reports an error, install @types/node
2. Introduce global styles such as SCSS
export default defineConfig({
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/assets/style/main.scss"; '}}}})Copy the code
3. Configure the proxy
server: {
port: VITE_PORT,
// Load proxy configuration from .env
proxy: {},},Copy the code
4. Dependencies that are forced out of the prebuild.
optimizeDeps: {
// @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly
include: [
'@iconify/iconify'.'ant-design-vue/es/locale/zh_CN'.'moment/dist/locale/zh-cn'.'ant-design-vue/es/locale/en_US'.'moment/dist/locale/eu',].exclude: ['vue-demi'],},Copy the code
5. Build package
build: {
target: 'es2015'.outDir: OUTPUT_DIR,
terserOptions: {
compress: {
keep_infinity: true.// The production environment removes the console debugger value to a Boolean value
drop_console: VITE_DROP_CONSOLE,
drop_debugger: VITE_DROP_DEBUGGER
},
},
// Turning off brotliSize display can slightly reduce packaging time
brotliSize: false.chunkSizeWarningLimit: 1500,},Copy the code
Vben-admin inside the framework configuration to do a detailed interpretation, especially vite configuration
Hand vben – admin
Write in the end: this article is just my learning record, there may be many problems and imperfect place, welcome you big boss criticism and correction, the opportunity will continue to update the content, in addition to thank big @ front-end small dish chicken chicken pecking article inspiration and guidance, we can also go to read big guy article address