release: template版本发布
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="头像组组件 -- 基础用法"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<avatars :data="data" />
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="头像组组件 -- 不显示tooltip"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<avatars :data="data" :tooltip="false" />
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="头像组组件 -- 最多展示5"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<avatars :data="data" :max="5" />
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="头像组组件 -- 展示头像"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<avatars show-avatar :data="data1" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AvatarsDemo">
|
||||
import { ref } from 'vue'
|
||||
import { AvatarConfig } from '_c/Avatars/types'
|
||||
import Avatars from '_c/Avatars/index.vue'
|
||||
|
||||
const data = ref<AvatarConfig[]>([
|
||||
{ text: '陈某某' },
|
||||
{ text: '李某某', type: 'success' },
|
||||
{ text: '张某某', type: 'danger' },
|
||||
{ text: '王某某', type: 'warning' },
|
||||
{ text: '龙某某' },
|
||||
{ text: '孙某某' },
|
||||
{ text: '刘某某' },
|
||||
{ text: '赵某某' }
|
||||
])
|
||||
const data1 = ref<AvatarConfig[]>([
|
||||
{
|
||||
text: '陈某某',
|
||||
url: 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2863969516,2611770076&fm=26&gp=0.jpg'
|
||||
},
|
||||
{
|
||||
text: '李某某',
|
||||
url: 'https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=465970198,3877503753&fm=26&gp=0.jpg'
|
||||
},
|
||||
{
|
||||
text: '张某某',
|
||||
url: 'https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1857202600,3614139084&fm=26&gp=0.jpg'
|
||||
},
|
||||
{
|
||||
text: '王某某',
|
||||
url: 'https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1444080181,4150129244&fm=26&gp=0.jpg'
|
||||
},
|
||||
{
|
||||
text: '龙某某',
|
||||
url: 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2469786567,2163872639&fm=26&gp=0.jpg'
|
||||
},
|
||||
{
|
||||
text: '孙某某',
|
||||
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4119236579,869456058&fm=26&gp=0.jpg'
|
||||
},
|
||||
{ text: '刘某某', url: 'xxxxx' },
|
||||
{ text: '赵某某' }
|
||||
])
|
||||
</script>
|
||||
@@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 vue-count-to 进行改造,支持所有 vue-count-to 参数。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<div class="count-to">
|
||||
<count-to
|
||||
ref="countRef"
|
||||
:start-val="startVal"
|
||||
:end-val="endVal"
|
||||
:duration="duration"
|
||||
:decimals="decimals"
|
||||
:separator="separator"
|
||||
:prefix="prefix"
|
||||
:suffix="suffix"
|
||||
:autoplay="autoplay"
|
||||
class="count-to__item"
|
||||
/>
|
||||
</div>
|
||||
<div class="action">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="action__item">
|
||||
<span>startVal:</span><el-input-number v-model="startVal" :min="0" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="action__item">
|
||||
<span>endVal:</span><el-input-number v-model="endVal" :min="1" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="action__item">
|
||||
<span>duration:</span><el-input-number v-model="duration" :min="1000" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="action__item"> <span>separator:</span><el-input v-model="separator" /> </div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="action__item"> <span>prefix:</span><el-input v-model="prefix" /> </div>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div class="action__item"> <span>suffix:</span><el-input v-model="suffix" /> </div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div style="margin-top: 20px; text-align: center">
|
||||
<el-button type="primary" @click="start">start</el-button>
|
||||
<el-button style="margin-left: 10px" @click="pauseResume">pause/resume</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CountToDemo">
|
||||
import { ref, unref } from 'vue'
|
||||
import CountTo from '_c/CountTo/index.vue'
|
||||
const countRef = ref<HTMLElement | null>(null)
|
||||
const startVal = ref<number>(0)
|
||||
const endVal = ref<number>(1314512)
|
||||
const duration = ref<number>(3000)
|
||||
const decimals = ref<number>(0)
|
||||
const separator = ref<string>(',')
|
||||
const prefix = ref<string>('¥ ')
|
||||
const suffix = ref<string>(' rmb')
|
||||
const autoplay = ref<boolean>(false)
|
||||
|
||||
function start(): void {
|
||||
;(unref(countRef) as any).start()
|
||||
}
|
||||
|
||||
function pauseResume(): void {
|
||||
;(unref(countRef) as any).pauseResume()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.count-to {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
|
||||
&__item {
|
||||
font-size: 80px;
|
||||
font-weight: bold;
|
||||
color: #f6416c;
|
||||
}
|
||||
}
|
||||
|
||||
.action {
|
||||
margin-top: 20px;
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
padding: 0 15px;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
|
||||
& > span {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.el-input-number) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,218 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="详情组件。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<com-detail :data="data" :schema="schema" title="基础示例" message="辅助文字" />
|
||||
|
||||
<com-detail
|
||||
title="不可折叠"
|
||||
:data="data"
|
||||
:schema="schema"
|
||||
:collapsed="false"
|
||||
message="辅助文字"
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
|
||||
<com-detail title="没有辅助文字" :data="data" :schema="schema" style="margin-top: 20px" />
|
||||
|
||||
<com-detail
|
||||
title="没有边框"
|
||||
:data="data"
|
||||
:schema="schema"
|
||||
:border="false"
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
|
||||
<com-detail
|
||||
title="垂直布局"
|
||||
:data="data"
|
||||
:vertical="true"
|
||||
:schema="schema"
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:hide-required-asterisk="true"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<com-detail title="与表单结合并自定义插槽" :data="form" :schema="fromSchema">
|
||||
<template #title="scope">
|
||||
<span class="is-required-item">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
<template #titleContent>
|
||||
<el-form-item prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template #author="scope">
|
||||
<span class="is-required-item">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
<template #authorContent>
|
||||
<el-form-item prop="author">
|
||||
<el-input v-model="form.author" placeholder="请输入作者" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template #display_time="scope">
|
||||
<span class="is-required-item">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
<template #display_timeContent>
|
||||
<el-form-item prop="display_time">
|
||||
<el-date-picker
|
||||
v-model="form.display_time"
|
||||
type="datetime"
|
||||
placeholder="请选择创建时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template #importance="scope">
|
||||
<span class="is-required-item">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
<template #importanceContent>
|
||||
<el-form-item prop="importance">
|
||||
<el-select v-model="form.importance" placeholder="请选择重要性" style="width: 100%">
|
||||
<el-option label="重要" value="3" />
|
||||
<el-option label="良好" value="2" />
|
||||
<el-option label="一般" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template #pageviews="scope">
|
||||
<span class="is-required-item">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
<template #pageviewsContent>
|
||||
<el-form-item prop="pageviews">
|
||||
<el-input-number
|
||||
v-model="form.pageviews"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</com-detail>
|
||||
<div style="margin-top: 15px; text-align: center">
|
||||
<el-button type="primary" @click="saveData">保存(控制台查看数据)</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DetailDemo">
|
||||
import { reactive, ref, unref } from 'vue'
|
||||
import { SchemaConfig } from '_c/ComDetail/types'
|
||||
|
||||
const formRef = ref<Nullable<any>>(null)
|
||||
|
||||
const requiredRule: {
|
||||
required: boolean
|
||||
message: string
|
||||
} = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
const data = reactive<IObj>({
|
||||
username: 'chenkl',
|
||||
nickName: '梦似花落。',
|
||||
age: 26,
|
||||
phone: '13655971xxxx',
|
||||
email: '502431556@qq.com',
|
||||
addr: '这是一个很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的地址',
|
||||
sex: '男',
|
||||
certy: '35058319940712xxxx'
|
||||
})
|
||||
|
||||
const schema = reactive<SchemaConfig[]>([
|
||||
{
|
||||
field: 'username',
|
||||
label: '用户名'
|
||||
},
|
||||
{
|
||||
field: 'nickName',
|
||||
label: '昵称'
|
||||
},
|
||||
{
|
||||
field: 'phone',
|
||||
label: '联系电话'
|
||||
},
|
||||
{
|
||||
field: 'email',
|
||||
label: '邮箱'
|
||||
},
|
||||
{
|
||||
field: 'addr',
|
||||
label: '地址',
|
||||
span: 24
|
||||
}
|
||||
])
|
||||
|
||||
const fromSchema = reactive<SchemaConfig[]>([
|
||||
{
|
||||
field: 'title',
|
||||
label: '标题',
|
||||
span: 24
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: '作者'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: '重要性'
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: '阅读数'
|
||||
}
|
||||
])
|
||||
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
author: '', // 作者
|
||||
title: '', // 标题
|
||||
importance: '', // 重要性
|
||||
display_time: '', // 创建时间
|
||||
pageviews: 0 // 阅读数
|
||||
})
|
||||
|
||||
const rules = reactive<IObj>({
|
||||
title: [requiredRule],
|
||||
author: [requiredRule],
|
||||
importance: [requiredRule],
|
||||
display_time: [requiredRule],
|
||||
pageviews: [requiredRule]
|
||||
})
|
||||
|
||||
function saveData() {
|
||||
try {
|
||||
;(unref(formRef) as any).validate((valid) => {
|
||||
if (valid) {
|
||||
console.log(form)
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="对 Element 的 Dialog 组件进行二次封装,支持所有原生参数。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-button type="primary" @click="visible = true">打开弹窗</el-button>
|
||||
|
||||
<com-dialog v-model="visible" title="提示">
|
||||
<div style="height: 1000px"> 我是弹窗内容 </div>
|
||||
<template #footer>
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="visible = false">确定</el-button>
|
||||
</template>
|
||||
</com-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DialogDemo">
|
||||
import { ref } from 'vue'
|
||||
const visible = ref<boolean>(false)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,306 +0,0 @@
|
||||
import { EChartsOption } from 'echarts'
|
||||
import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud'
|
||||
|
||||
export const lineOptions: EChartsOption = {
|
||||
xAxis: {
|
||||
data: [
|
||||
'一月',
|
||||
'二月',
|
||||
'三月',
|
||||
'四月',
|
||||
'五月',
|
||||
'六月',
|
||||
'七月',
|
||||
'八月',
|
||||
'九月',
|
||||
'十月',
|
||||
'十一月',
|
||||
'十二月'
|
||||
],
|
||||
boundaryGap: false,
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: 20,
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
top: 30,
|
||||
containLabel: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
},
|
||||
padding: [5, 10]
|
||||
},
|
||||
yAxis: {
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['预期', '实际']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '预期',
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123],
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'cubicInOut'
|
||||
},
|
||||
{
|
||||
name: '实际',
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
itemStyle: {},
|
||||
data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123],
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'quadraticOut'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const pieOptions: EChartsOption = {
|
||||
title: {
|
||||
text: '用户访问来源',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left',
|
||||
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '用户访问来源',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['50%', '60%'],
|
||||
data: [
|
||||
{ value: 335, name: '直接访问' },
|
||||
{ value: 310, name: '邮件营销' },
|
||||
{ value: 234, name: '联盟广告' },
|
||||
{ value: 135, name: '视频广告' },
|
||||
{ value: 1548, name: '搜索引擎' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const barOptions: EChartsOption = {
|
||||
title: {
|
||||
text: '每周用户活跃量',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '活跃量',
|
||||
data: [13253, 34235, 26321, 12340, 24643, 1322, 1324],
|
||||
type: 'bar'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const pieOptions2: EChartsOption = {
|
||||
title: {
|
||||
text: '用户访问来源',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '访问来源',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['50%', '50%'],
|
||||
data: [
|
||||
{
|
||||
value: 335,
|
||||
name: '直接访问'
|
||||
},
|
||||
{
|
||||
value: 310,
|
||||
name: '邮件营销'
|
||||
},
|
||||
{
|
||||
value: 274,
|
||||
name: '联盟广告'
|
||||
},
|
||||
{
|
||||
value: 235,
|
||||
name: '视频广告'
|
||||
},
|
||||
{
|
||||
value: 400,
|
||||
name: '搜索引擎'
|
||||
}
|
||||
].sort(function (a, b) {
|
||||
return a.value - b.value
|
||||
}),
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const wordOptions: EChartsWordOption = {
|
||||
tooltip: {},
|
||||
series: [
|
||||
{
|
||||
type: 'wordCloud',
|
||||
gridSize: 2,
|
||||
sizeRange: [12, 50],
|
||||
rotationRange: [-90, 90],
|
||||
shape: 'pentagon',
|
||||
width: 600,
|
||||
height: 400,
|
||||
drawOutOfBound: true,
|
||||
textStyle: {
|
||||
color: function () {
|
||||
return (
|
||||
'rgb(' +
|
||||
[
|
||||
Math.round(Math.random() * 160),
|
||||
Math.round(Math.random() * 160),
|
||||
Math.round(Math.random() * 160)
|
||||
].join(',') +
|
||||
')'
|
||||
)
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowColor: '#333'
|
||||
}
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: 'Sam S Club',
|
||||
value: 10000,
|
||||
textStyle: {
|
||||
color: 'black'
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Macys',
|
||||
value: 6181
|
||||
},
|
||||
{
|
||||
name: 'Amy Schumer',
|
||||
value: 4386
|
||||
},
|
||||
{
|
||||
name: 'Jurassic World',
|
||||
value: 4055
|
||||
},
|
||||
{
|
||||
name: 'Charter Communications',
|
||||
value: 2467
|
||||
},
|
||||
{
|
||||
name: 'Chick Fil A',
|
||||
value: 2244
|
||||
},
|
||||
{
|
||||
name: 'Planet Fitness',
|
||||
value: 1898
|
||||
},
|
||||
{
|
||||
name: 'Pitch Perfect',
|
||||
value: 1484
|
||||
},
|
||||
{
|
||||
name: 'Express',
|
||||
value: 1112
|
||||
},
|
||||
{
|
||||
name: 'Home',
|
||||
value: 965
|
||||
},
|
||||
{
|
||||
name: 'Johnny Depp',
|
||||
value: 847
|
||||
},
|
||||
{
|
||||
name: 'Lena Dunham',
|
||||
value: 582
|
||||
},
|
||||
{
|
||||
name: 'Lewis Hamilton',
|
||||
value: 555
|
||||
},
|
||||
{
|
||||
name: 'KXAN',
|
||||
value: 550
|
||||
},
|
||||
{
|
||||
name: 'Mary Ellen Mark',
|
||||
value: 462
|
||||
},
|
||||
{
|
||||
name: 'Farrah Abraham',
|
||||
value: 366
|
||||
},
|
||||
{
|
||||
name: 'Rita Ora',
|
||||
value: 360
|
||||
},
|
||||
{
|
||||
name: 'Serena Williams',
|
||||
value: 282
|
||||
},
|
||||
{
|
||||
name: 'NCAA baseball tournament',
|
||||
value: 273
|
||||
},
|
||||
{
|
||||
name: 'Point Break',
|
||||
value: 265
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="统一封装 Echart 组件,自适应宽度,只需传入 options 与 height 属性即可展示对应的图表。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="10">
|
||||
<div class="chart-wrap">
|
||||
<echart :height="'300px'" :options="pieOptions" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<div class="chart-wrap">
|
||||
<echart :options="barOptions" :height="'300px'" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<div class="chart-wrap">
|
||||
<echart :options="lineOptions" :height="'300px'" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<div class="chart-wrap">
|
||||
<echart :options="pieOptions2" :height="'300px'" />
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="chart-wrap">
|
||||
<echart :options="wordOptions" :height="'300px'" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="EchartsDemo">
|
||||
import { lineOptions, pieOptions, barOptions, pieOptions2, wordOptions } from './echart-data'
|
||||
import Echart from '_c/Echart/index.vue'
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-wrap {
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,45 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 wangeditor 封装的 富文本 组件。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<editor ref="editorRef" :value="content" @change="handleChange" />
|
||||
|
||||
<div style="margin-top: 20px; text-align: center">
|
||||
<el-button @click="showHtml"> 获取TTML(请在控制台查看) </el-button>
|
||||
<el-button @click="showText"> 获取TEXT(请在控制台查看) </el-button>
|
||||
<el-button @click="showJson"> 获取JSON(请在控制台查看) </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="EditorDemo">
|
||||
import { ref, unref } from 'vue'
|
||||
import Editor from '_c/Editor/index.vue'
|
||||
|
||||
const content = ref<string>('默认展示数据')
|
||||
const editorRef = ref<Nullable<any>>(null)
|
||||
|
||||
function handleChange(html: string) {
|
||||
console.log(html)
|
||||
}
|
||||
|
||||
function showHtml() {
|
||||
console.log((unref(editorRef) as any).getHtml())
|
||||
}
|
||||
|
||||
function showText() {
|
||||
console.log((unref(editorRef) as any).getText())
|
||||
}
|
||||
|
||||
function showJson() {
|
||||
console.log((unref(editorRef) as any).getJSON())
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="文字高亮组件 -- 基础用法"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<highlight :keys="['vue-element-plus-admin', 'vue-element-admin', 'vben-admin']">
|
||||
vue-element-plus-admin是一个基于vue3、vite2、element-plus的后台解决方案,借鉴了vue-element-admin和vben-admin的写法和优点。内置了动态路由,权限验证,典型的业务模型,丰富的功能组件,并且提供了多页配置,开箱即用,可以用来作为项目的启动模版。它可以帮助你快速搭建企业级中后台产品原型,也可以作为一个示例,用于学习。
|
||||
</highlight>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="文字高亮组件 -- 点击事件"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<highlight
|
||||
:keys="['vue-element-plus-admin', 'vue-element-admin', 'vben-admin']"
|
||||
@click="keyClick"
|
||||
>
|
||||
vue-element-plus-admin是一个基于vue3、vite2、element-plus的后台解决方案,借鉴了vue-element-admin和vben-admin的写法和优点。内置了动态路由,权限验证,典型的业务模型,丰富的功能组件,并且提供了多页配置,开箱即用,可以用来作为项目的启动模版。它可以帮助你快速搭建企业级中后台产品原型,也可以作为一个示例,用于学习。
|
||||
</highlight>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="HighlightDemo">
|
||||
import Highlight from '_c/Highlight/index'
|
||||
import { Message } from '_c/Message'
|
||||
function keyClick(key: string) {
|
||||
Message.success(key)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="二次封装 Element 的 Message 组件,每次只显示最新一条消息,避免出现太多消息提示导致不美观。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-button @click="show">显示</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MessageDemo">
|
||||
import { ref } from 'vue'
|
||||
import { Message } from '_c/Message'
|
||||
const count = ref<number>(0)
|
||||
function show() {
|
||||
count.value = count.value + 1
|
||||
Message.success('这是成功消息' + count.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="抽取于 Element 的图片预览组件进行改造,实现函数式调用组件,无需基于图片进行点击预览。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="有底图预览。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<div class="img-wrap">
|
||||
<div
|
||||
v-for="(item, $index) in imgList"
|
||||
:key="item"
|
||||
class="img-item"
|
||||
@click="showHasImg($index)"
|
||||
>
|
||||
<img :src="item" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="无底图预览。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<el-button type="primary" @click="showNoImg">点击预览</el-button>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="点击事件,包含图片点击事件以及关闭事件。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<el-button type="primary" @click="showImg">点击预览</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PreviewDemo">
|
||||
import { ref } from 'vue'
|
||||
import { createImgPreview } from '_c/Preview'
|
||||
import { Message } from '_c/Message'
|
||||
|
||||
const imgList = ref<string[]>([
|
||||
'https://img1.baidu.com/it/u=657828739,1486746195&fm=26&fmt=auto&gp=0.jpg',
|
||||
'https://img0.baidu.com/it/u=3114228356,677481409&fm=26&fmt=auto&gp=0.jpg',
|
||||
'https://img1.baidu.com/it/u=508846955,3814747122&fm=26&fmt=auto&gp=0.jpg',
|
||||
'https://img1.baidu.com/it/u=3536647690,3616605490&fm=26&fmt=auto&gp=0.jpg',
|
||||
'https://img1.baidu.com/it/u=4087287201,1148061266&fm=26&fmt=auto&gp=0.jpg',
|
||||
'https://img2.baidu.com/it/u=3429163260,2974496379&fm=26&fmt=auto&gp=0.jpg'
|
||||
])
|
||||
|
||||
function showHasImg(i: number) {
|
||||
createImgPreview({
|
||||
index: i,
|
||||
imageList: imgList.value
|
||||
})
|
||||
}
|
||||
|
||||
function showNoImg() {
|
||||
createImgPreview({
|
||||
index: 0,
|
||||
imageList: imgList.value
|
||||
})
|
||||
}
|
||||
|
||||
function showImg() {
|
||||
createImgPreview({
|
||||
index: 0,
|
||||
imageList: imgList.value,
|
||||
onClose: (i: number) => {
|
||||
Message.info('关闭的图片索引:' + i)
|
||||
},
|
||||
onSelect: (i: number) => {
|
||||
Message.info('当前点击的图片索引:' + i)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.img-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.img-item {
|
||||
position: relative;
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
margin: 0 10px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<div class="title-item">基础用法,默认canvas</div>
|
||||
<qrcode text="vue-element-plus-admin" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">img标签</div>
|
||||
<qrcode text="vue-element-plus-admin" tag="img" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">样式配置</div>
|
||||
<qrcode
|
||||
text="vue-element-plus-admin"
|
||||
:options="{
|
||||
color: {
|
||||
dark: '#55D187',
|
||||
light: '#2d8cf0'
|
||||
}
|
||||
}"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">点击</div>
|
||||
<qrcode text="vue-element-plus-admin" @click="codeClick" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">异步内容</div>
|
||||
<qrcode :text="text" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">二维码失效</div>
|
||||
<qrcode text="vue-element-plus-admin" :disabled="true" @disabled-click="disabledClick" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">logo配置</div>
|
||||
<qrcode text="vue-element-plus-admin" :logo="logoImg" />
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">logo样式配置</div>
|
||||
<qrcode
|
||||
text="vue-element-plus-admin"
|
||||
:logo="{
|
||||
src: logoImg,
|
||||
logoSize: 0.2,
|
||||
borderSize: 0.05,
|
||||
borderRadius: 50,
|
||||
bgColor: 'blue'
|
||||
}"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="title-item">大小配置</div>
|
||||
<qrcode text="vue-element-plus-admin" :width="300" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="QrcodeDemo">
|
||||
import { ref } from 'vue'
|
||||
import Qrcode from '_c/Qrcode/index.vue'
|
||||
import { Message } from '_c/Message'
|
||||
import logoImg from '@/assets/img/logo.png'
|
||||
|
||||
const text = ref<string>('')
|
||||
setTimeout(() => {
|
||||
text.value = '我是异步生成的内容'
|
||||
}, 3000)
|
||||
|
||||
function codeClick() {
|
||||
Message.info('我被点击了。')
|
||||
}
|
||||
function disabledClick() {
|
||||
Message.info('我失效被点击了。')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-col {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
.title-item {
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,149 +0,0 @@
|
||||
export const classicData = [
|
||||
{
|
||||
label: '即时配送',
|
||||
value: true,
|
||||
itemType: 'switch',
|
||||
field: 'delivery'
|
||||
},
|
||||
{
|
||||
label: '活动名称',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'name',
|
||||
placeholder: '活动名称',
|
||||
clearable: true,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入活动名称'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '活动区域',
|
||||
value: '',
|
||||
itemType: 'select',
|
||||
placeholder: '活动区域',
|
||||
clearable: true,
|
||||
field: 'region',
|
||||
options: [
|
||||
{
|
||||
title: '区域一',
|
||||
value: 'fujian'
|
||||
},
|
||||
{
|
||||
title: '区域二',
|
||||
value: 'beijing'
|
||||
}
|
||||
],
|
||||
rules: [
|
||||
{
|
||||
itemType: 'string',
|
||||
required: true,
|
||||
message: '请选择活动区域'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '特殊资源',
|
||||
value: '2',
|
||||
itemType: 'radio',
|
||||
field: 'resource',
|
||||
radioType: 'button', // button or radio
|
||||
options: [
|
||||
{
|
||||
label: '线上品牌商赞助',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '线下场地免费',
|
||||
value: '2'
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// label: '组织机构',
|
||||
// value: [],
|
||||
// itemType: 'treeSelect',
|
||||
// field: 'company',
|
||||
// allowClear: true,
|
||||
// placeholder: '请选择组织机构',
|
||||
// treeCheckable: false,
|
||||
// maxTagCount: 2,
|
||||
// options: [
|
||||
// {
|
||||
// title: 'Node1',
|
||||
// value: '0-0',
|
||||
// key: '0-0',
|
||||
// children: [
|
||||
// {
|
||||
// title: 'Child Node1',
|
||||
// value: '0-0-0',
|
||||
// key: '0-0-0'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// title: 'Node2',
|
||||
// value: '0-1',
|
||||
// key: '0-1',
|
||||
// children: [
|
||||
// {
|
||||
// title: 'Child Node3',
|
||||
// value: '0-1-0',
|
||||
// key: '0-1-0',
|
||||
// disabled: true
|
||||
// },
|
||||
// {
|
||||
// title: 'Child Node4',
|
||||
// value: '0-1-1',
|
||||
// key: '0-1-1'
|
||||
// },
|
||||
// {
|
||||
// title: 'Child Node5',
|
||||
// value: '0-1-2',
|
||||
// key: '0-1-2'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
label: '日选择器',
|
||||
value: '',
|
||||
itemType: 'datePicker',
|
||||
field: 'date1',
|
||||
clearable: true,
|
||||
format: 'YYYY-MM-DD',
|
||||
placeholder: '请选择日期'
|
||||
},
|
||||
{
|
||||
label: '月选择器',
|
||||
value: '',
|
||||
itemType: 'datePicker',
|
||||
field: 'date2',
|
||||
clearable: true,
|
||||
format: 'YYYY-MM',
|
||||
placeholder: '请选择日期'
|
||||
},
|
||||
{
|
||||
label: '范围选择器',
|
||||
value: [],
|
||||
itemType: 'datePicker',
|
||||
field: 'date3',
|
||||
clearable: true,
|
||||
type: 'daterange',
|
||||
rangeSeparator: '至',
|
||||
startPlaceholder: '开始日期',
|
||||
endPlaceholder: '结束日期'
|
||||
},
|
||||
{
|
||||
label: '周选择器',
|
||||
value: '',
|
||||
itemType: 'datePicker',
|
||||
field: 'date4',
|
||||
type: 'week',
|
||||
clearable: true,
|
||||
placeholder: '请选择日期'
|
||||
}
|
||||
]
|
||||
@@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="封装 Element 的 Form 组件,实现查询、重置等功能,并提供了三种布局风格。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="经典风格。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search :data="classicData" @search-submit="searchSubmit1" @reset-submit="resetSubmit1" />
|
||||
<div> 查询/重置后的数据:{{ formData1 }} </div>
|
||||
</div>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="底部操作按钮风格。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search
|
||||
layout="bottom"
|
||||
:data="classicData"
|
||||
@search-submit="searchSubmit2"
|
||||
@reset-submit="resetSubmit2"
|
||||
/>
|
||||
<div> 查询/重置后的数据:{{ formData2 }} </div>
|
||||
</div>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="右侧操作按钮风格。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="searh">
|
||||
<com-search
|
||||
layout="right"
|
||||
:data="classicData"
|
||||
@search-submit="searchSubmit3"
|
||||
@reset-submit="resetSubmit3"
|
||||
/>
|
||||
<div> 查询/重置后的数据:{{ formData3 }} </div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="SearchDemo">
|
||||
import { ref } from 'vue'
|
||||
import { classicData } from './data'
|
||||
const formData1 = ref<Nullable<IObj>>(null)
|
||||
const formData2 = ref<Nullable<IObj>>(null)
|
||||
const formData3 = ref<Nullable<IObj>>(null)
|
||||
|
||||
function searchSubmit1(data: any): void {
|
||||
formData1.value = data
|
||||
}
|
||||
|
||||
function resetSubmit1(data: any): void {
|
||||
formData1.value = data
|
||||
}
|
||||
|
||||
function searchSubmit2(data: any): void {
|
||||
formData2.value = data
|
||||
}
|
||||
|
||||
function resetSubmit2(data: any): void {
|
||||
formData2.value = data
|
||||
}
|
||||
|
||||
function searchSubmit3(data: any): void {
|
||||
formData3.value = data
|
||||
}
|
||||
|
||||
function resetSubmit3(data: any): void {
|
||||
formData3.value = data
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.searh {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -1,26 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="useWatermark,为整个系统提供水印功能。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-button type="primary" @click="setWatermark('vue-element-plus-admin')">创建水印</el-button>
|
||||
<el-button type="danger" @click="clear">清除水印</el-button>
|
||||
<el-button type="warning" @click="setWatermark('vue-element-plus-admin-new')">
|
||||
重置水印
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Watermark">
|
||||
import { onBeforeUnmount } from 'vue'
|
||||
import { useWatermark } from '@/hooks/web/useWatermark'
|
||||
const { setWatermark, clear } = useWatermark()
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clear()
|
||||
})
|
||||
</script>
|
||||
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="20" class="panel-group">
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
|
||||
<div class="card-panel-icon-wrapper icon-people">
|
||||
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">新增用户</div>
|
||||
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('messages')">
|
||||
<div class="card-panel-icon-wrapper icon-message">
|
||||
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">未读信息</div>
|
||||
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('purchases')">
|
||||
<div class="card-panel-icon-wrapper icon-money">
|
||||
<svg-icon icon-class="money" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">成交金额</div>
|
||||
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">购物总量</div>
|
||||
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PanelGroup">
|
||||
import CountTo from '_c/CountTo/index.vue'
|
||||
|
||||
const emit = defineEmits(['handleSetLineChartData'])
|
||||
|
||||
function handleSetLineChartData(type: string) {
|
||||
emit('handleSetLineChartData', type)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.panel-group {
|
||||
.card-panel-col {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.card-panel {
|
||||
position: relative;
|
||||
height: 108px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border-color: rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:hover {
|
||||
.card-panel-icon-wrapper {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icon-people {
|
||||
background: #40c9c6;
|
||||
}
|
||||
|
||||
.icon-message {
|
||||
background: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-money {
|
||||
background: #f4516c;
|
||||
}
|
||||
|
||||
.icon-shopping {
|
||||
background: #34bfa3;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-people {
|
||||
color: #40c9c6;
|
||||
}
|
||||
|
||||
.icon-message {
|
||||
color: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-money {
|
||||
color: #f4516c;
|
||||
}
|
||||
|
||||
.icon-shopping {
|
||||
color: #34bfa3;
|
||||
}
|
||||
|
||||
.card-panel-icon-wrapper {
|
||||
float: left;
|
||||
padding: 16px;
|
||||
margin: 14px 0 0 14px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.38s ease-out;
|
||||
}
|
||||
|
||||
.card-panel-icon {
|
||||
float: left;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.card-panel-description {
|
||||
float: right;
|
||||
margin: 26px;
|
||||
margin-left: 0;
|
||||
font-weight: bold;
|
||||
|
||||
.card-panel-text {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.card-panel-num {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<panel-group />
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="10">
|
||||
<div class="chart__wrap">
|
||||
@@ -22,7 +21,6 @@
|
||||
<script setup lang="ts" name="Dashboard">
|
||||
import { lineOptions, pieOptions, barOptions } from './echart-data'
|
||||
import Echart from '_c/Echart/index.vue'
|
||||
import PanelGroup from './components/PanelGroup.vue'
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="自定义指令:v-clipboard,用于复制文本。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基础示例。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="input__wrap">
|
||||
<el-input v-model="inputVal1" placeholder="请输入要复制的文本" />
|
||||
<el-button v-clipboard="inputVal1" type="primary">复制</el-button>
|
||||
</div>
|
||||
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="自定义回调方法。"
|
||||
type="info"
|
||||
style="margin-top: 20px; margin-bottom: 20px"
|
||||
/>
|
||||
<div class="input__wrap">
|
||||
<el-input v-model="inputVal2" placeholder="请输入要复制的文本" />
|
||||
<el-button
|
||||
v-clipboard="inputVal2"
|
||||
v-clipboard:success="clipboardSuccess"
|
||||
v-clipboard:error="clipboardError"
|
||||
type="primary"
|
||||
>复制</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="DirectivesDemo">
|
||||
import { ref } from 'vue'
|
||||
import { Message } from '_c/Message'
|
||||
const inputVal1 = ref<string>('')
|
||||
const inputVal2 = ref<string>('')
|
||||
function clipboardSuccess(val: any) {
|
||||
Message.success('我是自定义成功回调:' + val.text)
|
||||
}
|
||||
function clipboardError() {
|
||||
Message.error('我是自定义失败回调')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.input__wrap {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +0,0 @@
|
||||
import fetch from '@/axios-config'
|
||||
|
||||
export const getExampleListApi = ({ params }: any) => {
|
||||
return fetch({ url: '/example/list', method: 'get', params })
|
||||
}
|
||||
|
||||
export const delsExampApi = ({ data }: any) => {
|
||||
return fetch({ url: '/example/delete', method: 'post', data })
|
||||
}
|
||||
|
||||
export const setExampApi = ({ data }: any) => {
|
||||
return fetch({ url: '/example/save', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getExampDetApi = ({ params }: any) => {
|
||||
return fetch({ url: '/example/detail', method: 'get', params })
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<com-detail :data="form" :schema="fromSchema" :collapsed="false" title="文章详情">
|
||||
<template #contentContent="scope">
|
||||
<div v-html="scope.row.content"></div>
|
||||
</template>
|
||||
</com-detail>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Detail">
|
||||
import { PropType, reactive } from 'vue'
|
||||
import { getExampDetApi } from '../api'
|
||||
import { SchemaConfig } from '_c/ComDetail/types'
|
||||
|
||||
const fromSchema: SchemaConfig[] = [
|
||||
{
|
||||
field: 'title',
|
||||
label: '标题',
|
||||
span: 24
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: '作者'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: '重要性'
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: '阅读数'
|
||||
},
|
||||
{
|
||||
field: 'content',
|
||||
label: '内容',
|
||||
span: 24
|
||||
}
|
||||
]
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object as PropType<Nullable<IObj>>,
|
||||
default: () => null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
author: '', // 作者
|
||||
title: '', // 标题
|
||||
content: '', // 内容
|
||||
importance: '', // 重要性
|
||||
display_time: '', // 创建时间
|
||||
pageviews: 0 // 阅读数
|
||||
})
|
||||
|
||||
async function getDet() {
|
||||
if (props.info) {
|
||||
const id = props.info.id
|
||||
try {
|
||||
const res: any = await getExampDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
for (const key in form) {
|
||||
if (key === 'importance') {
|
||||
form[key] = (res.data[key] as number).toString()
|
||||
} else {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="title" label="标题">
|
||||
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="author" label="作者">
|
||||
<el-input v-model="form.author" placeholder="请输入作者" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="display_time" label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="form.display_time"
|
||||
type="datetime"
|
||||
placeholder="请选择创建时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="importance" label="重要性">
|
||||
<el-select v-model="form.importance" placeholder="请选择重要性" style="width: 100%">
|
||||
<el-option label="重要" value="3" />
|
||||
<el-option label="良好" value="2" />
|
||||
<el-option label="一般" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="pageviews" label="阅读数">
|
||||
<el-input-number
|
||||
v-model="form.pageviews"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="content" label="内容">
|
||||
<editor ref="editorRef" :value="form.content" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="IfnoWrite">
|
||||
import { PropType, reactive, ref } from 'vue'
|
||||
import { setExampApi, getExampDetApi } from '../api'
|
||||
import Editor from '_c/Editor/index.vue'
|
||||
import { Message } from '_c/Message'
|
||||
|
||||
const requiredRule: {
|
||||
required: boolean
|
||||
message: string
|
||||
} = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object as PropType<Nullable<IObj>>,
|
||||
default: () => null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
|
||||
const editorRef = ref<Nullable<HTMLElement>>(null)
|
||||
const formRef = ref<Nullable<HTMLElement>>(null)
|
||||
|
||||
const subLoading = ref<boolean>(false)
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
author: '', // 作者
|
||||
title: '', // 标题
|
||||
content: '', // 内容
|
||||
importance: '', // 重要性
|
||||
display_time: '', // 创建时间
|
||||
pageviews: 0 // 阅读数
|
||||
})
|
||||
const rules = reactive<IObj>({
|
||||
title: [requiredRule],
|
||||
author: [requiredRule],
|
||||
content: [requiredRule],
|
||||
importance: [requiredRule],
|
||||
display_time: [requiredRule],
|
||||
pageviews: [requiredRule]
|
||||
})
|
||||
|
||||
async function getDet() {
|
||||
if (props.info) {
|
||||
const id = props.info.id
|
||||
try {
|
||||
const res: any = await getExampDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
for (const key in form) {
|
||||
if (key === 'importance') {
|
||||
form[key] = (res.data[key] as number).toString()
|
||||
} else {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增或者编辑
|
||||
function setListData() {
|
||||
try {
|
||||
subLoading.value = true
|
||||
form.content = (editorRef.value as any).getHtml()
|
||||
;(formRef.value as any).validate(async (valid) => {
|
||||
if (valid) {
|
||||
const res = await setExampApi({
|
||||
data: form
|
||||
})
|
||||
if (res) {
|
||||
Message.success(form.id ? '编辑成功' : '新增成功')
|
||||
emit('success', form.id ? 'edit' : 'add')
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
export interface InfoWriteParams {
|
||||
title: string
|
||||
id?: string
|
||||
author: string
|
||||
content: string
|
||||
importance: string
|
||||
display_time: string
|
||||
pageviews: number
|
||||
}
|
||||
|
||||
export interface InfoWriteRules {
|
||||
title?: any[]
|
||||
author?: any[]
|
||||
content?: any[]
|
||||
importance?: any[]
|
||||
display_time?: any[]
|
||||
pageviews?: any[]
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="search__example--wrap">
|
||||
<com-search :data="searchData" @search-submit="searchSubmit" @reset-submit="resetSubmit" />
|
||||
</div>
|
||||
|
||||
<div class="button__example--wrap">
|
||||
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="open(null, 'InfoWrite')">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" @click="dels">删除</el-button>
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
selection
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defaultParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<template #importance="scope">
|
||||
<el-tag
|
||||
:type="
|
||||
scope.row.importance === 3
|
||||
? 'success'
|
||||
: scope.row.importance === 2
|
||||
? 'warning'
|
||||
: 'danger'
|
||||
"
|
||||
>
|
||||
{{ scope.row.importance === 3 ? '重要' : scope.row.importance === 2 ? '良好' : '一般' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #action="scope">
|
||||
<el-button type="primary" size="mini" @click="open(scope.row, 'InfoWrite')">编辑</el-button>
|
||||
<el-button type="success" size="mini" @click="open(scope.row, 'Detail')">查看</el-button>
|
||||
<el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
|
||||
<com-dialog v-model="dialogVisible" :title="dialogTitle">
|
||||
<info-write
|
||||
v-if="comName === 'InfoWrite' && dialogVisible"
|
||||
:info="rowData"
|
||||
@close="toggleVisible"
|
||||
@success="refreshTable"
|
||||
/>
|
||||
<detail v-if="comName === 'Detail' && dialogVisible" :info="rowData" @close="toggleVisible" />
|
||||
</com-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ExampleDialog">
|
||||
import { getExampleListApi, delsExampApi } from './api'
|
||||
import { useWork } from '@/hooks/work/useWork'
|
||||
import InfoWrite from './components/InfoWrite.vue'
|
||||
import Detail from './components/Detail.vue'
|
||||
const {
|
||||
defaultParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
dialogVisible,
|
||||
dialogTitle,
|
||||
comName,
|
||||
rowData,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
toggleVisible,
|
||||
getList,
|
||||
searchSubmit,
|
||||
resetSubmit,
|
||||
open,
|
||||
refreshTable,
|
||||
dels
|
||||
} = useWork({
|
||||
listFun: getExampleListApi,
|
||||
delFun: delsExampApi
|
||||
})
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '标题',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'title',
|
||||
placeholder: '请输入标题',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'title',
|
||||
label: '标题',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: '作者'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: '重要性',
|
||||
slots: {
|
||||
default: 'importance'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: '阅读数'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '220px',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
getList()
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
import fetch from '@/axios-config'
|
||||
|
||||
export const getExampleListApi = ({ params }: any) => {
|
||||
return fetch({ url: '/example/list2', method: 'get', params })
|
||||
}
|
||||
|
||||
export const delsExampApi = ({ data }: any) => {
|
||||
return fetch({ url: '/example/delete', method: 'post', data })
|
||||
}
|
||||
|
||||
export const setExampApi = ({ data }: any) => {
|
||||
return fetch({ url: '/example/save', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getExampDetApi = ({ params }: any) => {
|
||||
return fetch({ url: '/example/detail', method: 'get', params })
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<com-detail :data="form" :schema="fromSchema" :collapsed="false" title="文章详情">
|
||||
<template #contentContent="scope">
|
||||
<div v-html="scope.row.content"></div>
|
||||
</template>
|
||||
</com-detail>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Detail">
|
||||
import { PropType, reactive } from 'vue'
|
||||
import { getExampDetApi } from '../api'
|
||||
import { useRouter } from 'vue-router'
|
||||
const { push } = useRouter()
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String as PropType<string>,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const fromSchema = [
|
||||
{
|
||||
field: 'title',
|
||||
label: '标题',
|
||||
span: 24
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: '作者'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: '重要性'
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: '阅读数'
|
||||
},
|
||||
{
|
||||
field: 'content',
|
||||
label: '内容',
|
||||
span: 24,
|
||||
slots: {
|
||||
default: 'content'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
author: '', // 作者
|
||||
title: '', // 标题
|
||||
content: '', // 内容
|
||||
importance: '', // 重要性
|
||||
display_time: '', // 创建时间
|
||||
pageviews: 0 // 阅读数
|
||||
})
|
||||
|
||||
async function getDet() {
|
||||
if (props.id) {
|
||||
const id = props.id
|
||||
try {
|
||||
const res: any = await getExampDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
for (const key in form) {
|
||||
if (key === 'importance') {
|
||||
form[key] = (res.data[key] as number).toString()
|
||||
} else {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
push('/example-demo/example-page')
|
||||
}
|
||||
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,160 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="title" label="标题">
|
||||
<el-input v-model="form.title" placeholder="请输入标题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="author" label="作者">
|
||||
<el-input v-model="form.author" placeholder="请输入作者" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="display_time" label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="form.display_time"
|
||||
type="datetime"
|
||||
placeholder="请选择创建时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="importance" label="重要性">
|
||||
<el-select v-model="form.importance" placeholder="请选择重要性" style="width: 100%">
|
||||
<el-option label="重要" value="3" />
|
||||
<el-option label="良好" value="2" />
|
||||
<el-option label="一般" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="pageviews" label="阅读数">
|
||||
<el-input-number
|
||||
v-model="form.pageviews"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="content" label="内容">
|
||||
<editor ref="editorRef" :value="form.content" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="InfoWrite">
|
||||
import { PropType, ref, reactive } from 'vue'
|
||||
import { setExampApi, getExampDetApi } from '../api'
|
||||
import Editor from '_c/Editor/index.vue'
|
||||
import { Message } from '_c/Message'
|
||||
import { useRouter } from 'vue-router'
|
||||
const { push } = useRouter()
|
||||
|
||||
const requiredRule: {
|
||||
required: boolean
|
||||
message: string
|
||||
} = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String as PropType<string>,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
const editorRef = ref<Nullable<HTMLElement>>(null)
|
||||
const formRef = ref<Nullable<HTMLElement>>(null)
|
||||
|
||||
const subLoading = ref<boolean>(false)
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
author: '', // 作者
|
||||
title: '', // 标题
|
||||
content: '', // 内容
|
||||
importance: '', // 重要性
|
||||
display_time: '', // 创建时间
|
||||
pageviews: 0 // 阅读数
|
||||
})
|
||||
const rules = reactive<IObj>({
|
||||
title: [requiredRule],
|
||||
author: [requiredRule],
|
||||
content: [requiredRule],
|
||||
importance: [requiredRule],
|
||||
display_time: [requiredRule],
|
||||
pageviews: [requiredRule]
|
||||
})
|
||||
|
||||
async function getDet() {
|
||||
if (props.id) {
|
||||
const id = props.id
|
||||
try {
|
||||
const res: any = await getExampDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
for (const key in form) {
|
||||
if (key === 'importance') {
|
||||
form[key] = (res.data[key] as number).toString()
|
||||
} else {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增或者编辑
|
||||
function setListData() {
|
||||
try {
|
||||
subLoading.value = true
|
||||
form.content = (editorRef.value as any).getHtml()
|
||||
;(formRef.value as any).validate(async (valid) => {
|
||||
if (valid) {
|
||||
const res = await setExampApi({
|
||||
data: form
|
||||
})
|
||||
if (res) {
|
||||
Message.success(form.id ? '编辑成功' : '新增成功')
|
||||
emit('success', form.id ? 'edit' : 'add')
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
push('/example-demo/example-page')
|
||||
}
|
||||
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
export interface InfoWriteParams {
|
||||
title: string
|
||||
id?: string
|
||||
author: string
|
||||
content: string
|
||||
importance: string
|
||||
display_time: string
|
||||
pageviews: number
|
||||
}
|
||||
|
||||
export interface InfoWriteRules {
|
||||
title?: any[]
|
||||
author?: any[]
|
||||
content?: any[]
|
||||
importance?: any[]
|
||||
display_time?: any[]
|
||||
pageviews?: any[]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<template>
|
||||
<info-write @success="success" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ExampleAdd">
|
||||
import InfoWrite from './components/InfoWrite.vue'
|
||||
import bus from '@/vue-bus'
|
||||
function success(type: string) {
|
||||
bus.$emit('success', type)
|
||||
}
|
||||
</script>
|
||||
@@ -1,10 +0,0 @@
|
||||
<template>
|
||||
<detail :id="id" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ExampleDetail">
|
||||
import Detail from './components/Detail.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
const { query } = useRoute()
|
||||
const id = query.id as string
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<info-write :id="id" @success="success" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import InfoWrite from './components/InfoWrite.vue'
|
||||
import bus from '@/vue-bus'
|
||||
import { useRoute } from 'vue-router'
|
||||
const { query } = useRoute()
|
||||
const id = query.id as string
|
||||
|
||||
// 成功之后的回调
|
||||
function success(type: string) {
|
||||
// 由于使用的是页面跳转,所以只能通过vueBus去进行通信
|
||||
bus.$emit('success', type)
|
||||
}
|
||||
</script>
|
||||
@@ -1,139 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="search__example--wrap">
|
||||
<com-search :data="searchData" @search-submit="searchSubmit" @reset-submit="resetSubmit" />
|
||||
</div>
|
||||
|
||||
<div class="button__example--wrap">
|
||||
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="open(null)">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" @click="dels">删除</el-button>
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
selection
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defaultParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<template #importance="scope">
|
||||
<el-tag
|
||||
:type="
|
||||
scope.row.importance === 3
|
||||
? 'success'
|
||||
: scope.row.importance === 2
|
||||
? 'warning'
|
||||
: 'danger'
|
||||
"
|
||||
>
|
||||
{{ scope.row.importance === 3 ? '重要' : scope.row.importance === 2 ? '良好' : '一般' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #action="scope">
|
||||
<el-button type="primary" size="mini" @click="open(scope.row)">编辑</el-button>
|
||||
<el-button type="success" size="mini" @click="open(scope.row, 'Detail')">查看</el-button>
|
||||
<el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ExampleDialog">
|
||||
import { onBeforeUnmount } from 'vue'
|
||||
import { getExampleListApi, delsExampApi } from './api'
|
||||
import { useWork } from '@/hooks/work/useWork'
|
||||
import { useRouter } from 'vue-router'
|
||||
const { push } = useRouter()
|
||||
import bus from '@/vue-bus'
|
||||
const {
|
||||
defaultParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
handleSelectionChange,
|
||||
getList,
|
||||
searchSubmit,
|
||||
resetSubmit,
|
||||
refreshTable,
|
||||
dels
|
||||
} = useWork({
|
||||
listFun: getExampleListApi,
|
||||
delFun: delsExampApi
|
||||
})
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '标题',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'title',
|
||||
placeholder: '请输入标题',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'title',
|
||||
label: '标题',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: '作者'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: '重要性',
|
||||
slots: {
|
||||
default: 'importance'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: '阅读数'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '220px',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function open(row: Nullable<IObj>, component?: string) {
|
||||
push(
|
||||
!row
|
||||
? `/example-demo/example-add`
|
||||
: component
|
||||
? `/example-demo/example-detail?id=${row.id}`
|
||||
: `/example-demo/example-edit?id=${row.id}`
|
||||
)
|
||||
}
|
||||
|
||||
getList()
|
||||
|
||||
bus.$on('success', (type: string) => {
|
||||
refreshTable(type)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
bus.$off('success')
|
||||
})
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title=" 引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。引导页基于 intro.js"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-button type="primary" @click.prevent.stop="guide"> 开始引导 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Guide">
|
||||
import { onMounted } from 'vue'
|
||||
import { useIntro } from '@/hooks/web/useIntro'
|
||||
const { intro } = useIntro()
|
||||
import steps from './steps'
|
||||
|
||||
function guide() {
|
||||
intro.start()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
intro.addSteps(steps as any[]).setOptions({
|
||||
prevLabel: '上一步',
|
||||
nextLabel: '下一步',
|
||||
skipLabel: '跳过',
|
||||
doneLabel: '结束'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -1,40 +0,0 @@
|
||||
const steps = [
|
||||
{
|
||||
element: '#sidebar__wrap',
|
||||
title: '菜单栏',
|
||||
intro: '以路由的结构渲染的菜单栏',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
element: '#hamburger-container',
|
||||
title: '展开缩收',
|
||||
intro: '用于展开和缩放菜单栏',
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
element: '#breadcrumb-container',
|
||||
title: '面包屑',
|
||||
intro: '用于记录当前路由结构',
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
element: '#screenfull-container',
|
||||
title: '是否全屏',
|
||||
intro: '用于设置是否全屏',
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
element: '#user-container',
|
||||
title: '用户信息',
|
||||
intro: '用于展示用户',
|
||||
position: 'bottom'
|
||||
},
|
||||
{
|
||||
element: '#tag-container',
|
||||
title: '标签页',
|
||||
intro: '用于记录路由历史记录',
|
||||
position: 'bottom'
|
||||
}
|
||||
]
|
||||
|
||||
export default steps
|
||||
@@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<div class="icons-container">
|
||||
<div v-for="item of svgIcons" :key="item" v-clipboard="generateIconCode(item)">
|
||||
<el-tooltip placement="top" :content="generateIconCode(item)">
|
||||
<div class="icon-item">
|
||||
<svg-icon :icon-class="item" class-name="disabled" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import svgIcons from './svg-icons'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
// name: 'Icons',
|
||||
setup() {
|
||||
function generateIconCode(symbol: string) {
|
||||
return `<svg-icon icon-class="${symbol}" />`
|
||||
}
|
||||
return {
|
||||
svgIcons,
|
||||
generateIconCode
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.icons-container {
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
|
||||
.icon-item {
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 85px;
|
||||
margin: 20px;
|
||||
font-size: 30px;
|
||||
color: #24292e;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +0,0 @@
|
||||
const modules = import.meta.glob('../../assets/icons/*.svg')
|
||||
|
||||
const svgIcons: string[] = []
|
||||
|
||||
for (const key in modules) {
|
||||
svgIcons.push(key.split('../../assets/icons/')[1].split('.')[0])
|
||||
}
|
||||
|
||||
export default svgIcons
|
||||
@@ -1,9 +0,0 @@
|
||||
import fetch from '@/axios-config'
|
||||
|
||||
export const loginApi = ({ data }: FetchConfig) => {
|
||||
return fetch({ url: '/user/login', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getRoleDetApi = ({ params }: FetchConfig) => {
|
||||
return fetch({ url: '/role/detail', method: 'get', params })
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
|
||||
import { usePermissionStore } from '@/store/modules/permission'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { loginApi, getRoleDetApi } from './api'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const { wsCache } = useCache()
|
||||
|
||||
@@ -50,25 +49,14 @@ export default defineComponent({
|
||||
try {
|
||||
loading.value = true
|
||||
// 模拟登录接口之后返回角色信息
|
||||
const res: IObj = await loginApi({ data: form })
|
||||
if (res) {
|
||||
// 获取权限信息
|
||||
const role = await getRoleDetApi({
|
||||
params: {
|
||||
id: res.data.roleId
|
||||
}
|
||||
wsCache.set(appStore.getUserInfo, form)
|
||||
permissionStore.generateRoutes().then(() => {
|
||||
permissionStore.getAddRouters.forEach(async (route) => {
|
||||
await addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||
})
|
||||
if (role) {
|
||||
wsCache.set(appStore.getUserInfo, Object.assign(form, role.data))
|
||||
permissionStore.generateRoutes().then(() => {
|
||||
permissionStore.getAddRouters.forEach(async (route) => {
|
||||
await addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||
})
|
||||
permissionStore.setIsAddRouters(true)
|
||||
push({ path: redirect.value || '/' })
|
||||
})
|
||||
}
|
||||
}
|
||||
permissionStore.setIsAddRouters(true)
|
||||
push({ path: redirect.value || '/' })
|
||||
})
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import fetch from '@/axios-config'
|
||||
|
||||
export const getRoleListApi = ({ params }: any) => {
|
||||
return fetch({ url: '/role/list', method: 'get', params })
|
||||
}
|
||||
|
||||
export const setRoleApi = ({ data }: any) => {
|
||||
return fetch({ url: '/role/save', method: 'post', data })
|
||||
}
|
||||
|
||||
export const getRoleDetApi = ({ params }: any) => {
|
||||
return fetch({ url: '/role/detail', method: 'get', params })
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="roleName" label="角色名">
|
||||
<el-input v-model="form.roleName" disabled placeholder="请输入角色名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="角色权限">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:check-strictly="false"
|
||||
:data="routesData as any"
|
||||
:props="defaultProps as any"
|
||||
show-checkbox
|
||||
accordion
|
||||
node-key="path"
|
||||
highlight-current
|
||||
class="permission-tree"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="InfoWrite">
|
||||
import { PropType, computed, nextTick, reactive, ref } from 'vue'
|
||||
import path from 'path-browserify'
|
||||
import { setRoleApi, getRoleDetApi } from '../api'
|
||||
import { asyncRouterMap } from '@/router'
|
||||
import { isExternal } from '@/utils/validate'
|
||||
import { Message } from '_c/Message'
|
||||
import { AppRouteRecordRaw } from '@/router/types'
|
||||
|
||||
const requiredRule: {
|
||||
required: boolean
|
||||
message: string
|
||||
} = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object as PropType<Nullable<IObj>>,
|
||||
default: () => null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
|
||||
const tree = ref<Nullable<HTMLElement>>(null)
|
||||
const formRef = ref<Nullable<HTMLElement>>(null)
|
||||
const subLoading = ref<boolean>(false)
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
roleName: '', // 角色名
|
||||
checkedNodes: [], // 被选中的节点
|
||||
checkedkeys: [] // 被选中的keys
|
||||
})
|
||||
const rules = reactive<IObj>({
|
||||
roleName: [requiredRule]
|
||||
})
|
||||
const routes = ref<IObj>([])
|
||||
const defaultProps = reactive<IObj>({
|
||||
children: 'children',
|
||||
label: 'title'
|
||||
})
|
||||
|
||||
const routesData = computed(() => routes.value)
|
||||
|
||||
async function getDet() {
|
||||
if (props.info) {
|
||||
const id = props.info.id
|
||||
try {
|
||||
const res: any = await getRoleDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
for (const key in form) {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
nextTick(() => {
|
||||
;(tree.value as any).setCheckedKeys(form.checkedkeys)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增或者编辑
|
||||
function setListData() {
|
||||
try {
|
||||
subLoading.value = true
|
||||
;(formRef.value as any).validate(async (valid) => {
|
||||
if (valid) {
|
||||
// 获取所有被选中节点,由于是前端渲染,所以只要保存一维数组就行
|
||||
form.checkedNodes = (tree.value as any).getCheckedNodes(false, true)
|
||||
console.log(JSON.stringify(form.checkedNodes))
|
||||
// 获取所有被选中的keys,便于渲染是否选中
|
||||
form.checkedkeys = (tree.value as any).getCheckedKeys()
|
||||
console.log(JSON.stringify(form.checkedkeys))
|
||||
const res = await setRoleApi({
|
||||
data: form
|
||||
})
|
||||
if (res) {
|
||||
Message.success(
|
||||
form.id ? '编辑成功,请重新退出登录后查看效果' : '新增成功,请重新退出登录后查看效果'
|
||||
)
|
||||
emit('success', form.id ? 'edit' : 'add')
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function generateRoutes(routes: AppRouteRecordRaw[], basePath = '/') {
|
||||
const res: AppRouteRecordRaw[] = []
|
||||
|
||||
for (let route of routes) {
|
||||
// skip some route
|
||||
if (route.meta && route.meta.hidden) {
|
||||
continue
|
||||
}
|
||||
|
||||
const onlyOneShowingChild = onlyOneShowingChildFn(
|
||||
route.children,
|
||||
route,
|
||||
path.resolve(basePath, route.path)
|
||||
)
|
||||
|
||||
if (route.children && onlyOneShowingChild && !(route.meta && route.meta.alwaysShow)) {
|
||||
route = onlyOneShowingChild
|
||||
}
|
||||
|
||||
const data = {
|
||||
path: isExternal(route.path) ? route.path : path.resolve(basePath, route.path),
|
||||
title: route.meta && route.meta.title,
|
||||
name: route.name
|
||||
}
|
||||
// recursive child routes
|
||||
if (route.children) {
|
||||
;(data as any).children = generateRoutes(route.children, data.path)
|
||||
}
|
||||
res.push(data as any)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function onlyOneShowingChildFn(
|
||||
children: AppRouteRecordRaw[] = [],
|
||||
parent: AppRouteRecordRaw,
|
||||
basePath: string
|
||||
) {
|
||||
let onlyOneChild: Nullable<AppRouteRecordRaw | any> = null
|
||||
const showingChildren = children.filter((item) => !(item.meta && item.meta.hidden))
|
||||
// When there is only one child route, the child route is displayed by default
|
||||
if (showingChildren.length === 1) {
|
||||
onlyOneChild = showingChildren[0]
|
||||
onlyOneChild.path = isExternal(onlyOneChild.path)
|
||||
? onlyOneChild.path
|
||||
: path.resolve(basePath, onlyOneChild.path)
|
||||
return onlyOneChild
|
||||
}
|
||||
|
||||
// Show parent if there are no child route to display
|
||||
if (showingChildren.length === 0) {
|
||||
onlyOneChild = { ...parent, path: '', noShowingChildren: true }
|
||||
return onlyOneChild
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const oldRoutes = [...asyncRouterMap]
|
||||
routes.value = generateRoutes(oldRoutes)
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,225 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="130px">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="roleName" label="角色名">
|
||||
<el-input v-model="form.roleName" disabled placeholder="请输入角色名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色权限">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:check-strictly="false"
|
||||
:expand-on-click-node="false"
|
||||
:data="routesData as any"
|
||||
:props="defaultProps as any"
|
||||
accordion
|
||||
node-key="path"
|
||||
highlight-current
|
||||
class="permission-tree"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="seletTreeData" :span="12">
|
||||
<el-form-item label="title">
|
||||
<el-input v-model="seletTreeData.title" />
|
||||
</el-form-item>
|
||||
<el-form-item label="component">
|
||||
<el-input v-model="seletTreeData.component" />
|
||||
</el-form-item>
|
||||
<el-form-item label="redirect">
|
||||
<el-input v-model="seletTreeData.redirect" />
|
||||
</el-form-item>
|
||||
<el-form-item label="activeMenu">
|
||||
<el-input v-model="seletTreeData.meta.activeMenu" />
|
||||
</el-form-item>
|
||||
<el-form-item label="name">
|
||||
<el-input v-model="seletTreeData.name" />
|
||||
</el-form-item>
|
||||
<el-form-item label="icon">
|
||||
<el-input v-model="seletTreeData.meta.icon" />
|
||||
</el-form-item>
|
||||
<el-form-item label="hidden">
|
||||
<el-switch v-model="seletTreeData.meta.hidden" />
|
||||
</el-form-item>
|
||||
<el-form-item label="alwaysShow">
|
||||
<el-switch v-model="seletTreeData.meta.alwaysShow" />
|
||||
</el-form-item>
|
||||
<el-form-item label="noCache">
|
||||
<el-switch v-model="seletTreeData.meta.noCache" />
|
||||
</el-form-item>
|
||||
<el-form-item label="breadcrumb">
|
||||
<el-switch v-model="seletTreeData.meta.breadcrumb" />
|
||||
</el-form-item>
|
||||
<el-form-item label="affix">
|
||||
<el-switch v-model="seletTreeData.meta.affix" />
|
||||
</el-form-item>
|
||||
<el-form-item label="noTagsView">
|
||||
<el-switch v-model="seletTreeData.meta.noTagsView" />
|
||||
</el-form-item>
|
||||
<el-form-item label="showMainRoute">
|
||||
<el-switch v-model="seletTreeData.meta.showMainRoute" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div class="dialong__button--wrap">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="InfoWrite2">
|
||||
import { PropType, computed, nextTick, reactive, ref } from 'vue'
|
||||
import { setRoleApi, getRoleDetApi } from '../api'
|
||||
import { Message } from '_c/Message'
|
||||
import { AppRouteRecordRaw } from '@/router/types'
|
||||
|
||||
const requiredRule: {
|
||||
required: boolean
|
||||
message: string
|
||||
} = {
|
||||
required: true,
|
||||
message: '该项为必填项'
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object as PropType<Nullable<IObj>>,
|
||||
default: () => null
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
|
||||
const tree = ref<Nullable<HTMLElement>>(null)
|
||||
const formRef = ref<Nullable<HTMLElement>>(null)
|
||||
const subLoading = ref<boolean>(false)
|
||||
const form = reactive<IObj>({
|
||||
id: '', // id
|
||||
roleName: '', // 角色名
|
||||
checkedNodes: [], // 被选中的节点
|
||||
checkedkeys: [] // 被选中的keys
|
||||
})
|
||||
const rules = reactive<IObj>({
|
||||
roleName: [requiredRule]
|
||||
})
|
||||
const routes = ref<IObj>([])
|
||||
const defaultProps = reactive<IObj>({
|
||||
children: 'children',
|
||||
label: 'title'
|
||||
})
|
||||
const seletTreeData = ref<Nullable<IObj>>(null)
|
||||
const routesData = computed(() => routes.value)
|
||||
|
||||
async function getDet() {
|
||||
if (props.info) {
|
||||
const id = props.info.id
|
||||
try {
|
||||
const res: any = await getRoleDetApi({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
if (res) {
|
||||
console.log(res)
|
||||
for (const key in form) {
|
||||
form[key] = res.data[key]
|
||||
}
|
||||
routes.value = generateRoutes(form.checkedNodes)
|
||||
nextTick(() => {
|
||||
;(tree.value as any).setCheckedKeys(form.checkedkeys)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 树形点击
|
||||
function handleNodeClick(data: IObj) {
|
||||
seletTreeData.value = data
|
||||
}
|
||||
|
||||
// 新增或者编辑
|
||||
function setListData() {
|
||||
try {
|
||||
subLoading.value = true
|
||||
;(formRef.value as any).validate(async (valid) => {
|
||||
if (valid) {
|
||||
console.log(routesData.value)
|
||||
// 获取所有被选中节点
|
||||
// const checkedNodes = this.$refs.tree.getCheckedNodes(false, true).filter(v => {
|
||||
// if (v.path.includes('/')) return v
|
||||
// })
|
||||
// // 获取所有被选中的keys,便于渲染是否选中
|
||||
// this.form.checkedkeys = this.$refs.tree.getCheckedKeys()
|
||||
// console.log(JSON.stringify(this.form.checkedkeys))
|
||||
|
||||
// this.form.checkedNodes = this.getFilterNodes(checkedNodes)
|
||||
// console.log(JSON.stringify(this.form.checkedNodes))
|
||||
const res = await setRoleApi({
|
||||
data: Object.assign(form, { checkedNodes: routesData.value })
|
||||
})
|
||||
if (res) {
|
||||
Message.success(
|
||||
form.id ? '编辑成功,请重新退出登录后查看效果' : '新增成功,请重新退出登录后查看效果'
|
||||
)
|
||||
emit('success', form.id ? 'edit' : 'add')
|
||||
}
|
||||
} else {
|
||||
console.log('error submit!!')
|
||||
return false
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
} finally {
|
||||
subLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 树形渲染过滤
|
||||
function generateRoutes(routes: AppRouteRecordRaw[]) {
|
||||
const res: AppRouteRecordRaw[] = []
|
||||
|
||||
for (const route of routes) {
|
||||
const data: AppRouteRecordRaw = {
|
||||
path: route.path,
|
||||
name: route.name,
|
||||
redirect: route.redirect || '',
|
||||
title: (route as any).title || (route.meta && route.meta.title),
|
||||
component: (route as any).component || '',
|
||||
meta: {
|
||||
title: (route as any).title || (route.meta && route.meta.title),
|
||||
alwaysShow: route.meta && route.meta.alwaysShow,
|
||||
hidden: route.meta && route.meta.hidden,
|
||||
icon: route.meta && route.meta.icon,
|
||||
noCache: route.meta && route.meta.noCache,
|
||||
breadcrumb: route.meta && route.meta.breadcrumb,
|
||||
affix: route.meta && route.meta.affix,
|
||||
noTagsView: route.meta && route.meta.noTagsView,
|
||||
activeMenu: route.meta && route.meta.activeMenu,
|
||||
showMainRoute: route.meta && route.meta.showMainRoute
|
||||
}
|
||||
}
|
||||
// recursive child routes
|
||||
if (route.children) {
|
||||
data.children = generateRoutes(route.children)
|
||||
}
|
||||
res.push(data)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
getDet()
|
||||
</script>
|
||||
@@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="由于是模拟数据,所以只提供了两种不同权限的角色,开发者可根据实际情况自行改造结合。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<div class="search__example--wrap">
|
||||
<com-search :data="searchData" @search-submit="searchSubmit" @reset-submit="resetSubmit" />
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defaultParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
>
|
||||
<template #remark="scope">
|
||||
<span>模拟</span>
|
||||
<el-tag
|
||||
:type="scope.row.roleName === 'admin' ? 'success' : 'warning'"
|
||||
style="margin: 0 15px"
|
||||
>
|
||||
{{ scope.row.roleName === 'admin' ? '前端' : '后端' }}
|
||||
</el-tag>
|
||||
<span>角色</span>
|
||||
</template>
|
||||
|
||||
<template #action="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="open(scope.row, scope.row.roleName === 'admin' ? 'InfoWrite' : 'InfoWrite2')"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
|
||||
<com-dialog v-model="dialogVisible" :title="dialogTitle">
|
||||
<info-write
|
||||
v-if="comName === 'InfoWrite' && dialogVisible"
|
||||
:info="rowData"
|
||||
@close="toggleVisible"
|
||||
@success="refreshTable"
|
||||
/>
|
||||
<info-write2
|
||||
v-if="comName === 'InfoWrite2' && dialogVisible"
|
||||
:info="rowData"
|
||||
@close="toggleVisible"
|
||||
@success="refreshTable"
|
||||
/>
|
||||
</com-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Role">
|
||||
import { getRoleListApi } from './api'
|
||||
import { useWork } from '@/hooks/work/useWork'
|
||||
import InfoWrite from './components/InfoWrite.vue'
|
||||
import InfoWrite2 from './components/InfoWrite2.vue'
|
||||
const {
|
||||
defaultParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
dialogVisible,
|
||||
dialogTitle,
|
||||
comName,
|
||||
rowData,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
toggleVisible,
|
||||
getList,
|
||||
searchSubmit,
|
||||
resetSubmit,
|
||||
open,
|
||||
refreshTable
|
||||
} = useWork({
|
||||
listFun: getRoleListApi
|
||||
})
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '角色名',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'roleName',
|
||||
placeholder: '请输入角色名',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'roleName',
|
||||
label: '角色名'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
slots: {
|
||||
default: 'remark'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '80px',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
getList()
|
||||
</script>
|
||||
@@ -1,5 +0,0 @@
|
||||
import fetch from '@/axios-config'
|
||||
|
||||
export const getUserListApi = ({ params }: any) => {
|
||||
return fetch({ url: '/user/list', method: 'get', params })
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="由于是模拟数据,所以只提供了两种不同权限的帐号,开发者可根据实际情况自行改造结合。"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
|
||||
<div class="search__example--wrap">
|
||||
<com-search :data="searchData" @search-submit="searchSubmit" @reset-submit="resetSubmit" />
|
||||
</div>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: defaultParams.pageIndex,
|
||||
total: total,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
>
|
||||
<template #remark="scope">
|
||||
<span>模拟</span>
|
||||
<el-tag
|
||||
:type="scope.row.userName === 'admin' ? 'success' : 'warning'"
|
||||
style="margin: 0 15px"
|
||||
>
|
||||
{{ scope.row.userName === 'admin' ? '前端' : '后端' }}
|
||||
</el-tag>
|
||||
<span>控制路由权限</span>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="User">
|
||||
import { getUserListApi } from './api'
|
||||
import { useWork } from '@/hooks/work/useWork'
|
||||
const {
|
||||
defaultParams,
|
||||
tableData,
|
||||
loading,
|
||||
total,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
getList,
|
||||
searchSubmit,
|
||||
resetSubmit
|
||||
} = useWork({
|
||||
listFun: getUserListApi
|
||||
})
|
||||
|
||||
const searchData = [
|
||||
{
|
||||
label: '帐号',
|
||||
value: '',
|
||||
itemType: 'input',
|
||||
field: 'userName',
|
||||
placeholder: '请输入帐号',
|
||||
clearable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'userName',
|
||||
label: '帐号'
|
||||
},
|
||||
{
|
||||
field: 'password',
|
||||
label: '密码'
|
||||
},
|
||||
{
|
||||
field: 'role',
|
||||
label: '角色'
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
slots: {
|
||||
default: 'remark'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
getList()
|
||||
</script>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 基础表格"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="BasicTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 带边框表格"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" border />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="BorderTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,91 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 自定义表头"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="
|
||||
tableData.filter(
|
||||
(data) => !search || data.name.toLowerCase().includes(search.toLowerCase())
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #actionHeader>
|
||||
<el-input v-model="search" size="mini" placeholder="输入关键字搜索" />
|
||||
</template>
|
||||
<template #action="scope">
|
||||
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
|
||||
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">
|
||||
Delete
|
||||
</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CustomHeader">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
slots: {
|
||||
header: 'actionHeader',
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎1',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎2',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎3',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎4',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
const search = ref<string>('')
|
||||
|
||||
function handleEdit(index: number, row: any) {
|
||||
console.log(index, row)
|
||||
}
|
||||
function handleDelete(index: number, row: any) {
|
||||
console.log(index, row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,68 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 自定义索引"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CustomIndex">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
const columns = ref<any[]>([
|
||||
{
|
||||
field: 'index',
|
||||
type: 'index',
|
||||
index: (index: number) => {
|
||||
return index * 2
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,125 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 展开行"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table ref="multipleTable" v-loading="loading" :columns="columns" :data="tableData">
|
||||
<template #id="scope">
|
||||
<el-form label-position="left" inline class="demo-table-expand">
|
||||
<el-form-item label="商品名称">
|
||||
<span>{{ scope.row.name }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属店铺">
|
||||
<span>{{ scope.row.shop }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品 ID">
|
||||
<span>{{ scope.row.id }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺 ID">
|
||||
<span>{{ scope.row.shopId }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分类">
|
||||
<span>{{ scope.row.category }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺地址">
|
||||
<span>{{ scope.row.address }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述">
|
||||
<span>{{ scope.row.desc }}</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ExpandRow">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'id',
|
||||
type: 'expand',
|
||||
slots: {
|
||||
default: 'id'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
label: '商品ID'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '商品名称'
|
||||
},
|
||||
{
|
||||
field: 'desc',
|
||||
label: '描述'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: '12987122',
|
||||
name: '好滋好味鸡蛋仔',
|
||||
category: '江浙小吃、小吃零食',
|
||||
desc: '荷兰优质淡奶,奶香浓而不腻',
|
||||
address: '上海市普陀区真北路',
|
||||
shop: '王小虎夫妻店',
|
||||
shopId: '10333'
|
||||
},
|
||||
{
|
||||
id: '12987123',
|
||||
name: '好滋好味鸡蛋仔',
|
||||
category: '江浙小吃、小吃零食',
|
||||
desc: '荷兰优质淡奶,奶香浓而不腻',
|
||||
address: '上海市普陀区真北路',
|
||||
shop: '王小虎夫妻店',
|
||||
shopId: '10333'
|
||||
},
|
||||
{
|
||||
id: '12987125',
|
||||
name: '好滋好味鸡蛋仔',
|
||||
category: '江浙小吃、小吃零食',
|
||||
desc: '荷兰优质淡奶,奶香浓而不腻',
|
||||
address: '上海市普陀区真北路',
|
||||
shop: '王小虎夫妻店',
|
||||
shopId: '10333'
|
||||
},
|
||||
{
|
||||
id: '12987126',
|
||||
name: '好滋好味鸡蛋仔',
|
||||
category: '江浙小吃、小吃零食',
|
||||
desc: '荷兰优质淡奶,奶香浓而不腻',
|
||||
address: '上海市普陀区真北路',
|
||||
shop: '王小虎夫妻店',
|
||||
shopId: '10333'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.demo-table-expand) {
|
||||
font-size: 0;
|
||||
|
||||
label {
|
||||
width: 90px;
|
||||
color: #99a9bf;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
width: 50%;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 固定列和表头"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
border
|
||||
height="250"
|
||||
style="width: 820px"
|
||||
>
|
||||
<template #action="scope">
|
||||
<el-button type="text" size="small" @click="handleClick(scope.row)">查看</el-button>
|
||||
<el-button type="text" size="small">编辑</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="FixedColumnHeader">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
fixed: true,
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'province',
|
||||
label: '省份',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
label: '市区',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址',
|
||||
width: '300'
|
||||
},
|
||||
{
|
||||
field: 'zip',
|
||||
label: '邮编',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '100',
|
||||
fixed: 'right',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
zip: 200333
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function handleClick(row: any) {
|
||||
console.log(row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 固定列"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" border style="width: 820px">
|
||||
<template #action="scope">
|
||||
<el-button type="text" size="small" @click="handleClick(scope.row)">查看</el-button>
|
||||
<el-button type="text" size="small">编辑</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="FixedColumn">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
fixed: true,
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'province',
|
||||
label: '省份',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
label: '市区',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址',
|
||||
width: '300'
|
||||
},
|
||||
{
|
||||
field: 'zip',
|
||||
label: '邮编',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '100',
|
||||
fixed: 'right',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
zip: 200333
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function handleClick(row: any) {
|
||||
console.log(row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 固定表头"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" height="250" border />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="FixedHeader">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 流体高度"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
border
|
||||
max-height="250"
|
||||
style="width: 820px"
|
||||
>
|
||||
<template #action="scope">
|
||||
<el-button type="text" size="small" @click="deleteRow(scope.$index)">移除</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="FluidHeight">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
fixed: true,
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'province',
|
||||
label: '省份',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
label: '市区',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址',
|
||||
width: '300'
|
||||
},
|
||||
{
|
||||
field: 'zip',
|
||||
label: '邮编',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '100',
|
||||
fixed: 'right',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
const tableData = ref<IObj[]>([
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
zip: 200333
|
||||
}
|
||||
])
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function deleteRow(index: number) {
|
||||
tableData.value.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 合并行或列"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:span-method="arraySpanMethod"
|
||||
border
|
||||
/>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns1"
|
||||
:data="tableData"
|
||||
:span-method="objectSpanMethod"
|
||||
border
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MergeTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'ID'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'amount1',
|
||||
label: '数值1',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'amount2',
|
||||
label: '数值2',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'amount3',
|
||||
label: '数值4',
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns1 = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'ID'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'amount1',
|
||||
label: '数值1(元)'
|
||||
},
|
||||
{
|
||||
field: 'amount2',
|
||||
label: '数值2(元)'
|
||||
},
|
||||
{
|
||||
field: 'amount3',
|
||||
label: '数值4(元)'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: '12987122',
|
||||
name: '王小虎',
|
||||
amount1: '234',
|
||||
amount2: '3.2',
|
||||
amount3: 10
|
||||
},
|
||||
{
|
||||
id: '12987123',
|
||||
name: '王小虎',
|
||||
amount1: '165',
|
||||
amount2: '4.43',
|
||||
amount3: 12
|
||||
},
|
||||
{
|
||||
id: '12987124',
|
||||
name: '王小虎',
|
||||
amount1: '324',
|
||||
amount2: '1.9',
|
||||
amount3: 9
|
||||
},
|
||||
{
|
||||
id: '12987125',
|
||||
name: '王小虎',
|
||||
amount1: '621',
|
||||
amount2: '2.2',
|
||||
amount3: 17
|
||||
},
|
||||
{
|
||||
id: '12987126',
|
||||
name: '王小虎',
|
||||
amount1: '539',
|
||||
amount2: '4.1',
|
||||
amount3: 15
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function arraySpanMethod({ rowIndex, columnIndex }: any) {
|
||||
if (rowIndex % 2 === 0) {
|
||||
if (columnIndex === 0) {
|
||||
return [1, 2]
|
||||
} else if (columnIndex === 1) {
|
||||
return [0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function objectSpanMethod({ rowIndex, columnIndex }: any) {
|
||||
if (columnIndex === 0) {
|
||||
if (rowIndex % 2 === 0) {
|
||||
return {
|
||||
rowspan: 2,
|
||||
colspan: 1
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
rowspan: 0,
|
||||
colspan: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 多级表头"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData">
|
||||
<template #address="scope"> 地址是: {{ scope.row.address }} </template>
|
||||
<template #action="scope">
|
||||
<el-button type="text" size="small" @click="deleteRow(scope.$index)">移除</el-button>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MultiHeader">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
fixed: true,
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
label: '配送信息',
|
||||
children: [
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
label: '地址',
|
||||
children: [
|
||||
{
|
||||
field: 'province',
|
||||
label: '省份',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
label: '市区',
|
||||
width: '120'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址',
|
||||
slots: {
|
||||
default: 'address'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'zip',
|
||||
label: '邮编',
|
||||
width: '120'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: '操作',
|
||||
width: '100',
|
||||
slots: {
|
||||
default: 'action'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = ref<any[]>([
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-08',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-06',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
},
|
||||
{
|
||||
date: '2016-05-07',
|
||||
name: '王小虎',
|
||||
province: '上海',
|
||||
city: '普陀区',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
zip: 200333
|
||||
}
|
||||
])
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function deleteRow(index: number) {
|
||||
tableData.value.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 多选"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
ref="multipleTable"
|
||||
v-loading="loading"
|
||||
selection
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
@selection-change="handleSelectionChange"
|
||||
/>
|
||||
|
||||
<div style="margin-top: 20px">
|
||||
<el-button @click="toggleSelection([tableData[1], tableData[2]])">
|
||||
切换第二、第三行的选中状态
|
||||
</el-button>
|
||||
<el-button @click="toggleSelection()">取消选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="MultipleChoice">
|
||||
import { ref, unref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
const multipleTable = ref<HTMLElement | null>(null)
|
||||
function toggleSelection(rows?: any[]) {
|
||||
const multipleTableRef = unref(multipleTable as any).getTableRef()
|
||||
if (rows) {
|
||||
rows.forEach((row) => {
|
||||
multipleTableRef.toggleRowSelection(row)
|
||||
})
|
||||
} else {
|
||||
multipleTableRef.clearSelection()
|
||||
}
|
||||
}
|
||||
function handleSelectionChange(val: any) {
|
||||
console.log(val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,79 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 分页表格"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
currentPage: 1,
|
||||
total: 400,
|
||||
onSizeChange: handleSizeChange,
|
||||
onCurrentChange: handleCurrentChange
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PageTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function handleSizeChange(val: number) {
|
||||
console.log(val)
|
||||
}
|
||||
|
||||
function handleCurrentChange(val: number) {
|
||||
console.log(val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 筛选"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<el-button @click="resetDateFilter">清除日期过滤器</el-button>
|
||||
<el-button @click="clearFilter">清除所有过滤器</el-button>
|
||||
<com-table
|
||||
ref="filterTable"
|
||||
v-loading="loading"
|
||||
row-key="date"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:default-sort="{ prop: 'date', order: 'descending' }"
|
||||
>
|
||||
<template #tag="scope">
|
||||
<el-tag
|
||||
:type="(scope.row.tag === '家' ? 'primary' : 'success') as any"
|
||||
disable-transitions
|
||||
>{{ scope.row.tag }}</el-tag
|
||||
>
|
||||
</template>
|
||||
</com-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ScreenTable">
|
||||
import { ref, unref } from 'vue'
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄',
|
||||
tag: '家'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄',
|
||||
tag: '公司'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
tag: '家'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄',
|
||||
tag: '公司'
|
||||
}
|
||||
]
|
||||
|
||||
const filterTable = ref<HTMLElement | null>(null)
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
const columns = ref<any[]>([
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
sortable: true,
|
||||
width: '180',
|
||||
columnKey: 'date',
|
||||
filters: [
|
||||
{ text: '2016-05-01', value: '2016-05-01' },
|
||||
{ text: '2016-05-02', value: '2016-05-02' },
|
||||
{ text: '2016-05-03', value: '2016-05-03' },
|
||||
{ text: '2016-05-04', value: '2016-05-04' }
|
||||
],
|
||||
filterMethod: filterHandler
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
},
|
||||
{
|
||||
field: 'tag',
|
||||
label: '标签',
|
||||
filters: [
|
||||
{ text: '家', value: '家' },
|
||||
{ text: '公司', value: '公司' }
|
||||
],
|
||||
filterMethod: filterTag,
|
||||
filterPlacement: 'bottom-end',
|
||||
slots: {
|
||||
default: 'tag'
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
function resetDateFilter() {
|
||||
const filterTableRef = unref(filterTable as any).getTableRef()
|
||||
filterTableRef.clearFilter('date')
|
||||
}
|
||||
function clearFilter() {
|
||||
const filterTableRef = unref(filterTable as any).getTableRef()
|
||||
filterTableRef.clearFilter()
|
||||
}
|
||||
function filterTag(value: string, row: any) {
|
||||
return row.tag === value
|
||||
}
|
||||
function filterHandler(value: string, row: any, column: any) {
|
||||
const property = column['property']
|
||||
return row[property] === value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,82 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 单选"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
ref="singleTable"
|
||||
v-loading="loading"
|
||||
highlight-current-row
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
|
||||
<div style="margin-top: 20px">
|
||||
<el-button @click="setCurrent(tableData[1])">选中第二行</el-button>
|
||||
<el-button @click="setCurrent()">取消选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="SingleChoice">
|
||||
import { ref, unref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
const singleTable = ref<HTMLElement | null>(null)
|
||||
function setCurrent(row?: any) {
|
||||
const singleTableRef = unref(singleTable as any).getTableRef()
|
||||
singleTableRef.setCurrentRow(row)
|
||||
}
|
||||
function handleCurrentChange(val: any) {
|
||||
console.log(val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 排序"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
ref="multipleTable"
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:default-sort="{ prop: 'date', order: 'descending' }"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="SortTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 带状态表格"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:row-class-name="tableRowClassName"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StateTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function tableRowClassName({ rowIndex }: any) {
|
||||
if (rowIndex === 1) {
|
||||
return 'warning-row'
|
||||
} else if (rowIndex === 3) {
|
||||
return 'success-row'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.el-table) {
|
||||
.warning-row {
|
||||
background: oldlace;
|
||||
}
|
||||
|
||||
.success-row {
|
||||
background: #f0f9eb;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 带斑马纹表格"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" stripe />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StripeTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,148 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 表尾合计行"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table v-loading="loading" :columns="columns" :data="tableData" border show-summary />
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns1"
|
||||
:data="tableData"
|
||||
border
|
||||
height="200"
|
||||
:summary-method="getSummaries"
|
||||
show-summary
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TotalTable">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'ID'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'amount1',
|
||||
label: '数值1',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'amount2',
|
||||
label: '数值2',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'amount3',
|
||||
label: '数值4',
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
|
||||
const columns1 = [
|
||||
{
|
||||
field: 'id',
|
||||
label: 'ID'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'amount1',
|
||||
label: '数值1(元)'
|
||||
},
|
||||
{
|
||||
field: 'amount2',
|
||||
label: '数值2(元)'
|
||||
},
|
||||
{
|
||||
field: 'amount3',
|
||||
label: '数值4(元)'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: '12987122',
|
||||
name: '王小虎',
|
||||
amount1: '234',
|
||||
amount2: '3.2',
|
||||
amount3: 10
|
||||
},
|
||||
{
|
||||
id: '12987123',
|
||||
name: '王小虎',
|
||||
amount1: '165',
|
||||
amount2: '4.43',
|
||||
amount3: 12
|
||||
},
|
||||
{
|
||||
id: '12987124',
|
||||
name: '王小虎',
|
||||
amount1: '324',
|
||||
amount2: '1.9',
|
||||
amount3: 9
|
||||
},
|
||||
{
|
||||
id: '12987125',
|
||||
name: '王小虎',
|
||||
amount1: '621',
|
||||
amount2: '2.2',
|
||||
amount3: 17
|
||||
},
|
||||
{
|
||||
id: '12987126',
|
||||
name: '王小虎',
|
||||
amount1: '539',
|
||||
amount2: '4.1',
|
||||
amount3: 15
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function getSummaries(param: any) {
|
||||
const { columns, data } = param
|
||||
const sums: any[] = []
|
||||
columns.forEach((column: any, index: number) => {
|
||||
if (index === 0) {
|
||||
sums[index] = '总价'
|
||||
return
|
||||
}
|
||||
const values = data.map((item: any) => Number(item[column.property]))
|
||||
if (!values.every((value: number) => isNaN(value))) {
|
||||
sums[index] = values.reduce((prev: number, curr: number) => {
|
||||
const value = Number(curr)
|
||||
if (!isNaN(value)) {
|
||||
return prev + curr
|
||||
} else {
|
||||
return prev
|
||||
}
|
||||
}, 0)
|
||||
sums[index] += ' 元'
|
||||
} else {
|
||||
sums[index] = 'N/A'
|
||||
}
|
||||
})
|
||||
|
||||
return sums
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,163 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-alert
|
||||
effect="dark"
|
||||
:closable="false"
|
||||
title="基于 Element 的 Table 组件进行二次封装,实现数据驱动,支持所有 Table 参数 -- 树形数据与懒加载"
|
||||
type="info"
|
||||
style="margin-bottom: 20px"
|
||||
/>
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
row-key="id"
|
||||
border
|
||||
default-expand-all
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
/>
|
||||
|
||||
<com-table
|
||||
v-loading="loading"
|
||||
:columns="columns1"
|
||||
:data="tableData1"
|
||||
row-key="id"
|
||||
border
|
||||
lazy
|
||||
:load="load"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
style="margin-top: 20px"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="TreeAndLoad">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const columns1 = [
|
||||
{
|
||||
field: 'date',
|
||||
label: '日期'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '姓名'
|
||||
},
|
||||
{
|
||||
field: 'address',
|
||||
label: '地址'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
id: 1,
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
children: [
|
||||
{
|
||||
id: 31,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const tableData1 = [
|
||||
{
|
||||
id: 1,
|
||||
date: '2016-05-02',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1518 弄'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '2016-05-04',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1517 弄'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄',
|
||||
hasChildren: true
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
date: '2016-05-03',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1516 弄'
|
||||
}
|
||||
]
|
||||
|
||||
const loading = ref<boolean>(true)
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1000)
|
||||
|
||||
function load(_: any, __: any, resolve: Function) {
|
||||
setTimeout(() => {
|
||||
resolve([
|
||||
{
|
||||
id: 31,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
date: '2016-05-01',
|
||||
name: '王小虎',
|
||||
address: '上海市普陀区金沙江路 1519 弄'
|
||||
}
|
||||
])
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
Reference in New Issue
Block a user