1、确保已经安装了最新版本的 Node.js,建议使用 v14.17.0 或以上版本。
2、打开终端,并执行以下命令安装 Vite:npm install -g vite。
3、在终端中进入你要创建项目的目录,并执行以下命令创建一个新的 Vue3 项目:vite create my-project。
4、选择手动选择特性并添加以下特性:
Choose a framework preset: vue
Choose a variant: vue-ts
Select features: (A)uto install
5、在安装完成后,通过cd my-project命令进入该项目的根目录。
6、执行npm install 或 yarn安装项目依赖。
7、安装额外依赖:npm install element-plus axios --save
8、修改main.ts文件配置项目:
// ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
const app = createApp(App)
// 配置路由
app.use(router)
// 配置 Vuex
app.use(store)
// 配置 Element Plus 组件库
app.use(ElementPlus)
// 挂载根组件
app.mount('#app')
9、配置 router/index.ts文件生效 Vue Router:
// ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
// * 新增部分代码
const Admin = () => import('@/views/Admin.vue')
// * 新增部分代码结束
// 路由配置
const routes: RouteRecordRaw[] = [ {
path: '/',
name: 'Home',
component: Home,
}, {
path: '/about',
name: 'About',
component: About,
},
// * 新增部分代码
{
path: '/
name: 'Admin',
component: Admin,
meta: {
requiresAuth: true,
},
},
// * 新增部分代码结束
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(),
routes,
})
// 路由守卫
router.beforeEach((to, from, next) => {
console.log('beforeEach', to, from)
// 判断是否需要登录
const requiresAuth = to.matched.some((record) => record.meta.requiresAuth)
if (requiresAuth) {
// 判断是否已登录
const isAuthenticated = !!localStorage.getItem('token')
if (isAuthenticated) {
next()
} else {
next('/login')
}
} else {
next()
}
})
router.afterEach((to, from) => {
console.log('afterEach', to, from)
})
export default router
10、封装 Axios 并配置拦截器:
// ts
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
// 配置自定义 axios 实例
const api = axios.create({
baseURL: '/api',
timeout: 5000,
})
// 添加请求拦截器
api.interceptors.request.use((config: AxiosRequestConfig) => {
// 给请求头添加 token 等信息
config.headers.Authorization = 'Bearer token'
return config
}, (error) => {
console.error(error.message)
return Promise.reject(error)
})
// 添加响应拦截器
api.interceptors.response.use((response: AxiosResponse) => {
if (response.data.code === 0) {
return response.data.data
} else {
console.error(response.data.message)
return Promise.reject(response.data.message)
}
}, (error) => {
console.error(error.message)
return Promise.reject(error.message)
})
export default api
11、在组件中使用 Axios:
// ts
import { defineComponent, reactive } from 'vue'
import api from '@/api'
export default defineComponent({
name: 'MyComponent',
setup() {
const state = reactive({
data: null,
isLoading: false,
})
const fetchData = async () => {
state.isLoading = true
try {
const data = await api.get('/data')
state.data = data
console.log(data)
} catch (error) {
console.error(error.message)
}
state.isLoading = false
}
return { state, fetchData }
},
})
12、添加登录和注销功能:
// ts
// store/index.ts
import { createStore } from 'vuex'
import api from '@/api'
api.defaults.headers.common['Authorization'] = ‘Bearer ${localStorage.getItem('token')}’
export default createStore({
state: {
user: null,
},
mutations: {
setUser(state, user) {
state.user = user
},
},
actions: {
async login({ commit }, { username, password }) {
try {
const response = await api.post('/login', { username, password })
localStorage.setItem('token', response.token)
api.defaults.headers.common['Authorization'] = ‘Bearer ${response.token}’
commit('setUser', response.user)
} catch (error) {
console.error(error.message)
}
},
logout({ commit }) {
localStorage.removeItem('token')
delete api.defaults.headers.common['Authorization']
commit('setUser', null)
},
},
modules: {},
})
// ts
// LoginComponent.vue
import { defineComponent, reactive } from 'vue'
import { useStore } from 'vuex'
export default defineComponent({
name: 'LoginComponent',
setup() {
const store = useStore()
const state = reactive({
username: '',
password: '',
})
const handleSubmit = () => {
store.dispatch('login', {
username: state.username,
password: state.password,
})
}
return { state, handleSubmit }
},
})
// vue
<!-- Home.vue -->
<template>
<div>
<h2>Home Page</h2>
<p>{{ message }}</p>
<button @click="handleLogout()">Logout</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useStore } from 'vuex'
export default defineComponent({
name: 'HomePage',
setup() {
const store = useStore()
const message = 'Welcome to the homepage.'
const handleLogout = () => {
store.dispatch('logout')
}
return { message, handleLogout }
},
})
</script>
13、最后,配置 ESLint 和 Prettier 避免在 import语句中使用 .ts后缀,并在 .prettierrc.js中添加以下配置:
// js
// .prettierrc.js
module.exports = {
semi: false,
singleQuote: true,
jsxSingleQuote: false,
trailingComma: 'es5', // https://prettier.io/docs/en/options.html#trailing-commas
arrowParens: 'avoid', // https://prettier.io/docs/en/options.html#arrow-function-parentheses
bracketSpacing: true,
}
// js
// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/vue3-essential',
'@vue/airbnb',
'@vue/typescript/recommended',
'@vue/prettier',
'@vue/prettier/@typescript-eslint',
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
plugins: [],
rules: {
'no-console': 'off',
'no-debugger': 'off',
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'vue/no-multiple-template-root': 'off',
},
}
这样你就成功地创建了一个 Vue3 项目,并集成了 TypeScript、Vite、Vuex、Axios、Sass、Element Plus 和 Vue Router,并配置好了路由守卫、路由拦截和 Axios 封装。