高清版思维导图见后台管理项目地址
1.login登录页面
< el-form >表单
在 Form 组件中,每一个表单域由一个 Form-Item 组件构成,表单域中可以放置各种类型的表单控件,包括 Input、Select、Checkbox、Radio、Switch、DatePicker、TimePicker
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
<el-form
label-position="top" --【 对齐方式 (顶部对齐) 登录-换行-input的形式】
label-width="80px" -- 【表单域标签的宽度。作为 Form 直接子元素的 form-item 会继承该值。支持 auto】
:model="formdata" -- 【双向数据绑定,表单数据对象】
class="login-form"
:rules="rules" -- 【表单验证规则
ref="formdata" -- 【vue操作dom元素】
><el-form-item label="用户名" -- 【label是form-item的属性】prop="username" -- 【设置为需校验的字段名】><el-inputv-model="formdata.username"placeholder="请输入一个美丽的用户名"prefix-icon="el-icon-s-custom"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="formdata.password" type="password"placeholder="请输入密码"prefix-icon="el-icon-s-goods" -- 【input标签内使用图标】show-password --【可显示密码】></el-input></el-form-item>
</el-form>
2.主页home页面
2.1< el-container > 布局容器
用于布局的容器组件,方便快速搭建页面的基本结构:
< el-container>:外层容器。当子元素中包含 或 时,全部子元素会垂直上下排列,否则会水平左右排列。
< el-header>:顶栏容器。
< el-aside>:侧边栏容器。
< el-main>:主要区域容器。
< el-footer>:底栏容器。
以上组件采用了 flex 布局,使用前请确定目标浏览器是否兼容。此外,< el-container> 的子元素只能是后四者,后四者的父元素也只能是 < el-container>。
<el-container><el-header>Header</el-header><el-container><el-aside width="200px">Aside</el-aside><el-main>Main</el-main></el-container>
</el-container>
2.2 Layout 布局
通过基础的 24 分栏,迅速简便地创建布局。
用于< el-header>
<el-row><el-col :span="4" -- 【栅格占据的列数】> </el-col><el-col :span="16"></el-col><el-col :span="4"></el-col>
</el-row>
因此登录页面的【登录】【重置】按钮应使用layout布局
<el-row
justify="center" -- 【flex 布局下的水平排列方式】
type="flex" -- 【布局模式,可选 flex,现代浏览器下有效】
><el-button type="primary" class="login-btn" @click="handleLogin('formdata')" >登录</el-button><el-button @click="resetForm('formdata')" type="info" class="login-btn" >重置</el-button>
</el-row>
2.3 < el-menu>导航菜单-侧栏
- 导航菜单默认为垂直模式,通过mode属性可以使导航菜单变更为水平模式。另外,在菜单中通过submenu组件可以生成二级菜单。Menu 还提供了background-color、text-color和active-text-color,分别用于设置菜单的背景色、菜单的文字颜色和当前激活菜单的文字颜色。
- 通过el-menu-item-group组件可以实现菜单进行分组,分组名可以通过title属性直接设定,也可以通过具名 slot 来设定。-- 在项目中未用到,因为菜单是动态生成而非一一列举的,
<el-aside class="aside" width="200px"><el-col :span="24"><el-menudefault-active="2" -- 【当前激活菜单的 index】class="el-menu-vertical-demo"@open="handleOpen"@close="handleClose"background-color="teal"text-color="#fff"active-text-color="#ffff33":unique-opened= true -- 【是否只保持一个子菜单的展开】:router= true -- 【是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转】><el-submenu -- 【启用二级菜单】:index="item1.order.toString()" -- 【渲染一级菜单,index1~5】v-for="(item1,i) in menus" :key="item1.id"><template slot="title"> -- 【↖一级菜单】<i :class="iconlist[i]"></i><span>{{item1.authName}}</span></template><el-menu-item -- 【二级菜单】:index="item2.path" v-for="item2 in item1.children" :key="item2.id"><i class="el-icon-menu"></i><span>{{item2.authName}}</span></el-menu-item></el-submenu></el-menu></el-col>
</el-aside>
2.4< el-main>
<el-main class="main"><router-view></router-view>
</el-main>
2.5 < el-card>
将信息聚合在卡片容器中展示。
3. < el-main>–users/goods 用户/商品列表页面
3.1 面包屑
为了可复用,自定义组件 src/components/cuscom/myBread.vue
通过Prop向子组件传递数据
Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据。必须使用特定的方法才能实现组件之间的数据传递。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行.当然对 props 传递的参数应该添加一些验证规则;当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。
子组件:
<template><!-- 面包屑 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>{{level1}}</el-breadcrumb-item><el-breadcrumb-item>{{level2}}</el-breadcrumb-item></el-breadcrumb>
</template>
<script>
export default {props: ['level1', 'level2'],name: 'my-bread'
}
</script>
父组件:
<my-bread level1="商品管理" level2="商品列表"></my-bread>
3.2 搜索框
< el-input>
3.3 < el-table>列表
<el-table
:data="userlist"
height="450"
border style="width: 100%;margin-top: 15px"
><el-table-column type="index" -- 【对应列的类型。如果设置了 selection 则显示多选框;如果设置了 index 则显示该行的索引(从 1 开始计算);如果设置了 expand 则显示为一个可展开的按钮】prop="id" -- 【对应列内容的字段名,表格使用在于数据配置】label="序号"width="50"></el-table-column><el-table-column prop="userlist" label="创建日期"><template slot-scope="userlist">{{userlist.row.create_time | fmtdate}}</template></el-table-column>
</el-table>
3.3.1 el-switch状态开关
<el-switch v-model="userlist.row.mg_state" active-color="#13ce66" inactive-color="#ff4949" @change="changeState(userlist.row)">
</el-switch>
3.3.2 按钮el-button中使用icon
使用type、plain、round和circle属性来定义 Button 的样式。
<el-buttontype="danger"icon="el-icon-delete"size="small"circle @click="delUser(userlist.row.id)"></el-button>
3.3.3 表格 - 展开行
通过设置 type=“expand” 和 Scoped slot 可以开启展开行功能,el-table-column 的模板会被渲染成为展开行的内容,展开行可访问的属性与使用自定义列模板时的 Scoped slot 相同。
角色列表展开效果:
!注意以下几个el-table-column都是并列关系,展开内容就像是新增一列,但是现实效果展开后表头的下方。
<el-table :data="roleList" height="450" border style="width: 100%;margin-top: 15px"><el-table-column type="expand" prop="roleList">... 这里面是要展开的内容...</el-table-column><el-table-column type="index" prop="id" label="序号" width="80"></el-table-column><el-table-column prop="roleName" label="角色名称" width="180"></el-table-column>
</el-table>
3.3.4 tag标签
这里比较难的是结构
<el-table-column type="expand" prop="roleList"><template slot-scope = "scope"><!-- 一级 一行两列 --><span v-if="scope.row.children.length===0">该角色无权限</span><el-row v-for="(item1,i) in scope.row.children" :key="i"><!-- 第一列中放一级标签 --><el-col :span="4"><!-- 可移除标签,这里展示一级标签,绑定取消权限方法 --><el-tag closable @close="delRight(item1.id,scope.row)">{{item1.authName}}</el-tag></el-col><el-col :span="20"><!-- 第二列也是一行两列 --><el-row v-for="(item2,index) in item1.children" :key="index"><!-- 第二行第一列中放二级标签 --><el-col :span="4"><el-tag type="success" closable @close="delRight(item2.id,scope.row)">{{item2.authName}}</el-tag></el-col><el-col :span="20"><el-tag @close="delRight(item3.id,scope.row)" closable type="warning" v-for="(item3,indexInner) in item2.children" :key="indexInner">{{item3.authName}}</el-tag></el-col></el-row></el-col></el-row></template>
</el-table-column>
3.3.5 表格流体高度(滚动条)
通过设置max-height属性为 Table 指定最大高度。此时若表格所需的高度大于最大高度,则会显示一个滚动条。
3.3.6 Tree树形控件
关键在于配置,和绑定请求到数据的属性名,善用组件提供的方法
node-key的值,是treelist这个数据来源中的该值的key名
:default-expanded-keys=“allRoleId” 不需要forEach获得所有id了,这一个属性就完成所有功能
check-strictly在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false
<el-tree
ref="mytree"
default-expand-all
:data="treelist"
show-checkbox
node-key="id"
:default-checked-keys="checklistArr"
:props="defaultProps">
</el-tree>
注意:
async confirmRole () {this.dialogFormVisibleRight = false// getCheckedKeys若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组// getHalfCheckedKeys若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组// 角色授权接口post roles/:roleId/rights请求体ridslet arr1 = this.$refs.mytree.getCheckedKeys()let arr2 = this.$refs.mytree.getHalfCheckedKeys()let arr = [...arr1, ...arr2]const res = await this.$http.post(`roles/${this.currentRoleId}/rights`, {rids: arr.join(',')})console.log('设置角色', res)this.getRoleList()
}
editRight (role) {this.dialogFormVisibleRight = truethis.checklist = role.childrenthis.currentRoleId = role.id// 这里只展示现有的功能this.getRightsList()// 将所有权限的id赋值给数组allRoleId// console.log('role', role)// console.log('checklist:', this.checklist)// 问题:发现这里拿不到treelistvar tmpArr = []this.checklist.forEach(item1 => {// tmpArr.push(item1.id)var item2 = item1.childrenitem2.forEach(item2 => {// tmpArr.push(item2.id)var item3 = item2.childrenitem3.forEach(item3 => {tmpArr.push(item3.id)})})})this.checklistArr = tmpArr
},
3.4 < el-pagination>分页
<el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryinfo.pagenum":page-sizes="[2, 5, 10, 15]":page-size="queryinfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total">
</el-pagination>
4.商品管理
4.1 params分类参数
4.1.1 Alert 警告
<el-alerttitle="只允许为第三级分类设置参数"type="error">
</el-alert>
4.1.2 Cascader级联选择器
4.1.3 Tabs 标签页
<el-form ref="form" label-width="80px" ><el-form-item label="商品名称"> -- 【有form就有form-item】<el-cascader:show-all-levels="false"clearablev-model="value":options="options":props="{expandTrigger: 'hover', label: 'cat_name',value: 'cat_id',children: 'children'}"@change="handleChange"></el-cascader><el-tabs v-model="active" @tab-click="tabsHandleClick"><el-tab-pane label="动态参数" name="1"></el-tab-pane><el-tab-pane label="静态参数" name="2"></el-tab-pane></el-tabs></el-form-item>
</el-form>
4.2 categories商品分类 - tree-grid树形结构
tree-grid 和table-column一样使用
treeGrid
1.安装包
2.
<script>
// 引入tree-grid
var ElTreeGrid = require('element-tree-grid')
export default {// 局部注册 组件名<el-tree-grid>components: {ElTreeGrid}
</script>
3.
<el-table
:data="options"
border
style="width: 100%"><el-tree-gridtreeKey="cat_id"parentKey="cat_pid"levelKey="cat_level"childKey="children"prop="cat_name"label="分类名称"width="350"></el-tree-grid><el-table-columnprop="cat_deleted"label="是否有效"></el-table-column>
</el-table>
4.3 添加商品
4.3.1 步骤条
<!-- 步骤条 样式改变取决于属性active--><el-steps :active="parseInt(active)-1" finish-status="success" simple style="margin-top: 20px"><el-step title="基本信息" ></el-step><el-step title="商品参数" ></el-step><el-step title="商品属性" ></el-step><el-step title="商品图片" ></el-step><el-step title="商品内容" ></el-step></el-steps>
4.3.2 纵向tabs标签页
<!-- 纵向tabs标签页 样式改变取决于属性name/activeName--><!-- 最外层要用form包裹 --><el-form ref="form" :model="form" label-width="80px"><el-tabs tab-position="left" style="height:500px;margin-top: 20px;margin-bottom: 30px; overflow: scroll;"v-model="active" @tab-click="handleClick" ><el-tab-pane label="基本信息" name="1"><el-form-item label="商品名称"><el-input v-model="form.goods_name"></el-input></el-form-item> </el-tab-pane><el-tab-pane label="商品参数" name="2"><!-- 商品参数 显示动态信息 checkbox多选框组 checkbox-group元素能把多个 checkbox 管理为一组,只需要在 Group 中使用v-model绑定Array类型的变量即可。--></el-tab-pane><!-- 上传图片 upload组件 --><el-tab-pane label="商品图片" name="4"><el-form-item label-width="auto"><el-uploadaction="http://47.105.184.7:8888/api/private/v1/upload":headers="header":on-preview="handlePreview":on-remove="handleRemove":on-success="handleSuccess":file-list="fileList"list-type="picture"><el-button size="small" type="primary">点击上传</el-button><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div></el-upload></el-form-item></el-tab-pane><el-tab-pane label="商品内容" name="5"><el-form-item label-width="auto"><el-button type="primary" size="small" @click="addGoods">添加商品</el-button><!-- 富文本编辑器 vue-quill-editor --><quill-editor v-model="form.goods_introduce"></quill-editor></el-form-item></el-tab-pane></el-tabs></el-form>
4.3.3 el-upload上传图片
<el-tab-pane label="商品图片" name="4"><el-form-item label-width="auto"><el-uploadaction="http://47.105.184.7:8888/api/private/v1/upload":headers="header":on-preview="handlePreview":on-remove="handleRemove":on-success="handleSuccess":file-list="fileList"list-type="picture"><el-button size="small" type="primary">点击上传</el-button><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div></el-upload></el-form-item>
</el-tab-pane>
5.Dialog 对话框 - 弹框
<el-dialogtitle="提示":visible.sync="dialogVisible"width="30%":before-close="handleClose"><span>这是一段信息</span><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span>
</el-dialog>
6.导入
6.1 自定义组件 - 面包屑
myBread.vue
<template><!-- 面包屑 --><el-breadcrumb separator-class="el-icon-arrow-right" class="mybreadcrumb"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>{{level1}}</el-breadcrumb-item><el-breadcrumb-item>{{level2}}</el-breadcrumb-item></el-breadcrumb>
</template>
<script>
export default {props: ['level1', 'level2'],name: 'my-bread'
}
</script>
<style scoped>
.mybreadcrumb {margin-bottom: 15px;
}
</style>
main.js
import myBread from '@/components/cuscom/myBread.vue'
Vue.component(myBread.name, myBread)
6.2 富文本编辑器
npm上搜 vue-quill-editor
npm install vue-quill-editor --save
html:
<quill-editor v-model="form.goods_introduce"></quill-editor>
js:(按需)局部注册组件
mount with component
// require styles
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'import { quillEditor } from 'vue-quill-editor'export default {components: {quillEditor}
}
6.3 非element-UI的树形结构
npm搜索element-tree-grid
npm install element-tree-grid --save
html:
适用于< el-table>,可以直接像< el-table-column>一样使用
<el-tree-gridtreeKey="cat_id"parentKey="cat_pid"levelKey="cat_level"childKey="children"prop="cat_name"label="分类名称"width="350"
>
</el-tree-grid>
js:
var ElTreeGrid = require('element-tree-grid')
export default {// 局部注册 组件名<el-tree-grid>components: {ElTreeGrid}
}
6.4 城市数据
html:
<el-cascader
:options="citydata"
>
</el-cascader>
js:
import cityData from '@/assets/city_data2017_element.js'
export default {data () {return {citydata: []}}
6.5 数据报表echarts
echarts文档
6.5.1 安装
npm install echarts --save
6.5.2 引入 ECharts
html:
<!-- 为echart准备一个div容器 -->
<div id="main" style="width: 600px;height:400px;"></div>
js:
var echarts = require('echarts')
export default {data () {return {}},methods: {async useEchart () {// initvar myChart = echarts.init(document.getElementById('main'))const res = await this.$http.get(`reports/type/1`)// legend:// data: (5) ["华东", "华南", "华北", "西部", "其他"]// __proto__: Object// series: (5) [{…}, {…}, {…}, {…}, {…}]// xAxis: [{…}]// yAxis: [{…}]let option1 = {title: {text: '用户来源'},tooltip: {trigger: 'axis',axisPointer: {type: 'cross',label: {backgroundColor: '#E9EEF3'}}},toolbox: {feature: {saveAsImage: {}}},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true}}console.log('数据报表', res)let option2 = res.data.datalet option = {...option1, ...option2}console.log(option)// setOptionmyChart.setOption(option)}},mounted () {// 这里操作元素this.useEchart()}
}