mirror of
http://112.124.100.131/happyinsurance_eco/ebiz-sunful-eco-web.git
synced 2025-12-07 01:46:51 +08:00
refactor: 重构项目结构并删除未使用的组件和代码
- 删除了多个未使用的组件,包括 Breadcrumb、Hamburger、mavonEditor 等 -移除了未使用的 vuex store模块和 getters - 删除了未使用的 API 接口定义- 简化了 Navbar组件的结构 - 移除了全局的 resize 事件监听
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
"babel-eslint": "10.0.1",
|
||||
"babel-jest": "23.6.0",
|
||||
"chalk": "2.4.2",
|
||||
"compression-webpack-plugin": "^8.0.1",
|
||||
"connect": "3.6.6",
|
||||
"eslint": "5.15.3",
|
||||
"eslint-plugin-vue": "5.2.2",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import request from '@/assets/js/utils/request'
|
||||
import getUrl from '@/assets/js/utils/get-url'
|
||||
|
||||
// 登录
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: getUrl('/user/login', 0),
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取个人信息
|
||||
export function getInfo(token) {
|
||||
return request({
|
||||
url: getUrl('/user/info', 0),
|
||||
method: 'get',
|
||||
params: { token }
|
||||
})
|
||||
}
|
||||
|
||||
// 登出
|
||||
export function logout() {
|
||||
return request({
|
||||
url: getUrl('/user/logout', 0),
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
// 测试示例
|
||||
export function indexUser() {
|
||||
return request({
|
||||
url: getUrl('/index/user', 0),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import router from '@/router'
|
||||
import store from '@/store'
|
||||
import NProgress from 'nprogress' // progress bar
|
||||
import 'nprogress/nprogress.css' // progress bar style
|
||||
import { getToken } from '@/assets/js/utils/auth' // get token from cookie
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator-class="el-icon-arrow-right">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
|
||||
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect fs16">{{ item.meta.title }}</span>
|
||||
<span v-else>{{ item.meta.title }}</span>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
levelList: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb() {
|
||||
// only show routes with meta.title
|
||||
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||
// const first = matched[0]
|
||||
|
||||
// if (!this.isDashboard(first)) {
|
||||
// matched = [{ path: '/dashboard', meta: { title: 'Dashboard' } }].concat(matched)
|
||||
// }
|
||||
|
||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
},
|
||||
isDashboard(route) {
|
||||
const name = route && route.name
|
||||
if (!name) {
|
||||
return false
|
||||
}
|
||||
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
|
||||
},
|
||||
pathCompile(path) {
|
||||
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||
const { params } = this.$route
|
||||
var toPath = pathToRegexp.compile(path)
|
||||
return toPath(params)
|
||||
},
|
||||
handleLink(item) {
|
||||
const { redirect, path } = item
|
||||
if (redirect) {
|
||||
this.$router.push(redirect)
|
||||
return
|
||||
}
|
||||
this.$router.push(this.pathCompile(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
margin-left: 8px;
|
||||
|
||||
.no-redirect {
|
||||
color: #97a8be;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,39 +0,0 @@
|
||||
<template>
|
||||
<div style="padding: 0 15px;" @click="toggleClick">
|
||||
<svg :class="{ 'is-active': isActive }" class="hamburger" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64">
|
||||
<path
|
||||
d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Hamburger',
|
||||
props: {
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleClick() {
|
||||
this.$emit('toggleClick')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hamburger {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
||||
@@ -1,79 +0,0 @@
|
||||
<template>
|
||||
<div class="mavonEditor-index-container">
|
||||
<!-- 可视化富文本编辑器 书写代码-->
|
||||
<mavonEditor :defaultOpen="defaultOpen" ref="mavonEditor" :toolbarsFla="false" v-model="content" :toolbars="toolbars" :ishljs="true"></mavonEditor>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mavonEditor } from 'mavon-editor'
|
||||
import 'mavon-editor/dist/css/index.css'
|
||||
export default {
|
||||
name: 'mavonEditor-index',
|
||||
components: { mavonEditor },
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
},
|
||||
defaultOpen: {
|
||||
type: String,
|
||||
default: 'edit'
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'event1'
|
||||
},
|
||||
watch: {
|
||||
value(o) {
|
||||
this.content = o
|
||||
},
|
||||
content(o) {
|
||||
this.$emit('event1', o)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: '',
|
||||
toolbars: {
|
||||
bold: true, // 粗体
|
||||
italic: true, // 斜体
|
||||
header: true, // 标题
|
||||
underline: true, // 下划线
|
||||
strikethrough: true, // 中划线
|
||||
mark: true, // 标记
|
||||
superscript: true, // 上角标
|
||||
subscript: true, // 下角标
|
||||
quote: true, // 引用
|
||||
ol: true, // 有序列表
|
||||
ul: true, // 无序列表
|
||||
link: true, // 链接
|
||||
imagelink: true, // 图片链接
|
||||
code: true, // code
|
||||
table: true, // 表格
|
||||
fullscreen: true, // 全屏编辑
|
||||
readmodel: true, // 沉浸式阅读
|
||||
htmlcode: true, // 展示html源码
|
||||
help: true, // 帮助
|
||||
/* 1.3.5 */
|
||||
undo: true, // 上一步
|
||||
redo: true, // 下一步
|
||||
trash: true, // 清空
|
||||
save: true, // 保存(触发events中的save事件)
|
||||
/* 1.4.2 */
|
||||
navigation: true, // 导航目录
|
||||
/* 2.1.8 */
|
||||
alignleft: true, // 左对齐
|
||||
aligncenter: true, // 居中
|
||||
alignright: true, // 右对齐
|
||||
/* 2.2.1 */
|
||||
subfield: true, // 单双栏模式
|
||||
preview: true // 预览
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -1,127 +0,0 @@
|
||||
<template>
|
||||
<div class="render-swiper-container" style="height: 480px">
|
||||
<div class="swiper-container" ref="swiper" style="height: 500px">
|
||||
<div class="swiper-wrapper" style="height: 480px">
|
||||
<div v-for="item in 8" class="swiper-slide" style="height: 100%">
|
||||
<div style="position: relative" class="swp">
|
||||
<img src="../../assets/images/pages/img.png" alt="" style="width: 100px" class="mv10" />
|
||||
<div class="text-left ph20 fs14" style="line-height: 25px">
|
||||
<p>服务定位:为90%选择居家养老的老人提供高品质生活服务。</p>
|
||||
<p class="mt10">项目介绍:</p>
|
||||
<p class="mb10">106项深度保洁:全屋分10区细化清洁标准(如厨房高温消毒、卫生间防霉处理),解决服务非标化痛点</p>
|
||||
<div class="btn-btn">
|
||||
<div style="position: absolute;z-index: 1;width: 100%;">
|
||||
<div class="btn-btn-dashad"></div>
|
||||
<img src="../../assets/images/pages/btn.png" alt="" />
|
||||
</div>
|
||||
<div style="position: absolute;z-index: 2">
|
||||
<p class="mb10">医养管家套餐:联合平安家庭医生,提供用药提醒,慢病监测及三甲医院绿色通道转诊服务。</p>
|
||||
<p class="mb10">适老改造+智能监护:安装智能防跌检测设备,降低居家风险30%</p>
|
||||
<p class="mb20">创新点:直营团队+260项SOP流程,政府合作覆盖特困老人,满意度达98.6%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="swiper-pagination" v-if="showPagination"></div>
|
||||
<div class="swiper-button-next" v-if="showNextBtb"></div>
|
||||
<div class="swiper-button-prev" v-if="showNextBtb"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Swiper from 'swiper'
|
||||
import 'swiper/css/swiper.min.css'
|
||||
export default {
|
||||
name: 'render-swiper',
|
||||
data() {
|
||||
return {
|
||||
swiper: '',
|
||||
defaultOptions: {
|
||||
effect: 'coverflow',
|
||||
slidesPerView: 3,
|
||||
centeredSlides: true,
|
||||
initialSlide: 0, //初始展示索引
|
||||
direction: 'horizontal', //水平/垂直展示
|
||||
speed: 300, //切换速度
|
||||
grabCursor: false, //拖动时显示手势 鼠标覆盖Swiper 时指针会变成手掌形状,拖动时指针会变成抓手形状
|
||||
watchSlidesProgress: true, // 子元素的活动进程
|
||||
setWrapperSize: false, // Swiper使用flexbox布局(display: flex),开启这个设定会在Wrapper上添加等于slides相加的宽或高,在对flexbox布局的支持不是很好的浏览器中可能需要用到。
|
||||
virtualTranslate: false, // 滑动锁定
|
||||
width: undefined, //宽度
|
||||
height: undefined, //高度
|
||||
breakpoints: '', //响应式设置
|
||||
autoHeight: false, //自动高度。设置为 true 时,wrapper 和container 会随着当前slide 的高度而发生变化。
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 3000
|
||||
},
|
||||
// 切换效果
|
||||
coverflowEffect: {
|
||||
rotate: 0,
|
||||
stretch: -10,
|
||||
depth: 80,
|
||||
modifier: 4,
|
||||
slideShadows: false
|
||||
}
|
||||
// init: false
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
showPagination: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showNextBtb: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
components: {},
|
||||
filters: {},
|
||||
methods: {},
|
||||
created() {
|
||||
let newOptions = Object.assign({}, this.defaultOptions, this.options)
|
||||
this.$nextTick(() => {
|
||||
newOptions.loopAdditionalSlides = newOptions.loopAdditionalSlides ? newOptions.loopAdditionalSlides : 3
|
||||
this.swiper = new Swiper(this.$refs.swiper, newOptions)
|
||||
})
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.swp {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
.btn-btn {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 500px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.btn-btn-dashad {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -5%;
|
||||
width: 110%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'index',
|
||||
props: ['scope', 'item'],
|
||||
render() {
|
||||
let { scope, item } = this
|
||||
return scope.row[item.prop] ? (
|
||||
<div class="toolBox">
|
||||
<el-tooltip content={scope.row[item.prop] && scope.row[item.prop] != '' ? scope.row[item.prop] : '2'} placement="right" effect="dark">
|
||||
<div class="ellipsis">{scope.row[item.prop]}</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
) : (
|
||||
<div class="ellipsis">{scope.row[item.prop]}</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolBox {
|
||||
display: inline-grid;
|
||||
}
|
||||
</style>
|
||||
@@ -1,37 +0,0 @@
|
||||
<script>
|
||||
// 自定义内容的组件 实现element 自带render函数
|
||||
const RenderSlot = {
|
||||
functional: true,
|
||||
props: {
|
||||
row: Object,
|
||||
render: Function,
|
||||
index: Number,
|
||||
column: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
render: (h, data) => {
|
||||
const params = {
|
||||
row: data.props.row,
|
||||
index: data.props.index
|
||||
}
|
||||
if (data.props.column) params.column = data.props.column
|
||||
return data.props.render(h, params)
|
||||
}
|
||||
}
|
||||
export default {
|
||||
name: 'FormSlot',
|
||||
props: ['item', 'scope'],
|
||||
components: { RenderSlot },
|
||||
render() {
|
||||
let { item, scope } = this
|
||||
return (
|
||||
// <el-form-item prop={`"${item.ruleName}"`} rules={item.rules}>
|
||||
<render-slot row={scope.row} render={item.render} index={scope.$index} column={item} />
|
||||
// </el-form-item>
|
||||
// </el-form>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,31 +0,0 @@
|
||||
<script>
|
||||
// 自定义内容的组件 实现element 自带render函数
|
||||
const RenderSlot = {
|
||||
functional: true,
|
||||
props: {
|
||||
row: Object,
|
||||
render: Function,
|
||||
index: Number,
|
||||
column: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
render: (h, data) => {
|
||||
const params = {
|
||||
index: data.props.index
|
||||
}
|
||||
if (data.props.column) params.column = data.props.column
|
||||
return data.props.render(h, params)
|
||||
}
|
||||
}
|
||||
export default {
|
||||
name: 'headerSlot',
|
||||
props: ['item', 'scope'],
|
||||
components: { RenderSlot },
|
||||
render() {
|
||||
let { item, scope } = this
|
||||
return <render-slot render={item.headRender} index={scope.$index} column={item} />
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,369 +0,0 @@
|
||||
<template>
|
||||
<div id="RenderTable-container">
|
||||
<el-form :model="model" ref="model">
|
||||
<el-table
|
||||
:class="drag ? 'dragTable' : ''"
|
||||
:data="model.data"
|
||||
row-key="id"
|
||||
lazy
|
||||
@sort-change="sortChange"
|
||||
ref="renderTable"
|
||||
:border="border"
|
||||
stripe
|
||||
:header-align="align"
|
||||
size="small"
|
||||
default-expand-all
|
||||
:max-height="maxHeight || null"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
:tree-props="{ children: 'childList' }"
|
||||
>
|
||||
<template v-for="(item, index) in columns">
|
||||
<!--没有type 的模板-->
|
||||
<el-table-column
|
||||
:align="item.align"
|
||||
:row-key="item.id"
|
||||
:label="item.key"
|
||||
:type="item.type"
|
||||
:sortable="item.sortable"
|
||||
:key="index"
|
||||
:min-width="item.width ? item.width : 225"
|
||||
:fixed="item.fixed"
|
||||
v-if="!item.type"
|
||||
>
|
||||
<template #header="scope" v-if="item.headRender">
|
||||
<header-slot :item="item" :scope="scope" />
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<!--表单校验-->
|
||||
<el-form-item v-if="item.ruleCode" :prop="'data.' + scope.$index + '.' + item.ruleCode" :rules="item.ruleCode ? item.rules : []">
|
||||
<body-slot :item="item" :scope="scope" v-if="item.render" />
|
||||
</el-form-item>
|
||||
<body-slot :item="item" :scope="scope" v-if="!item.ruleCode && item.render" />
|
||||
<!--自定义render模板-->
|
||||
<!--</el-form>-->
|
||||
<!--自带的btn 不能有prop 属性-->
|
||||
<div v-if="!item.selfBtn && !item.prop && !item.type && !item.render" :fixed="item.fixed ? item.fixed : fixed">
|
||||
<el-button type="primary" size="mini" plain :disabled="disabled" @click="edit(scope.row, scope.$index)">编辑</el-button>
|
||||
<el-button type="danger" size="mini" plain :disabled="disabled" @click="del(scope.row, scope.$index)">删除</el-button>
|
||||
</div>
|
||||
<!--如果渲染的是selfBtn-->
|
||||
<div v-if="item.selfBtn && !item.render">
|
||||
<el-button
|
||||
v-for="(btn, btnIndex) in item.selfBtn"
|
||||
:fixed="item.fixed ? item.fixed : fixed"
|
||||
:disabled="item.disabled !== undefined ? item.disabled : disabled"
|
||||
:type="btn.type ? btn.type : 'primary'"
|
||||
:size="btn.size ? btn.size : 'mini'"
|
||||
:key="btnIndex"
|
||||
@click="handlerMethods(scope.row, scope.$index, btn)"
|
||||
:label="btn.name"
|
||||
>
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
</div>
|
||||
<!--提示框 内部判断是否给单元格提示-->
|
||||
<TooltipScope :scope="scope" :item="item" v-if="!item.type && !item.render && item.prop" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!--有设置type 的表格 type 设置的是selection 和 index-->
|
||||
<el-table-column
|
||||
:key="index"
|
||||
:row-key="item.id"
|
||||
:align="align"
|
||||
:label="item.key"
|
||||
:type="item.type"
|
||||
:width="item.width"
|
||||
v-else-if="item.type === 'index' || item.type === 'selection'"
|
||||
/>
|
||||
<el-table-column
|
||||
:key="index"
|
||||
:row-key="item.id"
|
||||
:align="align"
|
||||
:label="item.key"
|
||||
:type="item.type"
|
||||
:width="item.width"
|
||||
v-else-if="item.type === 'radio'"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-radio v-model="check" :label="scope.$index" @change="setCheck($event, scope)">{{ null }}</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<!--自定义默认按钮 ps:增加 一行 删除一行-->
|
||||
<el-table-column v-if="deletion" :align="align" width="180" :fixed="fixed">
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="
|
||||
e => {
|
||||
addRow(scope.row, scope.$index)
|
||||
}
|
||||
"
|
||||
:disabled="disabled"
|
||||
circle
|
||||
icon="el-icon-plus"
|
||||
size="medium"
|
||||
class="tableBtn"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
@click="
|
||||
e => {
|
||||
delRow(scope.row, scope.$index)
|
||||
}
|
||||
"
|
||||
:disabled="disabled"
|
||||
circle
|
||||
size="medium"
|
||||
icon="el-icon-minus"
|
||||
class="tableBtn"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form>
|
||||
<!--表格分页-->
|
||||
<div class="text-right" v-if="total">
|
||||
<el-pagination
|
||||
class="table-container"
|
||||
@size-change="sizeChange"
|
||||
@current-change="currentChange"
|
||||
background
|
||||
:currentPage="currentPage"
|
||||
layout="prev,sizes, pager, next,jumper"
|
||||
:page-sizes="[10, 20, 30, 40, 50]"
|
||||
:total="total"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sortable from 'sortablejs'
|
||||
import TooltipScope from './component/TooltipScope'
|
||||
import bodySlot from './component/bodySlot'
|
||||
import HeaderSlot from './component/headerSlot'
|
||||
/* * @Author: 陈昱达 * @Date: 2020-08-27 17:40:39 * @Last Modified by: 陈昱达 * @Last Modified time: 2020-08-27 17:40:39 */
|
||||
export default {
|
||||
name: 'RenderTable',
|
||||
data() {
|
||||
return {
|
||||
fixed: 'right',
|
||||
check: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
model(v) {
|
||||
return {
|
||||
data: v.data
|
||||
}
|
||||
}
|
||||
},
|
||||
components: { HeaderSlot, TooltipScope, bodySlot },
|
||||
props: {
|
||||
//是否拖拽
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//是否展示 删减行 按钮 和新增行按钮
|
||||
deletion: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//页码
|
||||
currentPage: {
|
||||
type: Number
|
||||
},
|
||||
//是否禁用表格自带按钮
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
//表格边框 border
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否剧中 align
|
||||
align: {
|
||||
type: String,
|
||||
default: 'center'
|
||||
},
|
||||
// table data
|
||||
data: {
|
||||
type: Array
|
||||
},
|
||||
//columns
|
||||
columns: {
|
||||
type: Array
|
||||
},
|
||||
//total
|
||||
total: {
|
||||
type: Number
|
||||
},
|
||||
maxHeight: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.drag) {
|
||||
this.rowDrop()
|
||||
// this.columnDrop()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 单选选中
|
||||
setCheck(e, scope) {
|
||||
this.check = e
|
||||
this.$emit('selectRow', { row: scope.row, index: scope.$index })
|
||||
this.$emit('select-row', { row: scope.row, index: scope.$index })
|
||||
},
|
||||
sortChange(sortData) {
|
||||
let filters = this.columns.filter(item => item.key === sortData.column.label)
|
||||
if (filters && filters.length > 0) {
|
||||
sortData.prop = filters[0].prop
|
||||
}
|
||||
this.$emit('sortChange', sortData)
|
||||
this.$emit('sort-change', sortData)
|
||||
},
|
||||
//行拖拽
|
||||
rowDrop() {
|
||||
const tbody = document.querySelector('.dragTable .el-table__body-wrapper tbody')
|
||||
Sortable.create(tbody, {
|
||||
animation: 180,
|
||||
onEnd: ({ newIndex, oldIndex }) => {
|
||||
const currRow = this.data.splice(oldIndex, 1)[0]
|
||||
this.data.splice(newIndex, 0, currRow)
|
||||
}
|
||||
})
|
||||
},
|
||||
//列拖拽 目前有问题 暂未解决
|
||||
columnDrop() {
|
||||
const wrapperTr = document.querySelector('.dragTable .el-table__header-wrapper tr')
|
||||
Sortable.create(wrapperTr, {
|
||||
animation: 180,
|
||||
filter: '.el-table-column--selection',
|
||||
delay: 0,
|
||||
onEnd: evt => {
|
||||
const oldItem = this.columns[evt.oldIndex]
|
||||
this.columns.splice(evt.oldIndex, 1)
|
||||
this.columns.splice(evt.newIndex, 0, oldItem)
|
||||
}
|
||||
})
|
||||
},
|
||||
//edit in table
|
||||
edit(row, index) {
|
||||
this.$emit('edit', row, index)
|
||||
},
|
||||
// del In Table
|
||||
del(row, index) {
|
||||
this.$emit('del', row, index)
|
||||
},
|
||||
//展示条数改变
|
||||
sizeChange(size) {
|
||||
this.$emit('sizeChange', size)
|
||||
this.$emit('size-change', size)
|
||||
},
|
||||
//页码改变
|
||||
currentChange(current) {
|
||||
this.$emit('currentChange', current)
|
||||
this.$emit('current-change', current)
|
||||
},
|
||||
//根据数据的格式去返回对应的数据结构
|
||||
getDataType(type) {
|
||||
let dataType = ''
|
||||
if (type === '[object Array]') {
|
||||
dataType = []
|
||||
} else if (type === '[object Object]') {
|
||||
dataType = {}
|
||||
}
|
||||
return dataType
|
||||
},
|
||||
//Add a new line
|
||||
addRow(row, index) {
|
||||
let newRow = JSON.parse(JSON.stringify(row))
|
||||
for (let item in newRow) {
|
||||
newRow[item] = this.getDataType(Object.prototype.toString.call(newRow[item]))
|
||||
}
|
||||
this.data.splice(index + 1, 0, newRow)
|
||||
this.$emit('buttonAdd', row, newRow)
|
||||
this.$emit('button-add', row, newRow)
|
||||
},
|
||||
//Delete row
|
||||
delRow(row, index) {
|
||||
this.$emit('buttonDel', row, index)
|
||||
this.$emit('button-del', row, index)
|
||||
let newRow = JSON.parse(JSON.stringify(row))
|
||||
this.data.splice(index, 1)
|
||||
if (this.data.length === 0) {
|
||||
for (let item in newRow) {
|
||||
newRow[item] = this.getDataType(Object.prototype.toString.call(newRow[item]))
|
||||
}
|
||||
this.data.push(newRow)
|
||||
}
|
||||
},
|
||||
//btnSelf 把当前数据提交给父组件自定义method事件中
|
||||
handlerMethods(row, index, btn) {
|
||||
this.$emit(btn.method, { row, index })
|
||||
},
|
||||
|
||||
handleRowClick(row, column, event) {
|
||||
this.$emit('row-click', row, column, event)
|
||||
},
|
||||
handleSelectionChange(row) {
|
||||
this.$emit('selection-change', row)
|
||||
},
|
||||
//具体查看element 文档
|
||||
toggleRowSelection(rows) {
|
||||
this.$nextTick(() => {
|
||||
if (rows) {
|
||||
rows.forEach(row => {
|
||||
this.$refs.renderTable.toggleRowSelection(row)
|
||||
})
|
||||
} else {
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
}
|
||||
})
|
||||
},
|
||||
clearSelection() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.renderTable.clearSelection()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pd5 {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.tableBtn {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/deep/.el-table {
|
||||
.el-radio__label {
|
||||
padding: unset;
|
||||
}
|
||||
.el-form-item__error {
|
||||
position: unset;
|
||||
}
|
||||
.el-form-item__content {
|
||||
line-height: unset;
|
||||
}
|
||||
.el-form-item__error {
|
||||
position: unset;
|
||||
}
|
||||
.el-form-item {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<div id="vueEditor-container">
|
||||
<!--富文本编辑器-->
|
||||
<VueEditor v-model="content" :editorToolbar="editorToolbar" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { VueEditor } from 'vue2-editor'
|
||||
export default {
|
||||
name: 'vueEditor',
|
||||
components: { VueEditor },
|
||||
props: {
|
||||
value: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'event1'
|
||||
},
|
||||
watch: {
|
||||
value(o, v) {
|
||||
this.content = o
|
||||
},
|
||||
content(o) {
|
||||
this.$emit('event1', o)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: this.value,
|
||||
editorToolbar: [
|
||||
[{ header: [false, 1, 2, 3, 4, 5, 6] }],
|
||||
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
||||
[{ align: ['', 'center', 'right', 'justify'] }],
|
||||
['blockquote'],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
|
||||
[{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
||||
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
|
||||
['clean','link', 'image']
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleImageAdded(file, Editor, cursorLocation, resetUploader) {
|
||||
let formData = new FormData()
|
||||
formData.append('file', file) //第一个file 后台接收的参数名
|
||||
uploadFileComponentForEditor(formData)
|
||||
.then(result => {
|
||||
let url = result.content.fileUrl // 返回给你的图片路径
|
||||
Editor.insertEmbed(cursorLocation, 'image', url)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
1
src/icons/svg/search.svg
Normal file
1
src/icons/svg/search.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1751627459592" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2770" width="20" height="20"><path d="M473.142857 54.514286c-231.2 0-418.742857 187.428571-418.742857 418.742857 0 231.2 187.428571 418.742857 418.742857 418.742857 102.742857 0 196.8-37.028571 269.6-98.285714L918.171429 969.142857l50.514285-50.514286-175.428571-175.657142c61.485714-72.914286 98.514286-167.085714 98.514286-269.828572 0.114286-231.2-187.428571-418.628571-418.628572-418.628571z m0 765.828571c-46.857143 0-92.342857-9.142857-135.085714-27.2-41.371429-17.485714-78.514286-42.514286-110.4-74.4-31.885714-31.885714-56.914286-69.028571-74.4-110.4-18.057143-42.742857-27.2-88.228571-27.2-135.085714s9.142857-92.342857 27.2-135.085714c17.485714-41.371429 42.514286-78.514286 74.4-110.4 31.885714-31.885714 69.028571-56.914286 110.4-74.4 42.742857-18.057143 88.228571-27.2 135.085714-27.2s92.342857 9.142857 135.085714 27.2c41.371429 17.485714 78.514286 42.514286 110.4 74.4 31.885714 31.885714 56.914286 69.028571 74.4 110.4 18.057143 42.742857 27.2 88.228571 27.2 135.085714s-9.142857 92.342857-27.2 135.085714c-17.485714 41.371429-42.514286 78.514286-74.4 110.4s-69.028571 56.914286-110.4 74.4c-42.742857 18.057143-88.228571 27.2-135.085714 27.2z" fill="#ffffff" p-id="2771"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,12 +1,11 @@
|
||||
import Vue from 'vue'
|
||||
import 'normalize.css/normalize.css' // A modern alternative to CSS
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
import Filters from './filters'
|
||||
// import Filters from './filters'
|
||||
import generatedComponents from './generatedComponents'
|
||||
// 注册过滤器
|
||||
Object.keys(Filters).forEach(k => Vue.filter(k, Filters[k]))
|
||||
// Object.keys(Filters).forEach(k => Vue.filter(k, Filters[k]))
|
||||
for (let item in generatedComponents) {
|
||||
Vue.component(item, generatedComponents[item])
|
||||
}
|
||||
@@ -16,6 +15,5 @@ import '@/assets/js/utils/permission' // permission control
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
const getters = {
|
||||
sidebar: state => state.app.sidebar,
|
||||
device: state => state.app.device,
|
||||
token: state => state.user.token,
|
||||
avatar: state => state.user.avatar,
|
||||
name: state => state.user.name,
|
||||
sidebarList: state => state.user.sidebarList,
|
||||
}
|
||||
export default getters
|
||||
@@ -1,17 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import getters from './getters'
|
||||
import app from './modules/app'
|
||||
import settings from './modules/settings'
|
||||
import user from './modules/user'
|
||||
Vue.use(Vuex)
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
app,
|
||||
settings,
|
||||
user,
|
||||
},
|
||||
getters
|
||||
})
|
||||
|
||||
export default store
|
||||
@@ -1,55 +0,0 @@
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
const state = {
|
||||
sidebar: {
|
||||
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
|
||||
withoutAnimation: false
|
||||
},
|
||||
device: 'desktop',
|
||||
sidebarList: []
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
TOGGLE_SIDEBAR: state => {
|
||||
state.sidebar.opened = !state.sidebar.opened
|
||||
state.sidebar.withoutAnimation = false
|
||||
if (state.sidebar.opened) {
|
||||
Cookies.set('sidebarStatus', 1)
|
||||
} else {
|
||||
Cookies.set('sidebarStatus', 0)
|
||||
}
|
||||
},
|
||||
CLOSE_SIDEBAR: (state, withoutAnimation) => {
|
||||
Cookies.set('sidebarStatus', 0)
|
||||
state.sidebar.opened = false
|
||||
state.sidebar.withoutAnimation = withoutAnimation
|
||||
},
|
||||
TOGGLE_DEVICE: (state, device) => {
|
||||
state.device = device
|
||||
},
|
||||
SET_SIDEBAR_LIST: (state, sidebar) => {
|
||||
state.sidebarList = sidebar
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
toggleSideBar({ commit }) {
|
||||
commit('TOGGLE_SIDEBAR')
|
||||
},
|
||||
closeSideBar({ commit }, { withoutAnimation }) {
|
||||
commit('CLOSE_SIDEBAR', withoutAnimation)
|
||||
},
|
||||
toggleDevice({ commit }, device) {
|
||||
commit('TOGGLE_DEVICE', device)
|
||||
},
|
||||
setSidebarList({ commit }, sidebarList) {
|
||||
commit('SET_SIDEBAR_LIST', sidebarList)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import defaultSettings from '@/assets/js/utils/settings'
|
||||
|
||||
const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
|
||||
|
||||
const state = {
|
||||
showSettings: showSettings,
|
||||
fixedHeader: fixedHeader,
|
||||
sidebarLogo: sidebarLogo
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
CHANGE_SETTING: (state, { key, value }) => {
|
||||
console.log(state, {key, value},'23232');
|
||||
if (state.hasOwnProperty(key)) {
|
||||
state[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
changeSetting({ commit }, data) {
|
||||
commit('CHANGE_SETTING', data)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
import { login, logout, getInfo } from '@/api/app/user'
|
||||
import { getToken, setToken, removeToken } from '@/assets/js/utils/auth'
|
||||
|
||||
const state = {
|
||||
token: getToken(),
|
||||
name: '',
|
||||
avatar: ''
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
SET_TOKEN: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name
|
||||
},
|
||||
SET_AVATAR: (state, avatar) => {
|
||||
state.avatar = avatar
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
getSid({ commit }, data) {
|
||||
commit('SET_SID', data)
|
||||
},
|
||||
setGroupList({ commit }, data) {
|
||||
commit('SET_GROUPLIST', data)
|
||||
},
|
||||
setToken({ commit },data){
|
||||
commit('SET_TOKEN', data)
|
||||
},
|
||||
// user login
|
||||
login({ commit }, userInfo) {
|
||||
const { username, password } = userInfo
|
||||
return new Promise((resolve, reject) => {
|
||||
login({ username: username.trim(), password: password })
|
||||
.then(res => {
|
||||
commit('SET_TOKEN', res.token)
|
||||
setToken(res.token)
|
||||
resolve()
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// get user info
|
||||
getInfo({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo(state.token)
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
reject('Verification failed, please Login again.')
|
||||
}
|
||||
|
||||
commit('SET_NAME', res.name)
|
||||
commit('SET_AVATAR', res.avatar)
|
||||
resolve(res)
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// user logout
|
||||
logout({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token)
|
||||
.then(() => {
|
||||
commit('SET_TOKEN', '')
|
||||
removeToken()
|
||||
resolve()
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// remove token
|
||||
resetToken({ commit }) {
|
||||
return new Promise(resolve => {
|
||||
commit('SET_TOKEN', '')
|
||||
removeToken()
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
@@ -6,23 +6,17 @@
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<input type="text" class="nav-input" />
|
||||
<el-icon class="el-icon-search ml10 white" size="20px"></el-icon>
|
||||
<svg-icon icon-class="search" style="margin-left: 15px;cursor: pointer"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import Breadcrumb from '@/components/Breadcrumb'
|
||||
import Hamburger from '@/components/Hamburger'
|
||||
import url from '@/assets/images/active.png'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Breadcrumb,
|
||||
Hamburger
|
||||
},
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
keyIndex: 0,
|
||||
@@ -31,18 +25,8 @@ export default {
|
||||
ls: [{ name: '关于幸福' }, { name: '发展历程' }, { name: '荣誉资质' }, { name: '联系我们' }]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['sidebar', 'avatar'])
|
||||
},
|
||||
methods: {
|
||||
toggleSideBar() {
|
||||
this.$store.dispatch('app/toggleSideBar')
|
||||
},
|
||||
async logout() {
|
||||
await this.$store.dispatch('user/logout')
|
||||
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
|
||||
}
|
||||
}
|
||||
computed: {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { default as Navbar } from './Navbar'
|
||||
export { default as Sidebar } from './Sidebar'
|
||||
// export { default as Sidebar } from './Sidebar'
|
||||
export { default as AppMain } from './AppMain'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper">
|
||||
<div class="app-wrapper">
|
||||
<div class="app-wrapper-box">
|
||||
<!-- <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
|
||||
<sidebar class="sidebar-container" />
|
||||
@@ -14,14 +14,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Navbar, Sidebar, AppMain } from './components'
|
||||
import ResizeMixin from './mixin/ResizeHandler'
|
||||
import { AppMain } from './components'
|
||||
|
||||
export default {
|
||||
name: 'Layout',
|
||||
components: {
|
||||
Navbar,
|
||||
Sidebar,
|
||||
AppMain
|
||||
},
|
||||
data() {
|
||||
@@ -29,25 +26,25 @@ export default {
|
||||
type: process.env.VUE_APP_FLAG
|
||||
}
|
||||
},
|
||||
mixins: [ResizeMixin],
|
||||
// mixins: [ResizeMixin],
|
||||
computed: {
|
||||
sidebar() {
|
||||
return this.$store.state.app.sidebar
|
||||
},
|
||||
device() {
|
||||
return this.$store.state.app.device
|
||||
},
|
||||
fixedHeader() {
|
||||
return this.$store.state.settings.fixedHeader
|
||||
},
|
||||
classObj() {
|
||||
return {
|
||||
hideSidebar: !this.sidebar.opened,
|
||||
openSidebar: this.sidebar.opened,
|
||||
withoutAnimation: this.sidebar.withoutAnimation,
|
||||
mobile: this.device === 'mobile'
|
||||
}
|
||||
}
|
||||
// sidebar() {
|
||||
// return this.$store.state.app.sidebar
|
||||
// },
|
||||
// device() {
|
||||
// return this.$store.state.app.device
|
||||
// },
|
||||
// fixedHeader() {
|
||||
// return this.$store.state.settings.fixedHeader
|
||||
// },
|
||||
// classObj() {
|
||||
// return {
|
||||
// hideSidebar: !this.sidebar.opened,
|
||||
// openSidebar: this.sidebar.opened,
|
||||
// withoutAnimation: this.sidebar.withoutAnimation,
|
||||
// mobile: this.device === 'mobile'
|
||||
// }
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
handleClickOutside() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import store from '@/store'
|
||||
// import store from '@/store'
|
||||
|
||||
const { body } = document
|
||||
const WIDTH = 992 // refer to Bootstrap's responsive design
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
jest: true
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils'
|
||||
import VueRouter from 'vue-router'
|
||||
import ElementUI from 'element-ui'
|
||||
import Breadcrumb from '@/components/Breadcrumb/index.vue'
|
||||
|
||||
const localVue = createLocalVue()
|
||||
localVue.use(VueRouter)
|
||||
localVue.use(ElementUI)
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
children: [{
|
||||
path: 'dashboard',
|
||||
name: 'dashboard'
|
||||
}]
|
||||
},
|
||||
{
|
||||
path: '/menu',
|
||||
name: 'menu',
|
||||
children: [{
|
||||
path: 'menu1',
|
||||
name: 'menu1',
|
||||
meta: { title: 'menu1' },
|
||||
children: [{
|
||||
path: 'menu1-1',
|
||||
name: 'menu1-1',
|
||||
meta: { title: 'menu1-1' }
|
||||
},
|
||||
{
|
||||
path: 'menu1-2',
|
||||
name: 'menu1-2',
|
||||
redirect: 'noredirect',
|
||||
meta: { title: 'menu1-2' },
|
||||
children: [{
|
||||
path: 'menu1-2-1',
|
||||
name: 'menu1-2-1',
|
||||
meta: { title: 'menu1-2-1' }
|
||||
},
|
||||
{
|
||||
path: 'menu1-2-2',
|
||||
name: 'menu1-2-2'
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
|
||||
const router = new VueRouter({
|
||||
routes
|
||||
})
|
||||
|
||||
describe('Breadcrumb.vue', () => {
|
||||
const wrapper = mount(Breadcrumb, {
|
||||
localVue,
|
||||
router
|
||||
})
|
||||
it('dashboard', () => {
|
||||
router.push('/dashboard')
|
||||
const len = wrapper.findAll('.el-breadcrumb__inner').length
|
||||
expect(len).toBe(1)
|
||||
})
|
||||
it('normal route', () => {
|
||||
router.push('/menu/menu1')
|
||||
const len = wrapper.findAll('.el-breadcrumb__inner').length
|
||||
expect(len).toBe(2)
|
||||
})
|
||||
it('nested route', () => {
|
||||
router.push('/menu/menu1/menu1-2/menu1-2-1')
|
||||
const len = wrapper.findAll('.el-breadcrumb__inner').length
|
||||
expect(len).toBe(4)
|
||||
})
|
||||
it('no meta.title', () => {
|
||||
router.push('/menu/menu1/menu1-2/menu1-2-2')
|
||||
const len = wrapper.findAll('.el-breadcrumb__inner').length
|
||||
expect(len).toBe(3)
|
||||
})
|
||||
// it('click link', () => {
|
||||
// router.push('/menu/menu1/menu1-2/menu1-2-2')
|
||||
// const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
|
||||
// const second = breadcrumbArray.at(1)
|
||||
// console.log(breadcrumbArray)
|
||||
// const href = second.find('a').attributes().href
|
||||
// expect(href).toBe('#/menu/menu1')
|
||||
// })
|
||||
// it('noRedirect', () => {
|
||||
// router.push('/menu/menu1/menu1-2/menu1-2-1')
|
||||
// const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
|
||||
// const redirectBreadcrumb = breadcrumbArray.at(2)
|
||||
// expect(redirectBreadcrumb.contains('a')).toBe(false)
|
||||
// })
|
||||
it('last breadcrumb', () => {
|
||||
router.push('/menu/menu1/menu1-2/menu1-2-1')
|
||||
const breadcrumbArray = wrapper.findAll('.el-breadcrumb__inner')
|
||||
const redirectBreadcrumb = breadcrumbArray.at(3)
|
||||
expect(redirectBreadcrumb.contains('a')).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -1,18 +0,0 @@
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import Hamburger from '@/components/Hamburger/index.vue'
|
||||
describe('Hamburger.vue', () => {
|
||||
it('toggle click', () => {
|
||||
const wrapper = shallowMount(Hamburger)
|
||||
const mockFn = jest.fn()
|
||||
wrapper.vm.$on('toggleClick', mockFn)
|
||||
wrapper.find('.hamburger').trigger('click')
|
||||
expect(mockFn).toBeCalled()
|
||||
})
|
||||
it('prop isActive', () => {
|
||||
const wrapper = shallowMount(Hamburger)
|
||||
wrapper.setProps({ isActive: true })
|
||||
expect(wrapper.contains('.is-active')).toBe(true)
|
||||
wrapper.setProps({ isActive: false })
|
||||
expect(wrapper.contains('.is-active')).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -1,22 +0,0 @@
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
describe('SvgIcon.vue', () => {
|
||||
it('iconClass', () => {
|
||||
const wrapper = shallowMount(SvgIcon, {
|
||||
propsData: {
|
||||
iconClass: 'test'
|
||||
}
|
||||
})
|
||||
expect(wrapper.find('use').attributes().href).toBe('#icon-test')
|
||||
})
|
||||
it('className', () => {
|
||||
const wrapper = shallowMount(SvgIcon, {
|
||||
propsData: {
|
||||
iconClass: 'test'
|
||||
}
|
||||
})
|
||||
expect(wrapper.classes().length).toBe(1)
|
||||
wrapper.setProps({ className: 'test' })
|
||||
expect(wrapper.classes().includes('test')).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -1,30 +0,0 @@
|
||||
import { formatTime } from '@/utils/index.js'
|
||||
|
||||
describe('Utils:formatTime', () => {
|
||||
const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
|
||||
const retrofit = 5 * 1000
|
||||
|
||||
it('ten digits timestamp', () => {
|
||||
expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分')
|
||||
})
|
||||
it('test now', () => {
|
||||
expect(formatTime(+new Date() - 1)).toBe('刚刚')
|
||||
})
|
||||
it('less two minute', () => {
|
||||
expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前')
|
||||
})
|
||||
it('less two hour', () => {
|
||||
expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前')
|
||||
})
|
||||
it('less one day', () => {
|
||||
expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前')
|
||||
})
|
||||
it('more than one day', () => {
|
||||
expect(formatTime(d)).toBe('7月13日17时54分')
|
||||
})
|
||||
it('format', () => {
|
||||
expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
|
||||
expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
|
||||
expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
|
||||
})
|
||||
})
|
||||
@@ -1,28 +0,0 @@
|
||||
import { parseTime } from '@/utils/index.js'
|
||||
|
||||
describe('Utils:parseTime', () => {
|
||||
const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
|
||||
it('timestamp', () => {
|
||||
expect(parseTime(d)).toBe('2018-07-13 17:54:01')
|
||||
})
|
||||
it('ten digits timestamp', () => {
|
||||
expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01')
|
||||
})
|
||||
it('new Date', () => {
|
||||
expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01')
|
||||
})
|
||||
it('format', () => {
|
||||
expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54')
|
||||
expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13')
|
||||
expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54')
|
||||
})
|
||||
it('get the day of the week', () => {
|
||||
expect(parseTime(d, '{a}')).toBe('五') // 星期五
|
||||
})
|
||||
it('get the day of the week', () => {
|
||||
expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日
|
||||
})
|
||||
it('empty argument', () => {
|
||||
expect(parseTime()).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -1,17 +0,0 @@
|
||||
import { validUsername, isExternal } from '@/utils/validate.js'
|
||||
|
||||
describe('Utils:validate', () => {
|
||||
it('validUsername', () => {
|
||||
expect(validUsername('admin')).toBe(true)
|
||||
expect(validUsername('editor')).toBe(true)
|
||||
expect(validUsername('xxxx')).toBe(false)
|
||||
})
|
||||
it('isExternal', () => {
|
||||
expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true)
|
||||
expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true)
|
||||
expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false)
|
||||
expect(isExternal('/dashboard')).toBe(false)
|
||||
expect(isExternal('./dashboard')).toBe(false)
|
||||
expect(isExternal('dashboard')).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user