这是我参与更文挑战的第3天,活动详情查看: 更文挑战html
阅读前请按照顺序参看系列文章,效果更佳!前端
听说系列文章很难火爆,由于知识点包袱不够多,因此你们看日后不太愿意收藏
, 不过不要紧了, 系列文章的好处是看着舒服,碎片化时间内很快就看完了,不是吗?vue
前面几个小节已经阐述过,若是须要完成咱们的低代码列表设计,那么必然会涉及到公共组件的设计。vuex
咱们设计了 CommonLayout 组件以完成公共的功能,固然它的内容很是少,仅仅是引入了 Component组件而已。后端
下面是摘自Vue文档介绍:api
有的时候,在不一样组件之间进行动态切换是很是有用的,好比在一个多标签的界面里,上述内容能够经过 Vue 的 元素加一个特殊的 is attribute 来实现:。markdown
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
复制代码
在上述示例中,currentTabComponent 能够包括已注册组件的名字,或一个组件的选项对象。app
因为这一个组件会对应多个路由,因为vue的优化,致使其created方法仅被调用一次。所以咱们须要完成路由切换时的加载工做。异步
前节的实现有些问题,由于涉及到api的调用,这个异步的方法会致使更新页面时状态刷新并不那么及时,所以对上节的组件须要进行优化,以便其可以顺利加载数据。ide
initCom
变量,在未准备好以前先不显示组件。这样作会有少量时间页面空白~~~ 暂时未找到合适的方案;<template>
<div class="app-container">
<keep-alive v-if="initCom">
<component :is="realCompoonent" v-if="realCompoonent" :guid="guid" />
<common-layout v-else :guid="guid" />
</keep-alive>
</div>
</template>
复制代码
beforeRouteEnter(to, from, next) {
next(vm => {
vm.guid = vm.getGuid(to)
if (vm.hasExpire(vm.udf, vm.guid)) {
const http = new Http()
http.fetch({
url: `/Tools/GetModelDefine/${vm.guid}`,
method: 'get',
}).then(data => {
vm.$store.dispatch('udf/setUdfModelData', { guid: vm.guid, data })
vm.init(to)
})
} else {
vm.init(to)
}
})
},
init(route) {
const path = route.path
try {
this.realCompoonent = require(`@/views${path}`).default
// this.$router.push(this.realCompoonent)
} catch (ex) {
console.log(`load sub com [${path}] failed. ${ex}`)
this.realCompoonent = null
}
this.initCom = true
},
复制代码
按照这样的修改,终于在页面刷新、菜单来回切换时表现正常了。
在没有定义 realCompoonent
组件页面时,咱们会自动的使用 CommonLayout组件显示。
其主要按照列表形式展示咱们定义的表单,作好的效果以下:
其主要按照模型定义,进行解析并展示。 经过Common页面组件,咱们已经顺利的拿到模型定义数据,并放在vuex内,所以本组件只须要拿到guid参数,而后到vuex内查询数据便可。
export default {
name: 'CommonLayout',
mixins: [mixClass],
props: {
guid: { type: String, default: '' },
},
data() {
return {}
},
}
复制代码
import { mapGetters } from 'vuex'
...
computed: {
...mapGetters(['udf']),
templateModel() {
// console.log(this.udf.get(this.guid))
return this.udf.get(this.guid)
},
showSummary() {
const index = this.templateModel.listTemplate.findIndex(
item => item.isSum == 1,
)
return index != -1
},
},
复制代码
混入 (mixin) 提供了一种很是灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象能够包含任意组件选项。当组件使用混入对象时,全部混入对象的选项将被“混合”进入该组件自己的选项。 当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。 更多合并规则,能够参考vue文档。
在混入类,咱们会按照约定规则调用分页数据api。
getlistApi(params) {
const model = this.templateModel.model.modelName
return this.$http.fetch({
url: `/${model}/Get${model}Page`,
method: 'post',
params: params,
})
},
复制代码
监视$rout,以便在created方法不被调用时刷新数据。
watch: {
$route: function(to, from) {
this.reset()
this.fetchData()
},
},
复制代码
<el-table-column
v-if="templateModel.model.listShowSelect == 1"
type="selection"
width="55"
/>
<el-table-column v-if="templateModel.model.listShowNo == 1" type="index" align="center" width="50" label="#" :index="table_index" />
复制代码
<el-table v-loading="listLoading" :data="list" element-loading-text="Loading" border fit highlight-current-row :show-summary="showSummary" :summary-method="getSummaries" @current-change="handleCurrentChange" @sort-change="sortList" >
复制代码
合并功能须要按照列设置进行显示,所以须要自定义getSummaries方法。实现的方法以下:
getSummaries(param) {
const list = this.templateModel.listTemplate
const { columns, data } = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计'
return
}
if (column.property) {
const item = list.find(o => o.fieldName.toLowerCase() == column.property.toLowerCase())
console.log(item)
if (item && item.isSum == 1) {
const values = data.map(item => Number(item[column.property]))
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr)
if (!isNaN(value)) {
return prev + curr
} else {
return prev
}
}, 0)
// sums[index]
}
}
})
return sums
},
复制代码
按照模型的列表定义,拉取列,并显示。这里定义了宽度、列名、对齐、属性、以及对日期数据进行格式化。固然还能够按照控件类型进行扩展。
<el-table-column v-for="(item, index) in templateModel.listTemplate" :key="index" :label="$t(templateModel.model.modelName + '.' + item.fieldName)" :width="item.width <= 0 ? 0 : item.width" :align="item.controlType == 'Number' ? 'right' : 'left'" :sortable="item.isSort == 1 ? 'custom' : false" :prop="firstLower(item.fieldName)" >
<template slot-scope="scope">
<template v-if="item.controlType == 'Text'">
{{ scope.row[firstLower(item.fieldName)] }}
</template>
<template v-else-if="item.controlType == 'DateTime'">
{{ scope.row[firstLower(item.fieldName)] | formatDate }}
</template>
<template v-else>
{{ scope.row[firstLower(item.fieldName)] }}
</template>
</template>
</el-table-column>
复制代码
<el-pagination v-if="templateModel.model.listShowPage == 1" background layout="total, sizes, prev, pager, next, jumper" :page-sizes="[10, 20, 50, 100, 500]" :page-size="listQuery.limit" :total="total" @size-change="changeSize" @current-change="fetchPage" @prev-click="fetchPrev" @next-click="fetchNext" />
复制代码
列名资源化是个问题,由于若是让前端不介入的话,那资源化的工做须要彻底放在后端,定义好资源文件后,前端经过接口获取资源并自动合并到资源化词典内。
增删改查能够按照通用的定义一套,若是须要扩展新的按钮,那么以前设计的模型须要增长按钮元数据,这块尚在设计中,有时间再分享。
列表的自定义大体功能基本已经实现了,经过这几回的介绍,你有没有学会呢?
在低代码项目设计中,列表自定义设计和表单自定义设计通常是绕不过的槛,若是你有更好的想法,能够留言。