Merge branch 'master' of github.com:Liugq5713/vue-element-admin

This commit is contained in:
liugq 2019-03-07 11:04:38 +08:00
commit c687a3f329
5 changed files with 196 additions and 309 deletions

View File

@ -3,8 +3,8 @@ import Vue from 'vue'
// Flattened array // Flattened array
export default function treeToArray(data, children = 'children') { export default function treeToArray(data, children = 'children') {
let tmp = [] let tmp = []
data.forEach((item, idx) => { data.forEach((item, index) => {
Vue.set(item, '_index', idx) Vue.set(item, '_index', index)
tmp.push(item) tmp.push(item)
if (item[children] && item[children].length > 0) { if (item[children] && item[children].length > 0) {
const res = treeToArray(item[children], children) const res = treeToArray(item[children], children)
@ -14,8 +14,10 @@ export default function treeToArray(data, children = 'children') {
return tmp return tmp
} }
export function addAttrs(data, { parent = null, level = 0, expand = false, children = 'children', show = true, select = false } = {}) { export function addAttrs(data, { parent = null, preIndex = false, level = 0, expand = false, children = 'children', show = true, select = false } = {}) {
data.forEach(item => { data.forEach((item, index) => {
const _id = (preIndex ? `${preIndex}-${index}` : index) + ''
Vue.set(item, '_id', _id)
Vue.set(item, '_level', level) Vue.set(item, '_level', level)
Vue.set(item, '_expand', expand) Vue.set(item, '_expand', expand)
Vue.set(item, '_parent', parent) Vue.set(item, '_parent', parent)
@ -26,6 +28,7 @@ export function addAttrs(data, { parent = null, level = 0, expand = false, child
parent: item, parent: item,
level: level + 1, level: level + 1,
expand, expand,
preIndex: _id,
children, children,
status, status,
select select

View File

@ -1,6 +1,7 @@
<template> <template>
<el-table :data="tableData" :row-style="showRow" v-bind="$attrs"> <el-table :data="tableData" :row-style="showRow" v-bind="$attrs" v-on="$listeners" >
<slot name="selection" /> <slot name="selection" />
<slot name="pre-column" />
<el-table-column <el-table-column
v-for="item in columns" v-for="item in columns"
:label="item.label" :label="item.label"
@ -11,7 +12,7 @@
<template slot-scope="scope"> <template slot-scope="scope">
<slot :scope="scope" :name="item.key"> <slot :scope="scope" :name="item.key">
<template v-if="item.expand"> <template v-if="item.expand">
<span :style="{'padding-left':+scope.row._level*spreadOffset + 'px'} "/> <span :style="{'padding-left':+scope.row._level*indent + 'px'} "/>
<span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)"> <span v-show="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
<i v-if="!scope.row._expand" class="el-icon-plus" /> <i v-if="!scope.row._expand" class="el-icon-plus" />
<i v-else class="el-icon-minus" /> <i v-else class="el-icon-minus" />
@ -20,13 +21,13 @@
<template v-if="item.checkbox"> <template v-if="item.checkbox">
<el-checkbox <el-checkbox
v-if="scope.row[defaultChildren]&&scope.row[defaultChildren].length>0" v-if="scope.row[defaultChildren]&&scope.row[defaultChildren].length>0"
:style="{'padding-left':+scope.row._level*checkboxOffset + 'px'} " :style="{'padding-left':+scope.row._level*indent + 'px'} "
:indeterminate="scope.row._select" :indeterminate="scope.row._select"
v-model="scope.row._select" v-model="scope.row._select"
@change="handleCheckAllChange(scope.row)" /> @change="handleCheckAllChange(scope.row)" />
<el-checkbox <el-checkbox
v-else v-else
:style="{'padding-left':+scope.row._level*checkboxOffset + 'px'} " :style="{'padding-left':+scope.row._level*indent + 'px'} "
v-model="scope.row._select" v-model="scope.row._select"
@change="handleCheckAllChange(scope.row)" /> @change="handleCheckAllChange(scope.row)" />
</template> </template>
@ -52,7 +53,6 @@ export default {
type: Array, type: Array,
default: () => [] default: () => []
}, },
/* eslint-enable */
defaultExpandAll: { defaultExpandAll: {
type: Boolean, type: Boolean,
default: false default: false
@ -61,51 +61,59 @@ export default {
type: String, type: String,
default: 'children' default: 'children'
}, },
spreadOffset: { indent: {
type: Number,
default: 50
},
checkboxOffset: {
type: Number, type: Number,
default: 50 default: 50
} }
}, },
data() { data() {
return { return {
tableData: [],
guard: 1 guard: 1
} }
}, },
computed: { computed: {
children() { children() {
return this.defaultChildren return this.defaultChildren
} },
}, tableData() {
watch: { const data = this.data
data: { if (this.data.length === 0) {
// deep watchdeep watch return []
handler(val) { }
if (val.length === 0) { addAttrs(data, {
this.tableData = [] expand: this.defaultExpandAll,
return children: this.defaultChildren
} })
console.log('render')
if (this.guard > 0) {
addAttrs(val, {
expand: this.defaultExpandAll,
children: this.defaultChildren
})
this.guard--
}
const retval = treeToArray(val, this.defaultChildren) const retval = treeToArray(data, this.defaultChildren)
this.tableData = retval return retval
},
// deep: true,
immediate: true
} }
}, },
methods: { methods: {
addBrother(row, data) {
if (row._parent) {
row._parent.children.push(data)
} else {
this.data.push(data)
}
},
addChild(row, data) {
if (!row.children) {
this.$set(row, 'children', [])
}
row.children.push(data)
},
delete(row) {
const { _index, _parent } = row
if (_parent) {
_parent.children.splice(_index, 1)
} else {
this.data.splice(_index, 1)
}
},
getData() {
return this.tableData
},
showRow: function({ row }) { showRow: function({ row }) {
const parent = row._parent const parent = row._parent
const show = parent ? parent._expand && parent._show : true const show = parent ? parent._expand && parent._show : true

View File

@ -7,244 +7,158 @@
target="_blank" target="_blank"
>Documentation</a> >Documentation</a>
</el-tag> </el-tag>
<TreeTable
:data="menus" <tree-table
ref="TreeTable"
:data="tableData"
:default-expand-all="true" :default-expand-all="true"
:columns="columns" :columns="columns"
border border
default-children="sub_button" default-children="children"
@selection-change ="selectChange"
> >
<template slot="selection"> <template slot="selection">
<el-table-column type="selection" width="55"/> <el-table-column type="selection" align="center" width="55"/>
</template> </template>
<template slot="__expand">
<template slot="pre-column">
<el-table-column type="expand" width="55"> <el-table-column type="expand" width="55">
<template> <template>
<el-tag type="info"> <el-tag type="info">
支持element-ui 的扩展和多选框事件哦 Here is just a placeholder slot, you can display anything.
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<template slot="name" slot-scope="{scope}">
<span :style="{'padding-left':+scope.row.__level*50 + 'px'} "> <template slot="timeline" slot-scope="{scope}">
<a
v-if="scope.row.type === 'view'" <el-tooltip :content="scope.row.timeLine+'ms'" effect="dark" placement="left">
:href="scope.row.url" <div class="processContainer">
class="link-type" <div
>{{ scope.row.name }}</a> :style="{ width:(scope.row.timeLine||0) * 3+'px',
<span v-else>{{ scope.row.name }}</span> background:scope.row.timeLine>50?'rgba(233,0,0,.5)':'rgba(0,0,233,0.5)',
</span> marginLeft:scope.row._level * 50+'px' }"
class="process">
<span style="display:inline-block"/>
</div>
</div>
</el-tooltip>
</template> </template>
<template slot="__opt_parent" slot-scope="{scope}">
<template slot="append" slot-scope="{scope}">
<el-button <el-button
v-if="scope.row.__level === 0"
size="mini" size="mini"
type="primary" type="primary"
@click="addMenuItem(defaultMenu,1,scope.row.__index)" @click="addMenuItem(scope.row,'brother')"
>添加子菜单</el-button> >Append Brother
</el-button>
<el-button
size="mini"
type="primary"
@click="addMenuItem(scope.row,'children')"
>Append Child
</el-button>
</template> </template>
<template slot="__opt" slot-scope="{scope}"> <template slot="operation" slot-scope="{scope}">
<el-button size="mini" type="primary" @click="editMenuItem(scope.row,'update')">编辑</el-button> <el-button size="mini" type="success" @click="editItem(scope.row)">Edit</el-button>
<el-button size="mini" type="danger" @click="deleteMenuItem(scope.row)">删除</el-button> <el-button size="mini" type="danger" @click="deleteItem(scope.row)">Delete</el-button>
</template> </template>
</TreeTable> </tree-table>
</div> </div>
<el-dialog :visible.sync="dialogFormVisible" title="编辑菜单">
<el-form ref="menuForm" :model="menu" :rules="rules" label-width="100px" style="width:600px"> <el-dialog :visible.sync="dialogFormVisible" title="Edit">
<el-form-item label="type"> <el-form :model="tempItem" label-width="100px" style="width:600px">
<el-select v-model="menu.type" clearable placeholder="请选择"> <el-form-item label="Name">
<el-option label="view" value="view"/> <el-input v-model.trim="tempItem.name" placeholder="Name"/>
<el-option label="click" value="click"/>
<el-option label="miniprogram" value="miniprogram"/>
</el-select>
</el-form-item>
<template v-if="menu.type==='click'">
<el-form-item label="key">
<el-input v-model.trim="menu.key" placeholder="请输入key"/>
</el-form-item>
</template>
<template v-else>
<el-form-item label="url">
<el-input v-model.trim="menu.url" placeholder="请输入url"/>
</el-form-item>
</template>
<el-form-item label="名称">
<el-input v-model.trim="menu.name" placeholder="请输入name"/>
</el-form-item>
<el-form-item label="appid">
<el-input v-model.trim="menu.appid" placeholder="请输入appid"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="clickToUpsertMenuItem('menuForm')">确定</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">Cancel</el-button>
<el-button type="primary" @click="updateItem">Confirm</el-button>
</span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
const defaultMenu = {
name: undefined,
appid: Math.random() * 10000,
key: undefined,
page_path: undefined,
type: undefined,
url: undefined
}
import TreeTable from '@/components/TreeTable' import TreeTable from '@/components/TreeTable'
import { data } from './data.js' import { data } from './data.js'
export default { export default {
components: { components: { TreeTable },
TreeTable
},
data() { data() {
return { return {
defaultMenu, tableData: [],
menus: [], tempItem: {},
menu: { ...defaultMenu },
rules: {},
dialogFormVisible: false, dialogFormVisible: false,
columns: [ columns: [
{ {
label: '', label: 'Name',
key: '__sperad' key: 'name',
expand: true
}, },
{ {
label: 'name', label: 'Timeline',
key: 'name' key: 'timeline'
}, },
{ {
label: 'type', label: 'Append',
key: 'type' key: 'append',
width: 300
}, },
{ {
label: 'appid', label: 'Operation',
key: 'appid' key: 'operation',
}, width: 160
{
label: 'key',
key: 'key'
},
{
label: '操作',
key: '__opt_parent'
},
{
label: '操作',
key: '__opt',
width: '160px'
} }
] ]
} }
}, },
computed: {
canAddMenuItem() {
return this.menus.length < 3
}
},
created() { created() {
this.getWechatMenu() this.getData()
}, },
methods: { methods: {
getWechatMenu() { getData() {
this.menus = data.button this.tableData = data
}, },
// editItem(row) {
updateMenu() { this.tempItem = Object.assign({}, row)
const button = JSON.parse(
JSON.stringify(this.menus, [
'name',
'type',
'appid',
'url',
'key',
'media_id',
'page_path',
'sub_button'
])
)
//
console.log('button', button)
// upsertWechatMenu({ button }).then(() => {
// this.$message.success('')
// })
},
clickToUpsertMenuItem(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.updateMenuItem(this.menu)
this.dialogFormVisible = false
} else {
console.log('error submit!!')
return false
}
})
},
editMenuItem(menuItem) {
this.dialogFormVisible = true this.dialogFormVisible = true
this.menu = { ...menuItem }
}, },
// updateItem() {
// const data = this.$refs.TreeTable.getData()
addMenuItem(menuItem, level, index) { const { _id } = this.tempItem
if (level === 0) {
this.menus.push({ let index
...menuItem, for (let i = 0; i < data.length; i++) {
sub_button: [], if (data[i]._id === _id) {
__level: 0, index = i
__expand: true, break
__parent: null,
__show: true,
__select: false
})
}
if (level === 1) {
this.menus[index]['sub_button'].push({
...menuItem,
__level: 1,
__expand: true,
__parent: this.menus[index],
__show: true,
__select: false
})
}
},
deleteMenuItem(menuItem) {
if (menuItem.__level === 0) {
this.menus.splice(menuItem.__index, 1)
}
if (menuItem.__level === 1) {
this.menus[menuItem.__parent.__index]['sub_button'].splice(
menuItem.__index,
1
)
}
},
updateMenuItem(menuItem) {
if (menuItem.type === 'view') {
if (!menuItem.url) {
this.$message.error('请输入url')
return
} }
} }
if (menuItem.type === 'click') {
if (!menuItem.key) { data.splice(index, 1, Object.assign({}, this.tempItem))
this.$message.error('请输入key') this.dialogFormVisible = false
return },
} addMenuItem(row, type) {
if (type === 'children') {
this.$refs.TreeTable.addChild(row, { name: 'child' })
} }
if (menuItem.__level === 0) {
this.menus.splice(menuItem.__index, 1, menuItem) if (type === 'brother') {
} this.$refs.TreeTable.addBrother(row, { name: 'brother' })
if (menuItem.__level === 1) {
this.menus[menuItem.__parent.__index]['sub_button'].splice(
menuItem.__index,
1,
menuItem
)
} }
},
deleteItem(row) {
this.$refs.TreeTable.delete(row)
},
selectChange(val) {
console.log(val)
} }
} }
} }

View File

@ -1,87 +1,49 @@
export const data = { export const data = [
button: [ {
{ name: '1',
type: '', timeLine: 100,
name: '账号绑定', children: [
key: '', {
url: '', name: '1-1',
media_id: '', timeLine: 20
appid: '', },
page_path: '', {
sub_button: [ name: '1-2',
{ timeLine: 60,
type: 'view', children: [
name: '推送开关', {
key: '', name: '1-2-1',
url: 'https://activity.wallstreetcn.com/wechat-notice/#/', timeLine: 35
media_id: '', },
appid: '', {
page_path: '', name: '1-2-2',
sub_button: [] timeLine: 25
}, }
{ ]
type: 'view', }
name: '绑定账号', ]
key: '', },
url: 'https://m.wallstreetcn.com/bind/wechat', {
media_id: '', name: '2',
appid: '', timeLine: 80,
page_path: '', children: [
sub_button: [] {
} name: '2-1',
] timeLine: 30
}, },
{ {
type: '', name: '2-2',
name: '兑礼品卡', timeLine: 50
key: '', },
url: '', {
media_id: '', name: '2-3',
appid: '', timeLine: 60
page_path: '', }
sub_button: [ ]
{ },
type: 'view', {
name: '兑礼品卡', name: '3',
key: '', timeLine: 40
url: 'https://activity.wallstreetcn.com/giftredemption/?from=hrjsxk', }
media_id: '', ]
appid: '',
page_path: '',
sub_button: []
},
{
type: 'view',
name: '下载APP',
key: '',
url:
'https://activity.wallstreetcn.com/newpackaget/receive.html?ngsem=111',
media_id: '',
appid: '',
page_path: '',
sub_button: []
},
{
type: 'view',
name: '在线客服',
key: '',
url: 'https://wdl.wallstreetcn.com/WechatIMG26.jpeg',
media_id: '',
appid: '',
page_path: '',
sub_button: []
}
]
},
{
type: 'view',
name: '关注我',
key: '',
url: 'https://liugq5713.github.io',
media_id: '',
appid: '',
page_path: '',
sub_button: []
}
]
}

View File

@ -8,7 +8,7 @@
</el-button> </el-button>
<div class="option-item"> <div class="option-item">
<el-tag>默认展开所有</el-tag> <el-tag>Expand All</el-tag>
<el-switch <el-switch
v-model="defaultExpandAll" v-model="defaultExpandAll"
active-color="#13ce66" active-color="#13ce66"
@ -17,7 +17,7 @@
</div> </div>
<div class="option-item"> <div class="option-item">
<el-tag>显示Checkbox</el-tag> <el-tag>Show Checkbox</el-tag>
<el-switch <el-switch
v-model="showCheckbox" v-model="showCheckbox"
active-color="#13ce66" active-color="#13ce66"