refactor(components): 组件重构和优化

- 将开发组件从dev目录迁移到advanced目录
- 修复样式变量导入路径问题
- 调整表单验证规则的必需性设置
- 更新组件演示页面的引用路径
- 移除不再需要的组件和相关代码
- 优化组件属性配置和默认值设定
- 删除重复的文件上传演示组件
- 整合并规范组件依赖关系
This commit is contained in:
2026-02-04 15:26:06 +08:00
parent b9b1f8eb8c
commit 3d5b9083d9
34 changed files with 1201 additions and 928 deletions
@@ -1,233 +1,233 @@
<!--
* 拖拽表格组件:封装自定义逻辑与参数,表格支持拖拽排序
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table
ref="table"
v-loading="crud.loading"
stripe
empty-text="暂无数据"
:row-key="crud.primaryKey"
fit
:data="crud.dataSource"
style="width: 100%;"
:height="height"
:max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="showSelect" type="selection" width="55" />
<slot />
<el-pagination
v-if="paging"
:current-page="pageProps.current"
:page-sizes="[10, 20, 50]"
:page-size="pageProps.pageSize"
layout="total, sizes, prev, pager, next"
:total="pageProps.total"
@size-change="(size) => crud.onPageChange(pageProps.current, size, pageProps.total)"
@current-change="(current) => crud.onPageChange(current, pageProps.pageSize, pageProps.total)"
/>
</el-table></div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
name: 'CuteDragTable',
props: {
primaryKey: {
type: String,
required: true,
default: null
},
fetch: {
type: Function,
required: false,
default: null
},
paramsTransform: {
type: Function,
required: false,
default: null
},
responseTransform: {
type: Function,
required: false,
default: null
},
showSelect: {
type: Boolean,
required: false,
default: false
},
paging: {
type: Boolean,
required: false,
default: true
},
pageProps: {
type: Object,
required: true,
default: function() {
return {
current: 1,
pageSize: 10,
total: 0
}
}
}
},
data() {
return {
crud: {
loading: false,
primaryKey: this.primaryKey ? this.primaryKey : 'id',
fetchUrl: null,
dataSource: [],
onPageChange: (currentPage, pageSize) => {
this.pageProps.current = currentPage
this.pageProps.pageSize = pageSize
console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh()
},
orderBy: '',
selection: []
}
}
},
computed: {
height() {
return document.documentElement.clientHeight - 300
}
},
mounted() {
this.initData()
},
methods: {
refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData()
this.initDragTable()
},
async initData() {
let params = {}
// 自定义请求参数
if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps)
}
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) {
try {
this.crud.loading = true
// 请求远程数据
const response = await this.fetch(params)
// console.error('response', response)
// { content: [], totalElements: 0 }
// 转换为表格所需要的数据
if (this.responseTransform) {
return this.responseTransform(response)
}
if (response && response.hasOwnProperty('totalElements') && response.hasOwnProperty('content')) {
this.pageProps.total = response.totalElements
this.crud.dataSource = response.content
}
return response
} catch (e) {
console.error('CuteDragTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally {
this.crud.loading = false
}
}
},
onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection)
},
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
},
initDragTable() {
const that = this
const table = that.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
Sortable.create(table, {
animation: 1000,
onEnd({ newIndex, oldIndex }) {
// 拖拽排序数据
that.crud.dataSource.splice(newIndex, 0, that.crud.dataSource.splice(oldIndex, 1)[0])
const newArray = that.crud.dataSource.slice(0)
that.crud.dataSource = [] // 必须有此步骤,不然拖拽后回弹
that.$nextTick(function() {
that.crud.dataSource = newArray // 重新赋值,用新数据来刷新视图
this.updateOrderNum(that.crud.dataSource)// 更改列表中的序号,使序号1.2.3.4.....显示,不然就是行拖拽后乱序显示如:3.2.4.1...
})
}
})
},
updateOrderNum(data) {
data.forEach((item, index) => {
item.orderNum = index + 1
})
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
<!--
* 拖拽表格组件:封装自定义逻辑与参数,表格支持拖拽排序
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table
ref="table"
v-loading="crud.loading"
stripe
empty-text="暂无数据"
:row-key="crud.primaryKey"
fit
:data="crud.dataSource"
style="width: 100%;"
:height="height"
:max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="showSelect" type="selection" width="55" />
<slot />
<el-pagination
v-if="paging"
:current-page="pageProps.current"
:page-sizes="[10, 20, 50]"
:page-size="pageProps.pageSize"
layout="total, sizes, prev, pager, next"
:total="pageProps.total"
@size-change="(size) => crud.onPageChange(pageProps.current, size, pageProps.total)"
@current-change="(current) => crud.onPageChange(current, pageProps.pageSize, pageProps.total)"
/>
</el-table></div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
name: 'CuteDragTable',
props: {
primaryKey: {
type: String,
required: true,
default: null
},
fetch: {
type: Function,
required: false,
default: null
},
paramsTransform: {
type: Function,
required: false,
default: null
},
responseTransform: {
type: Function,
required: false,
default: null
},
showSelect: {
type: Boolean,
required: false,
default: false
},
paging: {
type: Boolean,
required: false,
default: true
},
pageProps: {
type: Object,
required: true,
default: function() {
return {
current: 1,
pageSize: 10,
total: 0
}
}
}
},
data() {
return {
crud: {
loading: false,
primaryKey: this.primaryKey ? this.primaryKey : 'id',
fetchUrl: null,
dataSource: [],
onPageChange: (currentPage, pageSize) => {
this.pageProps.current = currentPage
this.pageProps.pageSize = pageSize
console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh()
},
orderBy: '',
selection: []
}
}
},
computed: {
height() {
return document.documentElement.clientHeight - 300
}
},
mounted() {
this.initData()
},
methods: {
refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData()
this.initDragTable()
},
async initData() {
let params = {}
// 自定义请求参数
if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps)
}
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) {
try {
this.crud.loading = true
// 请求远程数据
const response = await this.fetch(params)
// console.error('response', response)
// { content: [], totalElements: 0 }
// 转换为表格所需要的数据
if (this.responseTransform) {
return this.responseTransform(response)
}
if (response && response.hasOwnProperty('totalElements') && response.hasOwnProperty('content')) {
this.pageProps.total = response.totalElements
this.crud.dataSource = response.content
}
return response
} catch (e) {
console.error('CuteDragTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally {
this.crud.loading = false
}
}
},
onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection)
},
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
},
initDragTable() {
const that = this
const table = that.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
Sortable.create(table, {
animation: 1000,
onEnd({ newIndex, oldIndex }) {
// 拖拽排序数据
that.crud.dataSource.splice(newIndex, 0, that.crud.dataSource.splice(oldIndex, 1)[0])
const newArray = that.crud.dataSource.slice(0)
that.crud.dataSource = [] // 必须有此步骤,不然拖拽后回弹
that.$nextTick(function() {
that.crud.dataSource = newArray // 重新赋值,用新数据来刷新视图
this.updateOrderNum(that.crud.dataSource)// 更改列表中的序号,使序号1.2.3.4.....显示,不然就是行拖拽后乱序显示如:3.2.4.1...
})
}
})
},
updateOrderNum(data) {
data.forEach((item, index) => {
item.orderNum = index + 1
})
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
@@ -185,7 +185,7 @@ export default {
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
@import "~@/assets/styles/variables";
.selection-box {
text-align: left;
@@ -1,137 +1,139 @@
<!--
* 简单表单弹窗:封装了常用方法和参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<el-dialog
:title="title"
:visible.sync="visible"
:width="width"
:fullscreen="fullscreen"
:before-close="beforeClose"
:modal="false"
>
<div class="container-form">
<el-form ref="form" :model="model" :rules="rules" :inline="inline" size="small">
<!-- 这里是插槽,用于渲染传入的 el-form-item -->
<slot />
</el-form>
</div>
<el-divider />
<div class="dialog-footer">
<el-button type="danger" @click="hidden">取 消</el-button>
<!--<el-button @click="resetForm('form')">重 置</el-button>-->
<el-button v-prevent-re-click type="primary" @click="submitForm('form')">提 交</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'CuteFormDialog',
props: {
title: {
type: String,
required: true,
default: '默认标题'
},
width: {
type: String,
required: false,
default: '40%'
},
fullscreen: {
type: Boolean,
required: false,
default: false
},
model: {
type: Object,
required: true,
default: null
},
rules: {
type: Object,
required: true,
default: null
},
// 是否平铺表单
inline: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true
},
hidden() {
this.resetForm('form')
this.visible = false
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('submit', this.model)
} else {
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
beforeClose() {
this.hidden()
}
}
}
</script>
<style lang="scss" scoped>
.container-form {
overflow-y: scroll; /* 启用滚动 */
scrollbar-width: none; /* Firefox */
padding-right: 20px;
-ms-overflow-style: none; /* Internet Explorer 10+ */
max-height: calc(100vh - 200px); /* 调整高度以适应页头和底部按钮 */
}
.container-form::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
.dialog-content-wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.dialog-footer {
text-align: right;
border-top: 1px solid #ebeef5;
padding: 16px 0 0 0;
background-color: white;
margin-top: auto;
}
::v-deep(.el-dialog__body) {
padding: 20px 20px !important;
height: 90%;
display: flex;
flex-direction: column;
}
::v-deep(.el-divider--horizontal) {
margin: 0 !important;
}
</style>
<!--
* 简单表单弹窗:封装了常用方法和参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<el-dialog
:title="title"
:visible.sync="visible"
:width="width"
:fullscreen="fullscreen"
:before-close="beforeClose"
:modal="false"
>
<div class="container-form">
<el-form ref="form" :model="model" :rules="rules" :inline="inline" size="small">
<!-- 这里是插槽,用于渲染传入的 el-form-item -->
<slot />
</el-form>
</div>
<el-divider />
<div class="dialog-footer">
<el-button type="danger" @click="hidden">取 消</el-button>
<!--<el-button @click="resetForm('form')">重 置</el-button>-->
<el-button v-prevent-re-click type="primary" @click="submitForm('form')">提 交</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'CuteFormDialog',
props: {
title: {
type: String,
required: true,
default: '默认标题'
},
width: {
type: String,
required: false,
default: '40%'
},
fullscreen: {
type: Boolean,
required: false,
default: false
},
model: {
type: Object,
required: true,
default: null
},
rules: {
type: Object,
required: false,
default: function() {
return {}
}
},
// 是否平铺表单
inline: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true
},
hidden() {
this.resetForm('form')
this.visible = false
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('submit', this.model)
} else {
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
beforeClose() {
this.hidden()
}
}
}
</script>
<style lang="scss" scoped>
.container-form {
overflow-y: scroll; /* 启用滚动 */
scrollbar-width: none; /* Firefox */
padding-right: 20px;
-ms-overflow-style: none; /* Internet Explorer 10+ */
max-height: calc(100vh - 200px); /* 调整高度以适应页头和底部按钮 */
}
.container-form::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
.dialog-content-wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.dialog-footer {
text-align: right;
border-top: 1px solid #ebeef5;
padding: 16px 0 0 0;
background-color: white;
margin-top: auto;
}
::v-deep(.el-dialog__body) {
padding: 20px 20px !important;
height: 90%;
display: flex;
flex-direction: column;
}
::v-deep(.el-divider--horizontal) {
margin: 0 !important;
}
</style>
@@ -1,141 +1,143 @@
<!--
* 简单表单抽屉:封装了常用方法和参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<el-drawer
:title="title"
:visible.sync="visible"
:size="width"
:before-close="beforeClose"
:append-to-body="true"
:close-on-press-escape="false"
:wrapper-closable="false"
:destroy-on-close="true"
:show-close="true"
:modal="false"
>
<div class="container-form">
<el-form ref="form" :model="model" :rules="rules" :inline="inline" size="small">
<!-- 这里是插槽,用于渲染传入的 el-form-item -->
<slot />
</el-form>
</div>
<el-divider />
<div class="dialog-footer">
<el-button type="danger" @click="hidden">取 消</el-button>
<el-button v-prevent-re-click type="primary" @click="submitForm('form')">提 交</el-button>
</div>
</el-drawer>
</template>
<script>
export default {
name: 'CuteFormDrawer',
props: {
title: {
type: String,
required: true,
default: '默认标题'
},
width: {
type: String,
required: false,
default: '40%'
},
model: {
type: Object,
required: true,
default: null
},
rules: {
type: Object,
required: true,
default: null
},
// 是否平铺表单
inline: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true
},
hidden() {
this.resetForm('form')
this.visible = false
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('submit', this.model)
} else {
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
beforeClose() {
this.hidden()
}
}
}
</script>
<style lang="scss" scoped>
.container-form {
overflow-y: scroll; /* 启用滚动 */
scrollbar-width: none; /* Firefox */
height: calc(100% - 60px); /* 预留出底部按钮的空间 */
padding-right: 20px;
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.container-form::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
.drawer-content-wrapper {
height: 100%;
display: flex;
flex-direction: column;
position: relative;
}
.dialog-footer{
position: absolute;
bottom: 0;
left: 0;
right: 0;
text-align: right;
background-color: white;
border-top: 1px solid #ebeef5;
padding: 16px 20px;
}
::v-deep(.el-drawer__header) {
padding: 10px;
border-bottom: 1px solid #DCDFE6;
}
::v-deep(.el-drawer__body) {
padding: 10px 10px !important;
}
::v-deep(.el-divider--horizontal) {
margin: 14px 0 !important;
}
</style>
<!--
* 简单表单抽屉:封装了常用方法和参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<el-drawer
:title="title"
:visible.sync="visible"
:size="width"
:before-close="beforeClose"
:append-to-body="true"
:close-on-press-escape="false"
:wrapper-closable="false"
:destroy-on-close="true"
:show-close="true"
:modal="false"
>
<div class="container-form">
<el-form ref="form" :model="model" :rules="rules" :inline="inline" size="small">
<!-- 这里是插槽,用于渲染传入的 el-form-item -->
<slot />
</el-form>
</div>
<el-divider />
<div class="dialog-footer">
<el-button type="danger" @click="hidden">取 消</el-button>
<el-button v-prevent-re-click type="primary" @click="submitForm('form')">提 交</el-button>
</div>
</el-drawer>
</template>
<script>
export default {
name: 'CuteFormDrawer',
props: {
title: {
type: String,
required: true,
default: '默认标题'
},
width: {
type: String,
required: false,
default: '40%'
},
model: {
type: Object,
required: true,
default: null
},
rules: {
type: Object,
required: false,
default: function() {
return {}
}
},
// 是否平铺表单
inline: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
visible: false
}
},
methods: {
show() {
this.visible = true
},
hidden() {
this.resetForm('form')
this.visible = false
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('submit', this.model)
} else {
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
beforeClose() {
this.hidden()
}
}
}
</script>
<style lang="scss" scoped>
.container-form {
overflow-y: scroll; /* 启用滚动 */
scrollbar-width: none; /* Firefox */
height: calc(100% - 60px); /* 预留出底部按钮的空间 */
padding-right: 20px;
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.container-form::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
.drawer-content-wrapper {
height: 100%;
display: flex;
flex-direction: column;
position: relative;
}
.dialog-footer{
position: absolute;
bottom: 0;
left: 0;
right: 0;
text-align: right;
background-color: white;
border-top: 1px solid #ebeef5;
padding: 16px 20px;
}
::v-deep(.el-drawer__header) {
padding: 10px;
border-bottom: 1px solid #DCDFE6;
}
::v-deep(.el-drawer__body) {
padding: 10px 10px !important;
}
::v-deep(.el-divider--horizontal) {
margin: 14px 0 !important;
}
</style>
@@ -1,219 +1,219 @@
<!--
* 简单表格组件:封装自定义逻辑与参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: right">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table
ref="table"
v-loading="crud.loading"
stripe
empty-text="暂无数据"
:row-key="crud.primaryKey"
fit
:data="crud.dataSource"
style="width: 100%;"
:height="height"
:max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="showSelect" type="selection" width="55" />
<slot />
</el-table>
<el-pagination
v-if="paging"
:current-page="pageProps.current"
:page-sizes="[10, 20, 50]"
:page-size="pageProps.pageSize"
layout="total, sizes, prev, pager, next"
:total="pageProps.total"
@size-change="(size) => crud.onPageChange(pageProps.current, size, pageProps.total)"
@current-change="(current) => crud.onPageChange(current, pageProps.pageSize, pageProps.total)"
/>
</div>
</template>
<script>
export default {
name: 'CuteSimpleTable',
props: {
primaryKey: {
type: String,
required: true,
default: null
},
fetch: {
type: Function,
required: false,
default: null
},
paramsTransform: {
type: Function,
required: false,
default: null
},
responseTransform: {
type: Function,
required: false,
default: null
},
showSelect: {
type: Boolean,
required: false,
default: false
},
paging: {
type: Boolean,
required: false,
default: true
},
pageProps: {
type: Object,
required: true,
default: function() {
return {
current: 1,
pageSize: 10,
total: 0
}
}
},
customHeight: {
type: Number,
required: false,
default: null
}
},
data() {
return {
crud: {
loading: false,
primaryKey: this.primaryKey ? this.primaryKey : 'id',
fetchUrl: null,
dataSource: [],
onPageChange: (currentPage, pageSize) => {
this.pageProps.current = currentPage
this.pageProps.pageSize = pageSize
console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh()
},
orderBy: '',
selection: []
}
}
},
computed: {
height() {
if (this.customHeight) {
return this.customHeight
}
return document.documentElement.clientHeight - 300
}
},
mounted() {
this.initData()
},
methods: {
refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData()
},
async initData() {
let params = {}
// 自定义请求参数
if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps)
}
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) {
try {
this.crud.loading = true
// 请求远程数据
const response = await this.fetch(params)
// console.error('response', response)
// { content: [], totalElements: 0 }
// 转换为表格所需要的数据
if (this.responseTransform) {
return this.responseTransform(response)
}
if (response && response.hasOwnProperty('totalElements') && response.hasOwnProperty('content')) {
this.pageProps.total = response.totalElements
this.crud.dataSource = response.content
}
return response
} catch (e) {
console.error('CuteSimpleTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally {
this.crud.loading = false
}
}
},
onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection)
},
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
<!--
* 简单表格组件:封装自定义逻辑与参数
* @author odboy
* @email tianjun@odboy.cn
* @created 2025-08-01
-->
<template>
<div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: right">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table
ref="table"
v-loading="crud.loading"
stripe
empty-text="暂无数据"
:row-key="crud.primaryKey"
fit
:data="crud.dataSource"
style="width: 100%;"
:height="height"
:max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange"
>
<el-table-column v-if="showSelect" type="selection" width="55" />
<slot />
</el-table>
<el-pagination
v-if="paging"
:current-page="pageProps.current"
:page-sizes="[10, 20, 50]"
:page-size="pageProps.pageSize"
layout="total, sizes, prev, pager, next"
:total="pageProps.total"
@size-change="(size) => crud.onPageChange(pageProps.current, size, pageProps.total)"
@current-change="(current) => crud.onPageChange(current, pageProps.pageSize, pageProps.total)"
/>
</div>
</template>
<script>
export default {
name: 'CuteSimpleTable',
props: {
primaryKey: {
type: String,
required: true,
default: null
},
fetch: {
type: Function,
required: false,
default: null
},
paramsTransform: {
type: Function,
required: false,
default: null
},
responseTransform: {
type: Function,
required: false,
default: null
},
showSelect: {
type: Boolean,
required: false,
default: false
},
paging: {
type: Boolean,
required: false,
default: true
},
pageProps: {
type: Object,
required: true,
default: function() {
return {
current: 1,
pageSize: 10,
total: 0
}
}
},
customHeight: {
type: Number,
required: false,
default: null
}
},
data() {
return {
crud: {
loading: false,
primaryKey: this.primaryKey ? this.primaryKey : 'id',
fetchUrl: null,
dataSource: [],
onPageChange: (currentPage, pageSize) => {
this.pageProps.current = currentPage
this.pageProps.pageSize = pageSize
console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh()
},
orderBy: '',
selection: []
}
}
},
computed: {
height() {
if (this.customHeight) {
return this.customHeight
}
return document.documentElement.clientHeight - 300
}
},
mounted() {
this.initData()
},
methods: {
refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData()
},
async initData() {
let params = {}
// 自定义请求参数
if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps)
}
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) {
try {
this.crud.loading = true
// 请求远程数据
const response = await this.fetch(params)
// console.error('response', response)
// { content: [], totalElements: 0 }
// 转换为表格所需要的数据
if (this.responseTransform) {
return this.responseTransform(response)
}
if (response && response.hasOwnProperty('totalElements') && response.hasOwnProperty('content')) {
this.pageProps.total = response.totalElements
this.crud.dataSource = response.content
}
return response
} catch (e) {
console.error('CuteSimpleTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally {
this.crud.loading = false
}
}
},
onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection)
},
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
@@ -29,7 +29,7 @@ export default {
props: {
title: {
type: String,
required: true,
required: false,
default: '默认标题'
},
width: {
@@ -18,7 +18,6 @@
<el-table
ref="leftTableRef"
v-loading="loading"
:disabled="disabled"
stripe
border
empty-text="暂无数据"
@@ -63,7 +62,6 @@
<el-col :span="11">
<el-table
ref="rightTableRef"
:disabled="disabled"
stripe
border
empty-text="暂无数据"
@@ -117,21 +115,15 @@ export default {
*/
primaryKey: {
type: String,
require: true,
require: false,
default: 'id'
},
/**
* 是否禁用
*/
disabled: {
type: Boolean,
default: false
},
/**
* 是否加载中
*/
loading: {
type: Boolean,
require: false,
default: false
}
},
@@ -53,7 +53,7 @@
<script>
import DictService from '@/api/system/dict'
import CuteDragTable from '@/views/components/dev/CuteDragTable.vue'
import CuteDragTable from '@/views/components/advanced/CuteDragTable.vue'
import { FormatRowDateTimeStr } from '@/utils/KitUtil'
export default {
@@ -1,52 +0,0 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl">
<cute-file-drag-upload v-model="form" mode="local" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import CuteFileDragUpload from '@/views/components/business/CuteFileDragUpload'
export default {
name: 'CuteFileDragUploadDemo',
components: { CuteFileDragUpload },
data() {
return {
form: {
name: '',
region: '',
fileUrl: ''
}
}
},
methods: {
submitForm(formName) {
const that = this
that.$refs[formName].validate((valid) => {
if (valid) {
console.log('submitForm:form', that.form)
} else {
return false
}
})
}
}
}
</script>
@@ -1,52 +0,0 @@
<template>
<div class="app-container">
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl">
<cute-file-upload v-model="form" mode="local" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import CuteFileUpload from '@/views/components/business/CuteFileUpload'
export default {
name: 'CuteFileUploadDemo',
components: { CuteFileUpload },
data() {
return {
form: {
name: '',
region: '',
fileUrl: ''
}
}
},
methods: {
submitForm(formName) {
const that = this
that.$refs[formName].validate((valid) => {
if (valid) {
console.log('submitForm:form', that.form)
} else {
return false
}
})
}
}
}
</script>
@@ -13,54 +13,20 @@
</cute-search-form>
<cute-section-title title="高级搜索Pro版 CuteSearchProForm" />
<cute-search-pro-form :model="searchFormProValues" :schema="searchFormProSchema" />
<cute-section-title title="数据穿梭 CuteTransfer" />
<cute-transfer :data-source="leftDataSource" primary-key="id">
<el-table-column prop="name" label="姓名" />
<el-table-column prop="description" label="备注" />
</cute-transfer>
<cute-section-title title="预览抽屉 CutePreviewDrawer">
<template v-slot:operation>
<cute-button type="primary" @click="handleCutePreviewDrawerShow">显示</cute-button>
</template>
</cute-section-title>
<cute-preview-drawer ref="cpd" title="预览抽屉">
<p>预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉</p>
</cute-preview-drawer>
<cute-section-title title="截屏 CuteScreenShot:包裹要截屏的组件" />
<cute-screen-shot>
<cute-search-form :model="searchFormModel" @submit="handleSearchFormSubmit" @reset="handleSearchFormReset">
<template v-slot:suffix>
<el-form-item label="模糊查询" prop="blurry">
<el-input v-model="searchFormModel.blurry" clearable />
</el-form-item>
</template>
<template v-slot:operation>
<cute-button type="primary">查询后置按钮</cute-button>
</template>
</cute-search-form>
</cute-screen-shot>
</div>
</template>
<script>
import CuteSearchForm from '@/views/components/dev/CuteSearchForm.vue'
import CutePreviewDrawer from '@/views/components/dev/CutePreviewDrawer.vue'
import CuteScreenShot from '@/views/components/dev/CuteScreenShot.vue'
import CuteSearchForm from '@/views/components/advanced/CuteSearchForm.vue'
import CuteSectionTitle from '@/views/components/dev/CuteSectionTitle.vue'
import CuteButton from '@/views/components/dev/CuteButton.vue'
import CuteTransfer from '@/views/components/dev/CuteTransfer.vue'
import CuteSearchFormPro from '@/views/components/dev/CuteSearchFormPro.vue'
import CuteSearchFormPro from '@/views/components/advanced/CuteSearchFormPro.vue'
export default {
name: 'CuteOtherDemo',
components: {
CuteSearchProForm: CuteSearchFormPro,
CuteTransfer,
CuteButton,
CuteSectionTitle,
CuteScreenShot,
CutePreviewDrawer,
CuteSearchForm
},
data() {
@@ -72,27 +38,7 @@ export default {
{ name: 'createDate', title: '创建日期', type: 'date' },
{ name: 'createTime', title: '创建时间', type: 'datetime' }
],
searchFormProValues: { name: '小明', sex: 'mm' },
leftDataSource: [
{ id: 1, name: '小明', description: '小明牛P' },
{ id: 2, name: '小红', description: '小红牛P', disabled: true },
{ id: 3, name: '小蓝', description: '小蓝牛P', disabled: true },
{ id: 4, name: '小绿', description: '小绿牛P' },
{ id: 5, name: '小黄', description: '小黄牛P' },
{ id: 6, name: '小紫', description: '小紫牛P' },
{ id: 7, name: '小青', description: '小青牛P', disabled: true },
{ id: 8, name: '小橙', description: '小橙牛P' },
{ id: 9, name: '小贵', description: '小贵牛P' },
{ id: 10, name: '小陈', description: '小陈牛P' },
{ id: 11, name: '小勇', description: '小勇牛P' },
{ id: 12, name: '小田', description: '小田牛P' },
{ id: 13, name: '小天', description: '小天牛P', disabled: true },
{ id: 14, name: '小邓', description: '小邓牛P', disabled: true },
{ id: 15, name: '小周', description: '小周牛P', disabled: true },
{ id: 16, name: '小吴', description: '小吴牛P' },
{ id: 17, name: '小郑', description: '小郑牛P' },
{ id: 18, name: '小王', description: '小王牛P' }
]
searchFormProValues: { name: '小明', sex: 'mm' }
}
},
methods: {
@@ -101,9 +47,6 @@ export default {
},
handleSearchFormReset() {
console.log('handleSearchFormReset')
},
handleCutePreviewDrawerShow() {
this.$refs.cpd.show()
}
}
}
@@ -115,15 +115,15 @@
</template>
<script>
import CuteSimpleTable from '@/views/components/dev/CuteSimpleTable'
import CuteSimpleTable from '@/views/components/advanced/CuteSimpleTable.vue'
import DictService from '@/api/system/dict'
import CuteFormDialog from '@/views/components/dev/CuteFormDialog'
import CuteFormDrawer from '@/views/components/dev/CuteFormDrawer'
import CuteFormDialog from '@/views/components/advanced/CuteFormDialog.vue'
import CuteFormDrawer from '@/views/components/advanced/CuteFormDrawer.vue'
import { FormatRowDateTimeStr } from '@/utils/KitUtil'
import CuteButton from '@/views/components/dev/CuteButton.vue'
import CuteTransfer from '@/views/components/dev/CuteTransfer.vue'
import CuteEditTable from '@/views/components/dev/CuteEditTable.vue'
import CuteFormDialogPro from '@/views/components/dev/CuteFormDialogPro.vue'
import CuteEditTable from '@/views/components/advanced/CuteEditTable.vue'
import CuteFormDialogPro from '@/views/components/advanced/CuteFormDialogPro.vue'
export default {
name: 'CuteSimpleTableDemo',
@@ -4,7 +4,7 @@
<ul class="description">
<li>选择、绑定部门信息时</li>
<li>统一部门数据来源</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)@Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<el-row>
@@ -0,0 +1,115 @@
<template>
<div>
<h4>何时使用</h4>
<ul class="description">
<li>需要用户上传文件时</li>
<li>当需要与表单组件(如 CuteFormDialog、CuteFormDrawer)集成时</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl">
<cute-file-drag-upload v-model="form" mode="local" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button>
</el-form-item>
</el-form>
<h4>与CuteFormDialog集成 <el-button type="text" @click="showFormDialog">显示对话框</el-button></h4>
<cute-form-dialog ref="formDialog" title="与CuteFormDialog集成" :model="form">
<el-form-item label="活动名称" prop="name" label-width="80px">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region" label-width="80px">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl" label-width="80px">
<cute-file-drag-upload v-model="form" mode="local" />
</el-form-item>
</cute-form-dialog>
<h4>与CuteFormDrawer集成 <el-button type="text" @click="showFormDrawer">显示抽屉</el-button></h4>
<cute-form-drawer ref="formDrawer" title="与CuteFormDrawer集成" :model="form">
<el-form-item label="活动名称" prop="name" label-width="80px">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region" label-width="80px">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl" label-width="80px">
<cute-file-drag-upload v-model="form" mode="local" />
</el-form-item>
</cute-form-drawer>
<h4>API</h4>
<el-table :data="apiData">
<el-table-column prop="name" label="参数" width="220" />
<el-table-column prop="remark" label="说明" width="450" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="defaultValue" label="默认值" />
<el-table-column prop="required" label="是否必填" />
</el-table>
</div>
</template>
<script>
import CuteFormDialog from '@/views/components/advanced/CuteFormDialog.vue'
import CuteFileDragUpload from '@/views/components/business/CuteFileDragUpload.vue'
import CuteFormDrawer from '@/views/components/advanced/CuteFormDrawer.vue'
export default {
name: 'CuteFileDragUploadDemo',
components: { CuteFormDrawer, CuteFormDialog, CuteFileDragUpload },
data() {
return {
form: {
name: '',
region: '',
fileUrl: ''
},
apiData: [
{ name: 'value', remark: '上传的文件路径', type: 'string', defaultValue: '-', required: '是' },
{ name: 'mode', remark: '上传方式。local本地、oss对象存储', type: 'string', defaultValue: 'local', required: '否' }
]
}
},
methods: {
showFormDialog() {
this.$refs.formDialog.show()
},
showFormDrawer() {
this.$refs.formDrawer.show()
},
submitForm(formName) {
const that = this
that.$refs[formName].validate((valid) => {
if (valid) {
console.log('submitForm:form', that.form)
} else {
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
ul {
padding-left: 20px;
}
.description > li{
font-size: 12px;
}
</style>
@@ -0,0 +1,115 @@
<template>
<div>
<h4>何时使用</h4>
<ul class="description">
<li>需要用户上传文件时</li>
<li>当需要与表单组件(如 CuteFormDialog、CuteFormDrawer)集成时</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="活动名称" prop="name">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl">
<cute-file-upload v-model="form" mode="local" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('form')">提 交</el-button>
</el-form-item>
</el-form>
<h4>与CuteFormDialog集成 <el-button type="text" @click="showFormDialog">显示对话框</el-button></h4>
<cute-form-dialog ref="formDialog" title="与CuteFormDialog集成" :model="form">
<el-form-item label="活动名称" prop="name" label-width="80px">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region" label-width="80px">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl" label-width="80px">
<cute-file-upload v-model="form" mode="local" />
</el-form-item>
</cute-form-dialog>
<h4>与CuteFormDrawer集成 <el-button type="text" @click="showFormDrawer">显示抽屉</el-button></h4>
<cute-form-drawer ref="formDrawer" title="与CuteFormDrawer集成" :model="form">
<el-form-item label="活动名称" prop="name" label-width="80px">
<el-input v-model="form.name" style="width: 100%" />
</el-form-item>
<el-form-item label="活动区域" prop="region" label-width="80px">
<el-select v-model="form.region" placeholder="请选择活动区域" style="width: 100%">
<el-option label="区域一" value="shanghai" />
<el-option label="区域二" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="文件上传" prop="fileUrl" label-width="80px">
<cute-file-upload v-model="form" mode="local" />
</el-form-item>
</cute-form-drawer>
<h4>API</h4>
<el-table :data="apiData">
<el-table-column prop="name" label="参数" width="220" />
<el-table-column prop="remark" label="说明" width="450" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="defaultValue" label="默认值" />
<el-table-column prop="required" label="是否必填" />
</el-table>
</div>
</template>
<script>
import CuteFileUpload from '@/views/components/business/CuteFileUpload.vue'
import CuteFormDialog from '@/views/components/advanced/CuteFormDialog.vue'
import CuteFormDrawer from '@/views/components/advanced/CuteFormDrawer.vue'
export default {
name: 'CuteFileUploadDemo',
components: { CuteFormDrawer, CuteFormDialog, CuteFileUpload },
data() {
return {
form: {
name: '',
region: '',
fileUrl: ''
},
apiData: [
{ name: 'value', remark: '上传的文件路径', type: 'string', defaultValue: '-', required: '是' },
{ name: 'mode', remark: '上传方式。local本地、oss对象存储', type: 'string', defaultValue: 'local', required: '否' }
]
}
},
methods: {
showFormDialog() {
this.$refs.formDialog.show()
},
showFormDrawer() {
this.$refs.formDrawer.show()
},
submitForm(formName) {
const that = this
that.$refs[formName].validate((valid) => {
if (valid) {
console.log('submitForm:form', that.form)
} else {
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
ul {
padding-left: 20px;
}
.description > li{
font-size: 12px;
}
</style>
@@ -4,7 +4,7 @@
<ul class="description">
<li>选择、绑定部门明细信息,需要根部门和子部门以及路径的信息等</li>
<li>统一部门数据来源</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)@Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<cute-product-line-select @change="onProductLineChange" @detail="onProductLineDetailChange" />
@@ -4,7 +4,7 @@
<ul class="description">
<li>选择、绑定部门明细信息,需要根部门和子部门以及路径的信息等</li>
<li>统一部门数据来源</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)@Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<cute-product-line-select-pro @change="onProductLineDetailProChange" />
@@ -4,7 +4,7 @@
<ul class="description">
<li>选择单个用户信息</li>
<li>支持用户姓名、手机号、邮箱、用户名查询</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<cute-single-user-select v-model="user" @change="onUserSelectChange" />
@@ -4,7 +4,7 @@
<ul class="description">
<li>选择多个用户信息</li>
<li>支持用户姓名、手机号、邮箱、用户名查询</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<cute-user-select v-model="user" @change="onUserSelectChange" />
@@ -3,7 +3,7 @@
<h4>何时使用</h4>
<ul class="description">
<li>需求输入各种代码数据</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>Java编辑器</h4>
<cute-code-editor :content="javaContent" mode="java" @change="onJavaChange" />
@@ -4,7 +4,7 @@
<ul class="description">
<li>当需要在容器内展示大量内容,需要横向滚动查看时</li>
<li>当希望在不同操作系统(Windows/Mac)上保持一致的滚动条样式时</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-horizontal-scroll-bar>
@@ -3,7 +3,7 @@
<h4>何时使用</h4>
<ul class="description">
<li>需求输入Markdown格式数据</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)@Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<cute-markdown
@@ -0,0 +1,54 @@
<template>
<div>
<h4>何时使用</h4>
<ul class="description">
<li>抽屉是用于在不离开主路径的情况下,提供用户快速执行简单的操作、确认用户信息或反馈提示的辅助窗口</li>
<li>宽度固定,样式统一</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-button type="primary" @click="handleCutePreviewDrawerShow">显示预览抽屉</cute-button>
<cute-preview-drawer ref="cpd" title="预览抽屉">
<p>预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉预览抽屉</p>
</cute-preview-drawer>
<h4>API</h4>
<el-table :data="apiData">
<el-table-column prop="name" label="参数" width="220" />
<el-table-column prop="remark" label="说明" width="450" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="defaultValue" label="默认值" />
<el-table-column prop="required" label="是否必填" />
</el-table>
</div>
</template>
<script>
import CuteButton from '@/views/components/dev/CuteButton.vue'
import CutePreviewDrawer from '@/views/components/dev/CutePreviewDrawer.vue'
export default {
name: 'CutePreviewDrawerDemo',
components: { CutePreviewDrawer, CuteButton },
data() {
return {
apiData: [
{ name: 'title', remark: '标题', type: 'string', defaultValue: '默认标题', required: '否' },
{ name: 'width', remark: '抽屉宽度', type: 'string', defaultValue: '40%', required: '否' },
{ name: 'wrapperClosable', remark: '点击遮罩层是否可以关闭抽屉', type: 'boolean', defaultValue: 'false', required: '否' }
]
}
},
methods: {
handleCutePreviewDrawerShow() {
this.$refs.cpd.show()
}
}
}
</script>
<style lang="scss" scoped>
ul {
padding-left: 20px;
}
.description > li{
font-size: 12px;
}
</style>
@@ -3,7 +3,7 @@
<h4>何时使用</h4>
<ul class="description">
<li>需求输入内容丰富的文本数据</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)@Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础使用</h4>
<cute-rich-text-editor @change="onChange" />
@@ -0,0 +1,48 @@
<template>
<div>
<h4>何时使用</h4>
<ul class="description">
<li>保存区域内已生成的结果为图片</li>
<li>需要页面截图,或者需要将表格滚动部分展开后截图,且页面不能有明显变化的时候</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-screen-shot>
<cute-page>
测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</cute-page>
</cute-screen-shot>
<h4>API</h4>
<el-table :data="apiData">
<el-table-column prop="name" label="参数" width="220" />
<el-table-column prop="remark" label="说明" width="450" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="defaultValue" label="默认值" />
<el-table-column prop="required" label="是否必填" />
</el-table>
</div>
</template>
<script>
import CuteScreenShot from '@/views/components/dev/CuteScreenShot.vue'
import CutePage from '@/views/components/dev/CutePage.vue'
export default {
name: 'CuteScreenShotDemo',
components: { CutePage, CuteScreenShot },
data() {
return {
apiData: [
{ name: 'type', remark: '按钮类型', type: 'primary| secondary | normal | text', defaultValue: 'normal', required: '否' }
]
}
}
}
</script>
<style lang="scss" scoped>
ul {
padding-left: 20px;
}
.description > li{
font-size: 12px;
}
</style>
@@ -4,7 +4,7 @@
<ul class="description">
<li>输入备注、说明等大量普通文本时</li>
<li>需要限制输入文本的长度</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-text-area-input v-model="content" />
@@ -0,0 +1,76 @@
<template>
<div>
<h4>何时使用</h4>
<ul class="description">
<li>在多个可选项中进行选择,并区分已选和待选状态</li>
<li>需要明确区分源数据和目标数据的场景</li>
<li>需要通过搜索功能快速筛选可选项的场景</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-transfer :data-source="leftDataSource" primary-key="id">
<el-table-column prop="name" label="姓名" />
<el-table-column prop="description" label="备注" />
</cute-transfer>
<h4>禁用状态</h4>
<cute-transfer :data-source="leftDataSource" primary-key="id" disabled>
<el-table-column prop="name" label="姓名" />
<el-table-column prop="description" label="备注" />
</cute-transfer>
<h4>API</h4>
<el-table :data="apiData">
<el-table-column prop="name" label="参数" width="220" />
<el-table-column prop="remark" label="说明" width="450" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="defaultValue" label="默认值" />
<el-table-column prop="required" label="是否必填" />
</el-table>
</div>
</template>
<script>
import CuteTransfer from '@/views/components/dev/CuteTransfer.vue'
export default {
name: 'CuteTransferDemo',
components: { CuteTransfer },
data() {
return {
leftDataSource: [
{ id: 1, name: '小明', description: '小明牛P' },
{ id: 2, name: '小红', description: '小红牛P', disabled: true },
{ id: 3, name: '小蓝', description: '小蓝牛P', disabled: true },
{ id: 4, name: '小绿', description: '小绿牛P' },
{ id: 5, name: '小黄', description: '小黄牛P' },
{ id: 6, name: '小紫', description: '小紫牛P' },
{ id: 7, name: '小青', description: '小青牛P', disabled: true },
{ id: 8, name: '小橙', description: '小橙牛P' },
{ id: 9, name: '小贵', description: '小贵牛P' },
{ id: 10, name: '小陈', description: '小陈牛P' },
{ id: 11, name: '小勇', description: '小勇牛P' },
{ id: 12, name: '小田', description: '小田牛P' },
{ id: 13, name: '小天', description: '小天牛P', disabled: true },
{ id: 14, name: '小邓', description: '小邓牛P', disabled: true },
{ id: 15, name: '小周', description: '小周牛P', disabled: true },
{ id: 16, name: '小吴', description: '小吴牛P' },
{ id: 17, name: '小郑', description: '小郑牛P' },
{ id: 18, name: '小王', description: '小王牛P' }
],
apiData: [
{ name: 'value', remark: '右侧已选值', type: 'array', defaultValue: '[]', required: '否' },
{ name: 'dataSource', remark: '左侧表格数据', type: 'array', defaultValue: '[]', required: '是' },
{ name: 'primary-key', remark: '取对象的哪个值作为value', type: 'string', defaultValue: 'id', required: '否' },
{ name: 'loading', remark: '是否加载中', type: 'boolean', defaultValue: 'false', required: '是' },
{ name: 'change', remark: '右侧已选值发生改变的时候触发的回调', type: '(value) => {}', defaultValue: '-', required: '否' }
]
}
}
}
</script>
<style lang="scss" scoped>
ul {
padding-left: 20px;
}
.description > li{
font-size: 12px;
}
</style>
@@ -4,7 +4,7 @@
<ul class="description">
<li>当需要在容器内展示大量内容,需要纵向滚动查看时</li>
<li>当希望在不同操作系统(Windows/Mac)上保持一致的滚动条样式时</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<cute-vertical-scroll-bar>
@@ -5,7 +5,7 @@
<li>不离开当前场景完成增删改操作</li>
<li>需要确认用户的操作,明确操作会产生的结果,提醒告知用户</li>
<li>作为配置型功能及信息的容器</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(设计)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)</li>
</ul>
<h4>基础用法</h4>
<el-row>
@@ -4,7 +4,7 @@
<ul class="description">
<li>实时与服务器进行数据交互</li>
<li>服务器主动推送数据给客户端</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端) @Odboy(设计) @Odboy(后端)</li>
<li>在使用过程中有任何问题,咨询 @Odboy(前端)@Odboy(后端)</li>
</ul>
<h4>基础用法</h4>
<el-card>
@@ -39,6 +39,15 @@
<el-collapse-item title="富文本框 CuteRichTextEditor" name="CuteRichTextEditor">
<CuteRichTextEditorDemo />
</el-collapse-item>
<el-collapse-item title="截图工具 CuteScreenShot" name="CuteScreenShot">
<CuteScreenShotDemo />
</el-collapse-item>
<el-collapse-item title="预览抽屉 CutePreviewDrawer" name="CutePreviewDrawer">
<CutePreviewDrawerDemo />
</el-collapse-item>
<el-collapse-item title="穿梭框 CuteTransfer" name="CuteTransfer">
<CuteTransferDemo />
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="快捷组件" name="kit">
@@ -74,6 +83,12 @@
<el-collapse-item title="产品线选择框Pro CuteProductLineSelectPro" name="CuteProductLineSelectPro">
<CuteProductLineSelectProDemo />
</el-collapse-item>
<el-collapse-item title="文件上传 CuteFileUpload" name="CuteFileUpload">
<CuteFileUploadDemo />
</el-collapse-item>
<el-collapse-item title="文件拖放上传 CuteFileDragUpload" name="CuteFileDragUpload">
<CuteFileDragUploadDemo />
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="高级组件" name="advanced" />
@@ -103,14 +118,22 @@ import CuteUserSelectDemo from '@/views/componentsDemo/business/CuteUserSelectDe
import CuteSingleUserSelectDemo from '@/views/componentsDemo/business/CuteSingleUserSelectDemo.vue'
import CuteProductLineSelectDemo from '@/views/componentsDemo/business/CuteProductLineSelectDemo.vue'
import CuteProductLineSelectProDemo from '@/views/componentsDemo/business/CuteProductLineSelectProDemo.vue'
import CuteDeptTree from '@/views/components/business/CuteDeptTree.vue'
import CuteDeptTreeDemo from '@/views/componentsDemo/business/CuteDeptTreeDemo.vue'
import CuteScreenShotDemo from '@/views/componentsDemo/dev/CuteScreenShotDemo.vue'
import CutePreviewDrawerDemo from '@/views/componentsDemo/dev/CutePreviewDrawerDemo.vue'
import CuteTransferDemo from '@/views/componentsDemo/dev/CuteTransferDemo.vue'
import CuteFileUploadDemo from '@/views/componentsDemo/business/CuteFileUploadDemo.vue'
import CuteFileDragUploadDemo from '@/views/componentsDemo/business/CuteFileDragUploadDemo.vue'
export default {
name: 'SystemComponents',
components: {
CuteFileDragUploadDemo,
CuteFileUploadDemo,
CuteTransferDemo,
CutePreviewDrawerDemo,
CuteScreenShotDemo,
CuteDeptTreeDemo,
CuteDeptTree,
CuteProductLineSelectProDemo,
CuteProductLineSelectDemo,
CuteSingleUserSelectDemo,
@@ -124,7 +147,14 @@ export default {
CuteSectionTitleDemo,
CuteNoDataDemo,
CutePageDemo,
CuteLinkDemo, KitWsClientDemo, KitDialogDemo, KitNotificationDemo, KitMessageDemo, CuteButtonDemo, CutePage },
CuteLinkDemo,
KitWsClientDemo,
KitDialogDemo,
KitNotificationDemo,
KitMessageDemo,
CuteButtonDemo,
CutePage
},
props: {
value: {
type: Object,