共计 7055 个字符,预计需要花费 18 分钟才能阅读完成。
应用 vite 搭建 vue3 我的项目
通过在终端中运行以下命令,能够应用 Vite 疾速构建 Vue 我的项目。
$ npm init vite-app <project-name> | |
$ cd <project-name> | |
$ npm install | |
$ npm run dev |
引入 Element Plus
装置 Element Plus:
npm install element-plus --save
main.js 中残缺引入 Element Plus:
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') |
引入 SCSS
执行命令装置 sass,npm i sass -D
,而后在 vue 文件的 style 标签下退出 lang=”scss” 即可,这些与以前 vue2 都是一样的。
npm i sass -D
引入 eslint
装置 eslint
npm i eslint -D
应用 eslint 对本我的项目进行初始化
npx eslint --init
依照提醒进行设置,这是我抉择的设置
引入 vue-router
装置 Vue Router 4
npm install vue-router@4
在 src 目录下新建 router 文件夹,并在 router 下新建 index.js 进行路由配置
import * as VueRouter from 'vue-router' | |
const routes = [ | |
{ | |
path: '/', | |
component: () => import('../page/Home.vue') | |
}, { | |
path: '/login', | |
component: () => import('../page/Login.vue') | |
} | |
] | |
export default VueRouter.createRouter({history: VueRouter.createWebHashHistory(), | |
routes | |
}) |
在 main.js 下应用该中间件
import router from './router' | |
//... | |
app.use(router) |
引入 vuex
装置 vuex
npm install vuex@next --save
在 src 下创立 store 门路,并在 store 下创立 index.js
import {createStore} from 'vuex' | |
export default createStore({state () { | |
return {username: ''} | |
}, | |
mutations: {setUserName (state, payload) {state.username = payload} | |
} | |
}) |
在 main.js 下应用 store
import vuex from './store' | |
//... | |
app.use(vuex) |
引入 axios
对于网络申请,这里应用 axios,首先装置 axios
npm i axios
在 src 目录下创立 api 目录,并在 api 门路下创立 axios.js,配置 axios 实例
// axios.js | |
import axios from 'axios' | |
// import config from '../../config' | |
import {useRouter} from 'vue-router' | |
export default function () { | |
// 1. 发送申请的时候,如果有 token,须要附带到申请头中 | |
const token = localStorage.getItem('token') | |
let instance = axios | |
if (token) { | |
instance = axios.create({ | |
// baseURL: config.server, | |
headers: {authorization: 'Bearer' + token} | |
}) | |
} | |
const router = useRouter() | |
instance.interceptors.response.use((resp) => { | |
// 2. 响应的时候,如果有 token,保留 token 到本地(localstorage)if (resp.data.data.token) {localStorage.setItem('token', resp.data.data.token) | |
} | |
// 3. 响应的时候,如果响应的音讯码是 403(没有 token,token 生效),在本地删除 token | |
if (resp.data.code === 403) {localStorage.removeItem('token') | |
localStorage.removeItem('username') | |
router.push({name: 'Login'}) | |
} | |
return resp | |
}, | |
(err) => {return Promise.reject(err) | |
} | |
) | |
return instance | |
} |
在 api 门路下创立 index.js 编写 api
import request from './axios.js' | |
import config from '../../config' | |
export default { | |
// 登录 | |
login (params) {return request().post(`${config.server}/login`, params) | |
}, | |
// 获取用户列表 | |
getUserList (params) {return request().get(`${config.server}/user/list`, {params: params}) | |
}, | |
// 增加一个用户 | |
createUser (params) {return request().post(`${config.server}/user/`, params) | |
}, | |
//... |
接下来应用 vue3 的 composition api 进行组件的开发,这里列举一个 User 模块的开发:
<template> | |
<div class="user-wrap"> | |
<el-button | |
class="create-btn" | |
type="success" | |
size="small" | |
@click="handleCreate"> 新增用户 +</el-button> | |
<el-table | |
:data="tableData" | |
style="width: 100%"> | |
<el-table-column | |
label="用户名" | |
prop="username"> | |
</el-table-column> | |
<el-table-column | |
label="明码" | |
prop="password"> | |
</el-table-column> | |
<el-table-column | |
align="right"> | |
<template #header> | |
<el-input | |
v-model="search" | |
@blur="searchUser" | |
size="mini" | |
placeholder="输出用户名搜寻"/> | |
</template> | |
<template #default="scope"> | |
<el-button | |
size="mini" | |
@click="handleEdit(scope.$index, scope.row)"> 编辑 </el-button> | |
<el-button | |
size="mini" | |
type="danger" | |
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button> | |
</template> | |
</el-table-column> | |
</el-table> | |
<el-pagination | |
:hide-on-single-page="hideOnSinglePage" | |
class="page-wrap" | |
@size-change="handleSizeChange" | |
@current-change="handleCurrentChange" | |
:current-page="currentPage" | |
:page-sizes="[10, 20, 30, 40]" | |
:page-size="pageSize" | |
layout="total, sizes, prev, pager, next, jumper" | |
:total="totalCount"> | |
</el-pagination> | |
<el-dialog title="用户信息" v-model="dialogFormVisible"> | |
<el-form :model="form"> | |
<el-form-item label="用户名" :label-width="formLabelWidth"> | |
<el-input v-model="form.username" autocomplete="off"></el-input> | |
</el-form-item> | |
<el-form-item label="明码" :label-width="formLabelWidth"> | |
<el-input v-model="form.password" autocomplete="off"></el-input> | |
</el-form-item> | |
</el-form> | |
<template #footer> | |
<span class="dialog-footer"> | |
<el-button @click="dialogFormVisible = false"> 取 消 </el-button> | |
<el-button type="primary" @click="confirmUser"> 确 定 </el-button> | |
</span> | |
</template> | |
</el-dialog> | |
</div> | |
</template> | |
<script> | |
import {ref, computed} from 'vue' | |
import api from '../../../api/index' | |
import {ElMessage, ElMessageBox} from 'element-plus' | |
export default {setup () { | |
let status = '' | |
let userId = null | |
const formLabelWidth = ref('120px') | |
// 获取用户列表 | |
const tableData = ref([]) | |
async function getList (params) {const res = await api.getUserList(params) | |
if (res.data.success) { | |
tableData.value = res.data.data.userList | |
totalCount.value = res.data.data.count | |
search.value = '' | |
} else {ElMessage.error('获取用户列表失败:' + res.data.msg) | |
} | |
} | |
getList() | |
const form = ref({ | |
username: '', | |
password: '' | |
}) | |
const dialogFormVisible = ref(false) | |
// 提交用户信息 | |
async function confirmUser () { | |
// 验证信息是否齐全 | |
if (!(form.value.username && form.value.password)) {ElMessage.error('表单信息不全') | |
return | |
} | |
switch (status) { | |
case 'create': | |
createUser(form.value) | |
break | |
case 'edit': | |
updateUser(userId, form.value) | |
break | |
} | |
} | |
// 增加用户 | |
async function handleCreate () { | |
form.value = { | |
username: '', | |
password: '' | |
} | |
dialogFormVisible.value = true | |
status = 'create' | |
} | |
// 增加用户信息 | |
async function createUser (params) {const res = await api.createUser(params) | |
if (res.data.success) {getList() | |
ElMessage.success({ | |
message: '增加胜利', | |
type: 'success' | |
}) | |
dialogFormVisible.value = false | |
} else {ElMessage.error('增加失败:' + res.data.msg) | |
} | |
} | |
// 编辑用户 | |
async function handleEdit (index, row) {console.log(index, row) | |
dialogFormVisible.value = true | |
status = 'edit' | |
form.value.username = row.username | |
form.value.password = row.password | |
userId = row.id | |
} | |
// 批改用户信息 | |
async function updateUser (id, params) {const res = await api.updateUser(id, params) | |
if (res.data.success) { | |
ElMessage.success({ | |
message: '批改胜利', | |
type: 'success' | |
}) | |
getList() | |
dialogFormVisible.value = false | |
} else {ElMessage.error('批改失败:' + res.data.msg) | |
} | |
} | |
// 删除用户 | |
const handleDelete = async (index, row) => { | |
ElMessageBox.confirm('此操作将永恒删除该用户, 是否持续?', '提醒', { | |
confirmButtonText: '确定', | |
cancelButtonText: '勾销', | |
type: 'warning' | |
}).then(async () => {await delUser(row.id) | |
}).catch(() => { | |
ElMessage({ | |
type: 'info', | |
message: '已勾销删除' | |
}) | |
}) | |
} | |
// 删除用户信息 | |
async function delUser (id) {const res = await api.delUser(id) | |
if (res.data.success) {getList() | |
ElMessage.success({ | |
type: 'success', | |
message: '删除胜利!' | |
}) | |
} else {ElMessage.error('删除失败:' + res.data.msg) | |
} | |
} | |
// 搜寻用户 | |
const search = ref('') | |
async function searchUser () { | |
currentPage.value = 1 | |
pageSize.value = 10 | |
if (search.value === '') {getList({ pageindex: currentPage.value, pagesize: pageSize.value}) | |
return | |
} | |
currentPage.val = 1 | |
const res = await api.findUserByUsername({username: search.value}) | |
if (res.data.success) { | |
tableData.value = res.data.data.userList | |
ElMessage.success({ | |
message: '搜寻胜利', | |
type: 'success' | |
}) | |
} else {ElMessage.error('批改失败:' + res.data.msg) | |
} | |
} | |
// 分页相干 | |
const totalCount = ref(0) | |
const currentPage = ref(1) | |
const pageSize = ref(10) | |
function handleSizeChange (val) { | |
pageSize.value = val | |
getList({pageindex: currentPage.value, pagesize: val}) | |
} | |
function handleCurrentChange (val) { | |
currentPage.value = val | |
getList({pageindex: val, pagesize: pageSize.value}) | |
} | |
// 超过一页就暗藏分页插件 | |
const hideOnSinglePage = computed(() => {return totalCount.value <= 10}) | |
return { | |
tableData, | |
search, | |
dialogFormVisible, | |
form, | |
formLabelWidth, | |
createUser, | |
handleEdit, | |
handleDelete, | |
confirmUser, | |
handleCreate, | |
searchUser, | |
currentPage, | |
totalCount, | |
handleSizeChange, | |
handleCurrentChange, | |
pageSize, | |
hideOnSinglePage | |
} | |
} | |
} | |
</script> | |
<style lang="scss" scoped> | |
.user-wrap{ | |
width: 100%; | |
min-width: 500px; | |
.create-btn{ | |
margin-bottom: 10px; | |
display: flex; | |
justify-content: flex-end; | |
} | |
.page-wrap{margin-top: 10px;} | |
} | |
</style> |
正文完