Vue3、Node全栈项目
Vue3
路由
-login.vue -mainbox.vue - home.vue - center.vue - user - adduser.vue - listuser.vue - news - addnews.vue - listnews.vue -product - addproduct.vue - listproduct.vue
import routesConfig from './config.js'
import store from '@/store/index.js'
const routes = [
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/mainbox',
name: 'mainbox',
component: MainBox
}
]
// 导航守卫
router.beforeEach((to, from, next) => {
if (to.name === "login") {
next()
} else {
if (!localStorage.getItem("token")) {
next({
path: "/login"
})
} else {
// 判断是否是第一次
if (!store.state.isGetterRouter) {
ConfigRouter()
next({
path: to.fullPath
})
}else{
next()
}
}
}
})
// 设置子路由
const ConfigRouter = function () {
routesConfig.forEach(item => {
router.addRoute('mainbox', item)
})
store.commit('changeGetterRouter',true)
}
-- config.js
import Home from '@/views/home/HomeViews.vue'
import Center from '@/views/center/CenterViews.vue'
import Adduser from '@/views/user/AdduserViews.vue'
import Listuser from '@/views/user/ListuserViews.vue'
import Listnews from '@/views/news/ListnewsViews'
import Addnews from '@/views/news/AddnewsViews'
import Addproduct from '@/views/product/AddproductViews.vue'
import Listproduct from '@/views/product/ListproductViews.vue'
import NotFound from '@/views/notfound/NotFoundViews.vue'
const routes = [
{
path:'/index',
component:Home
},
{
path:'/center',
component: Center
},
{
path:'/user/adduser',
component: Adduser
},
{
path:'/user/listuser',
component: Listuser
},
{
path:'/news/addnews',
component: Addnews
},
{
path:'/news/listnews',
component: Listnews
},
{
path:'/product/addproduct',
component: Addproduct
},
{
path:'/product/listproduct',
component: Listproduct
},
{
path:'/',
redirect:'/index'
},
{
path:'/:pathMatch(.*)*',
component:NotFound
}
]
export default routes
import { createStore } from 'vuex'
export default createStore({
state: {
isGetterRouter:false,
},
getters: {
},
mutations: {
changeGetterRouter(state,value){
state.isGetterRouter = value
},
},
actions: {
},
modules: {
},
})
页面设计
Login.vue
使用Element-Plus 表单组件
- el-form属性
- ref="loginFormRef" 校验方法
- :model="loginForm" 绑定数据
- :rules="rules" 校验
<template>
<div class="loginbox">
<h1> <span>AAA</span> 管理系统</h1>
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="rules"
status-icon
label-width="120px"
class="demo-ruleForm"
>
<el-form-item label="用户账号" prop="username">
<el-input v-model="loginForm.username" type="text" autocomplete="off" />
</el-form-item>
<el-form-item label="用户密码" prop="password">
<el-input
v-model="loginForm.password"
type="password"
autocomplete="off"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)"
>登入</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import {ref,reactive} from "vue"
import {useRouter} from 'vue-router'
const loginFormRef = ref()
const loginForm = reactive({
username:'',
password:''
})
const router = useRouter()
const submitForm = ()=>{
loginFormRef.value.validate((valid)=>{
console.log(valid);
if(valid){
localStorage.setItem('token','lijiacheng')
router.push("/index")
}
})
console.log(123);
}
const rules = reactive({
username:[
{
required:true,message:'请输入用户名',triggere:'blur'
}
],
password:[
{
required:true,message:'请输入密码',triggere:'blur'
}
],
})
</script>
<style lang="scss" scoped>
.loginbox{
width: 600px;
height: 400px;
margin: 300px auto;
padding: 0 30px;
border:1px solid #dcdfe6;
h1{
text-align: center;
padding: 50px 0;
span{
color:blue
}
}
}
</style>
使用Element-Plus Layout布局
mainbox
- Aside.vue =>components //侧边栏
-Header =>components //right头部
-router-view =>views//路由出口
<el-container>
<Aside/> <!-- 侧边栏-->
<el-container direction="vertical">
<Header/><!-- right头部 -->
<el-main> <router-view/></el-main> <!-- 路由出口 -->
</el-container>
</el-container>
Aside.vue
- 重点用到了Menu菜单
- 折叠宽度,宽度切换
- <el-menu
* :collapse="$store.state.isCollapse" 折叠状态默认false不折叠(数据持久化vuex用到了vuex-persistedstate)
* :default-active="route.fullPath" 状态保持import {useRoute} from 'vue-router' const route = useRoute()
:collapse-transition="false" 折叠动画默认true
:router="true" 路由跳转是否跟着index值同步
<template>
<el-aside :width="$store.state.isCollapse?'64px':'200px'">
<el-menu
:collapse="$store.state.isCollapse"
:collapse-transition="false"
:router="true"
:default-active="route.fullPath"
>
<el-menu-item index="/index">
<el-icon><HomeFilled /></el-icon>
<span>首页</span>
</el-menu-item>
<el-menu-item index="/center">
<el-icon><Avatar /></el-icon>
<span>个人中心</span>
</el-menu-item>
<el-sub-menu index="user">
<template #title>
<el-icon><UserFilled /></el-icon>
<span>用户管理</span>
</template>
<el-menu-item index="/user/adduser">添加用户</el-menu-item>
<el-menu-item index="/user/listuser">用户列表</el-menu-item>
</el-sub-menu>
<el-sub-menu index="news">
<template #title>
<el-icon><MessageBox /></el-icon>
<span>新闻管理</span>
</template>
<el-menu-item index="/news/addnews">创建新闻</el-menu-item>
<el-menu-item index="/news/listnews">新闻列表</el-menu-item>
</el-sub-menu>
<el-sub-menu index="product">
<template #title>
<el-icon><Reading /></el-icon>
<span>产品管理</span>
</template>
<el-menu-item index="/product/addproduct">创建产品</el-menu-item>
<el-menu-item index="/product/listproduct">产品列表</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
</template>
<script setup>
import {
HomeFilled,
Avatar,
UserFilled,
MessageBox,
Reading,
Pointer} from '@element-plus/icons-vue'
import {useRoute} from 'vue-router'
const route = useRoute()
console.log(route);
</script>
<style lang="scss" scoped>
.el-aside{
height: 100vh;
}
.el-aside{
height: 100vh;
}
</style>
- el-menu属性
- :collapse="$store.state.isCollapse" 折叠状态默认false不折叠、数据持久化 刷新不会改变
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate' //引入数据持久化
export default createStore({
state: {
isGetterRouter:false,
isCollapse:false
},
getters: {
},
mutations: {
changeGetterRouter(state,value){
state.isGetterRouter = value
},
setCollapse(state){
state.isCollapse = !state.isCollapse
}
},
actions: {
},
modules: {
},
plugins: [createPersistedState({
paths:['isCollapse'] //只让isCollapse数据持久化
})]
})
- el-menu属性
- :default-active="route.fullPath" 状态保持import {useRoute} from 'vue-router' const route = useRoute()
import {useRoute} from 'vue-router'
const route = useRoute()
console.log(route);