目录
一、 Aside和 Header,Main组件拆分
1、Invalid prop: type check failed for prop “collapse“. Expected Boolean, got Function
原先我的写法是:
既然现在传过来的是Function, 那么有两个方法, 要么将传入的参数改为Boolean, 要么将collapse指定接收的参数类型改为Function
以下为第二种方法的改法:
2、created选项名称错误写成create,导致刷新未调用接口加载数据
3、子组件和父组件
子组件路由
const routes = [
{
path: '/',
name: 'Manage',
redirect: '/home',
component: () => import('../views/Manage.vue'),
children: [
{path: 'user',name: 'User',component: ()=>import ('../views/User.vue') },
{path: 'home',name: 'Home',component: ()=>import ('../views/Home.vue') }
]
父组件-》子组件传参数
1)子组件设置props选项
Aside.vue
export default {
name: "Aside",
props: {
isCollapse: Boolean,
logoTextShow: Boolean
}
}
2)父组件传参数:
manage.vue
<el-aside :width="sideWidth+'px'" style="box-shadow: 2px 0 6px rgb(0, 21, 41 / 35%);">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow"/>
</el-aside>
data() {
return {
collapseBtnClass: 'el-icon-s-fold',
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
};
},
User.vue
<template>
<div>
<div style="margin: 10px 0;">
<el-input suffix-icon="el-icon-search" style="width: 200px;" placeholder="请输入姓名" class="search" v-model="username" clearable></el-input>
<el-input suffix-icon="el-icon-message" style="width: 200px;" placeholder="请输入邮箱" class="search" v-model="email" clearable></el-input>
<el-input suffix-icon="el-icon-position" style="width: 200px;" placeholder="请输入地址" class="search" v-model="address" clearable></el-input>
<el-button class="ml-5" type="primary" @click="load">查询</el-button>
<el-button class="ml-5" type="warning" @click="reset">重置</el-button>
</div>
<div style="margin: 10px 0">
<el-button type="primary" @click="handleAdd">新增<i class="el-icon-circle-plus-outline"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确认'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定删除吗?"
@confirm ="delBatch" >
<el-button type="danger" slot="reference">批量删除<i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
<el-button type="primary">导入<i class="el-icon-bottom"></i></el-button>
<el-button type="primary" class="ml-5">导出<i class="el-icon-bottom"></i></el-button>
</div>
<el-table :data="tableData" border stripe :header-cell-class-name="headerBg" @selection-change="handleSelectionChange">
>
<el-table-column type="selection" width="55"> </el-table-column>
<el-table-column prop="id" label="ID" width="80px" align="center">
</el-table-column>
<el-table-column prop="username" label="用户名" width="140px" align="center">
</el-table-column>
<el-table-column prop="nickname" label="昵称" width="120px" align="center">
</el-table-column>
<el-table-column prop="email" label="邮箱" width="120px" align="center">
</el-table-column>
<el-table-column prop="phone" label="电话" width="120px" align="center">
</el-table-column>
<el-table-column prop="address" label="地址" width="200px" align="center">
</el-table-column>
<el-table-column label="操作" width="200px" align="center">
<template slot-scope="scope">
<el-button type="success" @click="handleEdit(scope.row)">编辑<i class="el-icon-edit"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text='确认'
cancel-button-text='我再想想'
icon="el-icon-info"
icon-color="red"
title="您确定删除吗?"
@confirm ="del(scope.row.id)" >
<el-button type="danger" slot="reference">删除<i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div style="padding: 10px 0;">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[2, 5, 10, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
<el-dialog title="用户信息" :visible.sync="dialogFormVisible" width="30%">
<el-form label-width = "80px" size = "small">
<el-form-item label="用户名">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="form.nickname" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.phone" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data(){
return {
tableData: [],
total: 0,
pageNum: 1,
pageSize: 2,
username: '',
nickname: '',
email: '',
phone: '',
address: '',
dialogFormVisible: false,
form: {},
multipleSelection: [],
headerBg: 'headerBg',
}
},
created(){
this.load()
},
methods: {
handleSizeChange(pageSize) {
console.log(pageSize);
this.pageSize = pageSize;
this.load();
},
handleCurrentChange(pageNum) {
console.log(pageNum);
this.pageNum = pageNum;
this.load();
},
load() {
//请求分页查询
// this.request.get("http://localhost:9090/user/page?pageNum="+this.pageNum+"&pageSize="+this.pageSize+"&username="+this.username).then(res=>{
// console.log(res)
// this.tableData =res.data
// this.total = res.total
// })
this.request.get("/user/page", {
params: {
pageNum: this.pageNum,
pageSize: this.pageSize,
username: this.username,
email: this.email,
address: this.address
}
}).then(res => {
console.log(res);
this.tableData = res.records;
this.total = res.total;
})
},
reset() {
this.username = '',
this.email = '',
this.address = '',
this.load();
},
handleAdd() {
this.dialogFormVisible = true,
this.form = {};
},
save() {
this.request.get("/user", this.form).then(res => {
if (res) {
this.$message.success("保存成功");
this.dialogFormVisible = false;
this.load();
}
else {
this.$message.error("保存失败");
this.dialogFormVisible = false;
this.load();
}
});
},
handleEdit(row) {
this.form = row;
this.dialogFormVisible = true;
},
del(id) {
this.request.delete("/user/" + id).then(res => {
if (res) {
this.$message.success("删除成功");
this.load();
}
else {
this.$message.error("删除失败");
}
});
},
handleSelectionChange(val) {
console.log(val);
this.multipleSelection = val;
},
delBatch() {
let ids = this.multipleSelection.map(v => v.id); //[1,2,3]
this.request.post("/user/del/batch", ids).then(res => {
if (res) {
this.$message.success("删除成功");
this.load();
}
else {
this.$message.error("删除失败");
}
});
}
}
}
</script>
<style scoped>
.headerBg {
background: #eee!important;
}
</style>
二、路由控制动态组件显示
<template>
<el-container style="min-height: 100vh;">
<el-aside :width="sideWidth+'px'" style="box-shadow: 2px 0 6px rgb(0, 21, 41 / 35%);">
<Aside :isCollapse="isCollapse" :logoTextShow="logoTextShow"/>
</el-aside>
<el-container >
<el-header style="border-bottom: 1px solid #ccc;">
<Header :collapseBtnClass="collapseBtnClass" :collapse="collapse"/>
</el-header>
<el-main>
<!-- 当前页面的子路由在当前位置显示 -->
<router-view/>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Aside from '@/components/Aside.vue'
import Header from '@/components/Header.vue'
export default {
data() {
return {
collapseBtnClass: 'el-icon-s-fold',
isCollapse: false,
sideWidth: 200,
logoTextShow: true,
};
},
components: {
Aside,
Header
},
methods: {
collapse() {
this.isCollapse = !this.isCollapse;
if (this.isCollapse) { //收缩
this.sideWidth = 64;
this.collapseBtnClass = 'el-icon-s-unfold';
this.logoTextShow = false;
}
else { //展开
this.sideWidth = 200;
this.collapseBtnClass = 'el-icon-s-fold';
this.logoTextShow = true;
}
}
}
}
</script>
<style>
.el-header {
background-color: #fff;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
三、面包屑菜单导航
1)Vuex安装
npm i Vuex -S
2)store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
currentPathName:''
},
mutations:{
setPath(state){
state.currentPathName= localStorage.getItem("currentPathName")
}
}
})
export default store
3)router 引入 store,
import store from '@/store'
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
//路由守卫
router.beforeEach((to,from,next)=>{
localStorage.setItem("currentPathName",to.name)
store.commit("setPath")
next()
})
4)main.js 引入Vuex
import store from './store'
new Vue({ router, store, render: h => h(App) }).$mount('#app')
5)面包屑使用store
Header.vue
<div stype="flex: 1;">
<span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>
<el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px;">
<el-breadcrumb-item :to="'/'">首页</el-breadcrumb-item>
<el-breadcrumb-item>{{currentPathName }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
computed: {
currentPathName(){
return store.state.currentPathName
}
},
watch:{
currentPathName(newVal,oldVal){
console.log(newVal);
}
问题:
this.store不存在