目录
一般后台管理系统,通常页面都有增删改查;而查不外乎就是渲染新增/修改的数据(由输入框变成输入框禁用),因为输入框禁用后颜色透明度会降低,显的颜色偏暗;为解决这个需求于是封装了详情组件

- 操作按钮自定义
- 字典类型(即后台返回的是数字类型)过滤转成中文
- 自定义模版 数组类型 对象类型
- 渲染图片
<orderDetail :descList="detailModule" :data="renderData"></orderDetail>
- * [
- * {
- * title:String 分类标题
- * column:Number 每行几个(默认2)
- * size:String 大小 medium / small / mini(默认 medium)
- * border:Boolean边框(默认true)
- * keyArr:[
- * {
- * icon:String,(描述标题的图标)
- * label:String,描述标题
- * keyName:String(对应的翻译值)
- * innerKey:String 数组时对应的翻译值
- * detailType:"image"渲染图片
- * formatter:Function :自定义渲染
- * getTranslation:Function:为对象时处理翻译的值
- * }
- * ]
- * extra:{ '操作按钮'
- * text:String(按钮文案)
- * methods:function(方法回调)
- * }
- * }
- * ]
- <template>
- <div class="detail-box demo-image__error cell-44">
- <el-descriptions v-for="(item, index) in descList" :border="item.border || true" :key="'descList' + index"
- class="mb20" :title="item.title || ''" :column="item.column || 2" labelClassName="custom-label"
- contentClassName="custom-content" :size="item.size || 'medium'">
- <template slot="extra" v-if="item.extra">
- <el-button type="primary" size="small" @click="item.extra.methods(item, index)">{{ item.extra.text }}</el-button>
- </template>
- <!-- 描述title -->
- <el-descriptions-item v-for="(descKey, innerIndex) in item.keyArr" :key="innerIndex + 'desc'">
- <template slot="label" v-if="descKey.label">
- <i class="el-icon-user" v-if="item.icon"></i>
- {{ descKey.label }}
- </template>
- <!-- 图片类型数据 -->
- <div class="cell" v-if="descKey.detailType == 'image'">
- <el-image style="width: 44px; height: 44px" :src="data[descKey.keyName]">
- <div slot="error" class="image-slot">
- <i class="el-icon-picture-outline"></i>
- </div>
- </el-image>
- </div>
- <!-- 自定义模版 -->
- <div v-else-if="descKey.formatter" v-html="descKey.formatter(data)"></div>
- <!-- 数组对象、或数组 -->
- <template v-else-if="Array.isArray(data[descKey.keyName])">
- <el-tag v-for="(innerItem, innerI) in data[descKey.keyName]" :key="'tag' + innerI" size="small"
- class="mr10 mb10">
- {{ (descKey.innerKey ? innerItem[descKey.innerKey] : innerItem) || "--" }}
- </el-tag>
- </template>
- <!-- 默认键值对 -->
- <span v-else-if="(data[descKey.keyName] || data[descKey.keyName] === 0) &&
- typeof data[descKey.keyName] !== 'object'
- ">
- {{
- data[descKey.keyName] || data[descKey.keyName] == 0
- ? data[descKey.keyName]
- : "--"
- }}
- </span>
- <!-- 对象类型数据 -->
- <span v-else-if="typeof data[descKey.keyName] === 'object'">
- <el-descriptions :data="data[descKey.keyName]" :border="false">
- <el-descriptions-item v-for="(value, key) in data[descKey.keyName]" :key="key">
- <template slot="label">{{ descKey.getTranslation(key, index) }}</template>
- <span>{{ value }}</span>
- </el-descriptions-item>
- </el-descriptions>
- </span>
- <!-- 没有匹配项目 -->
- <span v-else>--</span>
-
- </el-descriptions-item>
- </el-descriptions>
- </div>
- </template>
-
- <script>
- export default {
- props: {
- /**
- * [
- * {
- * title:String 分类标题
- * column:Number 每行几个(默认2)
- * size:String 大小 medium / small / mini(默认 medium)
- * border:Boolean边框(默认true)
- * keyArr:[
- * {
- * icon:String,(描述标题的图标)
- * label:String,描述标题
- * keyName:String(对应的翻译值)
- * innerKey:String 数组时对应的翻译值
- * detailType:"image"渲染图片
- * formatter:Function :自定义渲染
- * getTranslation:Function:为对象时处理翻译的值
- * }
- * ]
- * extra:{ '操作按钮'
- * text:String(文案)
- * methods:function(方法回调)
- * }
- * }
- * ]
- */
- descList: {
- type: Array,
- default: () => {
- return [];
- },
- },
- data: {
- type: Object,
- default: () => {
- return {};
- },
- },
- },
- };
- </script>
-
- <style lang="scss">
- .custom-label,
- .custom-content {
- width: 25% !important;
- }
-
- .demo-image__error .image-slot,
- .demo-image__placeholder .image-slot {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
- background: #f5f7fa;
- color: #909399;
- font-size: 14px;
- }
-
- .cell-44 {
- .cell {
- height: 44px;
- line-height: 44px;
- }
- }
- </style>
- <template>
- <div class="table-page">
- <FormDetail :descList="detailModule" :data="renderData"></FormDetail>
- </div>
- </template>
- <script>
- import FormDetail from "@/components/FormDetail/details.vue";
- export default {
- components: {
- FormDetail,
- },
- data() {
- return {
- detailModule: [
- {
- translations: { age: "年龄", name: '姓名' },
- title: "信息",
- keyArr: [
- { label: "账户名称", keyName: "AccountName" },
- { label: "账户id", keyName: "AccountId" },
- { detailType: 'image', label: '头像', keyName: 'image' },
- {
- formatter: (data) => {
- console.log(data, '------');
- return `<span style="white-space: nowrap;color: dodgerblue;">${data.status}</span>`;
- },
- label: '自定义',
- },
- { label: '数组', keyName: 'list', innerKey: 'asList' },
- {
- label: "测试", keyName: "obj",
- getTranslation: (key, index) => {
- return this.detailModule[index].translations[key] || key; // 如果找不到翻译,返回键本身
- }
- }
- ],
- extra: {
- text: 'text',
- methods: (item, index) => {
- console.log(item, index);
- }
- },
-
-
- },
- ],
- renderData: {
- AccountId: "1",
- AccountName: "张三",
- image: 'https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png',
- status: '开启',
- list: [
- { asList: "5" },
- { status: "5" },
- { asList: "5" },
- ],
- obj: {
- age: 8,
- name: 'zs',
- sex: 'nan',
- }
- },
- }
- },
- };
- </script>