vue中.render的使用,element-ui里el-table组件动态渲染,jsx语法

难易程度 最易⭐️    难⭐️⭐️⭐️⭐️⭐️  

一:demo的使用:

方式一:(⭐️正常写死)

<h3>方式一</h3>
      <el-table :data="tableData"> 
        <el-table-column prop="name" label="姓名"></el-table-column>
        <el-table-column prop="age" label="年龄"></el-table-column>
      </el-table>
data() {
  return  {
    tableData: [{name: '王小虎',age: 18}, {name: '王小虎',age: 18}],
 }
}

方式二:(⭐️⭐️使用column变量)

<h3>方式二</h3>
      <el-table :data="tableData"> 
        <el-table-column v-for="(item, index) in tableColumns" :key="index" :prop="item.prop" :label="item.label">
          <template slot-scope="scope">
              <my-render v-if="item.render" :render="item.render"></my-render>
              <span v-else>{{ scope.row[item.prop] }} </span>
          </template>
        </el-table-column>
      </el-table>

data() {
  return  {
    tableData: [{name: '王小虎',age: 18}, {name: '王小虎',age: 18}],
    tableColumns: [{prop: 'name', label: '名字'},{prop: 'age', label: '年龄'}]
 }
}


方式三:(⭐️⭐️⭐️使用column变量 + 自定义组件)

<h3>方式三</h3>
      <el-table :data="tableData"> 
        <el-table-column v-for="(item, index) in tableColumns" :key="index" :prop="item.prop" :label="item.label">
          <template slot-scope="scope">
              <my-render v-if="item.render" :render="item.render"></my-render>
              <span v-else>{{ scope.row[item.prop] }} </span>
          </template>
        </el-table-column>
      </el-table>

import myRender from "./component/my-render.vue"
components: {
    myRender
},
data() {
  return  {
    tableData: [{name: '王小虎',age: 18}, {name: '王小虎',age: 18}],
    tableColumns: [{prop: 'name', label: '名字'},{ label: '年龄',render: (h, param) => {return param.row.age;}}]
 }
}

my-render组件   my-render.vue 

<script>
    export default {
        render: (h, ctx) => {
            let elem = <div>{ctx.props.render(h)}</div>;
            return (elem)
        }
    };
</script>

 方式四:(⭐️⭐️⭐️⭐️使用column变量 + 自定义组件 + 传参params的使用)

<h3>方式三</h3>
      <el-table :data="tableData"> 
        <el-table-column v-for="(item, index) in tableColumns" :key="index" :prop="item.prop" :label="item.label">
          <template slot-scope="scope">
              <my-render v-if="item.render"  :sc="scope" :row="scope.row" :render="item.render"></my-render>
              <span v-else>{{ scope.row[item.prop] }} </span>
          </template>
        </el-table-column>
      </el-table>

import myRender from "./component/my-render.vue"
components: {
    myRender
},
data() {
  return  {
    tableData: [{name: '王小虎',age: 18}, {name: '王小虎',age: 18}],
    tableColumns: [{prop: 'name', label: '名字'},{ label: '年龄',render: (h, param) => {return param.row.age;}},// 4、⭐️⭐️⭐️⭐️动态插入标签 + 动态属性值 + 动态属性 + 动态data值 
        {
            label: '操作',
            render: (h, param) => {
                let  redBtn= 'redBtn', bg= 'yellow';
                const elem = <div><button class={redBtn} style={{background: bg}}>删除{param.row.name}</button></div>;
                return (elem);
            }
        },]
 }
}

my-render组件   my-render.vue  

<script>
    export default {
        functional: true,
        props: {
            row: {
                type: Object,
                required: true
            },
            render: {
                type: Function,
                required: true
            },
            sc: {
                type: Object,
                required: true
            }
        },
        render: (h, ctx) => {
            const arr = [];
            const params = {
                row: ctx.props.row,
                index: ctx.props.sc.$index
            };
            const VNode = ctx.props.render(h, params);
            arr.push(VNode);
            return h('div', arr, '');
        }
    };
</script>


二、demo里的方式四的tableColumns的使用写法详解:

      windowName: "cxl",
      tableData: [{name: '王小虎',age: 18}, {name: '王小虎',age: 18}],
      tableColumns: [
        // 1、⭐️直接显示 
        {prop: 'name', label: '名字'},
        // 2、⭐️⭐️添加字符串转换显示 
        {
            label: '年龄',
            render: (h, param) => {
                return param.row.age;
            }
        },
        // 3、⭐️⭐️⭐️动态插入标签显示
        {
            label: '操作',
            render: (h, param) => {
                const elem = <div><button>新增</button></div>;
                return (elem);
            }
        },
        // 4、⭐️⭐️⭐️⭐️动态插入标签 + 动态属性值 + 动态属性 + 动态data值 
        {
            label: '操作',
            render: (h, param) => {
                let  redBtn= 'redBtn', bg= 'yellow';
                const elem = <div><button class={redBtn} style={{background: bg}}>删除{param.row.name}</button></div>;
                return (elem);
            }
        },
        // 5、⭐️⭐️⭐️⭐️⭐️【之jsx写法a】动态插入标签 + 事件显示 
        {
            label: '操作',
            render: (h, param) => {
                let that = this;
                function logFunc() {
                  // console.log("点击删除" + param.row.name, that.windowName)
                  console.log("点击", param) // = {"row": {"name": "王小虎","age": 18},"index": 0}
                }
                const elem = <div><button  onClick={logFunc}>删除</button></div>;
                return (elem);
            }
        },
        // 5、⭐️⭐️⭐️⭐️⭐️【之render函数写法b】动态插入标签 + 事件显示  
        {
            label: '操作',
            render: (h, param) => {  // params是操作返回的 
                const delBtn = h('button', {
                    class: 'operate-btn',
                    domProps: {
                        innerHTML: '删除'
                    },
                    on: {
                        click: () => {
                          // console.log("点击删除" + param.row.name, that.windowName);
                          console.log("点击", param) // = {"row": {"name": "王小虎","age": 18},"index": 0}
                        }
                    }
                });
                return h('div', [delBtn]);
            }
        },
      ]


三、demo里方式四里my-render组件,自定义render组件的写法详解

1、直接返回function

render: (h, ctx) => {
            let elem = <div>{ctx.props.render(h)}</div>;
            return (elem)
        }

2、返回function + params 

props: {
            row: {
                type: Object,
                required: true
            },
            render: {
                type: Function,
                required: true
            },
            sc: {
                type: Object,
                required: true
            }
        },
        render: (h, ctx) => {
            const arr = [];
            const params = {
                row: ctx.props.row,
                index: ctx.props.sc.$index
            };
            const VNode = ctx.props.render(h, params); //parmas 可以把参数传回给二中的tableColumns使用,
            arr.push(VNode);
            return h('div', arr, '');
        },
tableColumns: [
        // 4、⭐️⭐️⭐️⭐️ 操作parmas
        {
            label: 'parmas',
            render: (h, param) => {
                const elem = <div>{param.index} {JSON.stringify(param.row)} </div>;
                return (elem);
            }
        },

<think>好的,我现在需要帮助用户解决如何自定义Element-UI Transfer组件在无数据时的样式并添加图片占位的问题。首先,我得回忆一下Element-UI组件结构和相关文档。根据用户提供的引用,特别是引用[3]提到了Transfer组件的事件,但可能没有直接说明如何修改无数据时的样式。不过用户提到他们想修改无数据时的样式,并插入图片,所以可能需要覆盖默认的CSS或者使用插槽。 首先,Transfer组件的结构可能包含当数据为空时显示的提示信息。我需要检查Element-UI的文档或源码,看是否有相关的插槽(slot)可以用来自定义内容。例如,可能有一个名为empty的插槽,类似于其他组件el-table中的empty插槽。如果存在这样的插槽,用户可以通过插槽插入自定义的HTML,包括图片和样式。 如果官方文档没有明确说明,可能需要查看源码或者参考类似组件的实现。例如,引用[1]中提到在el-button中添加了自定义指令和局部组件,这说明可能需要通过覆盖组件内部的部分结构来实现。但使用插槽可能是更直接的方法。 另外,用户提到引用[4]中关于样式问题,比如fixed属性导致布局错位,这说明在修改样式时需要注意CSS的布局影响。可能需要使用scoped样式或者更具体的选择器来避免冲突。 接下来,我需要考虑具体的实现步骤。可能的步骤如下: 1. 使用Transfer组件提供的插槽来自定义无数据时的显示内容。例如,使用empty插槽或者类似的插槽名称。 2. 在插槽中添加图片和自定义的提示文字,并应用自定义的CSS类。 3. 通过CSS修改样式,调整图片大小、文字颜色等,确保在无数据时显示正确。 如果Transfer组件没有提供这样的插槽,可能需要通过CSS选择器直接覆盖默认的样式。例如,找到无数据时显示的元素的类名,然后通过CSS隐藏原有文本,并通过伪元素添加背景图片。但这种方法可能不够灵活,且容易受到组件版本更新的影响。 另外,可能需要使用Vue渲染函数或JSX来更灵活地插入内容,但用户可能希望用更简单的方式实现,比如模板语法。 总结可能的解决方案: 方案一:使用插槽(如果存在) 检查Transfer组件是否有empty插槽,如果有,使用它插入图片和提示。 方案二:覆盖CSS 通过CSS定位到无数据时的元素,隐藏默认文本,添加背景图片。 方案三:条件渲染 监听Transfer组件的数据,当数据为空时,显示自定义的占位元素,覆盖在Transfer组件上方。 需要验证哪种方法可行。根据Element-UI的文档,Transfer组件是否有相关插槽?查阅Element-UI官方文档,Transfer组件的插槽包括左侧和右侧的面板内容,可能使用left-footer和right-footer,或者是否有默认的empty状态插槽。例如,el-table有empty插槽,但Transfer可能没有明确的插槽。或者可能通过:props传入自定义的render-content函数? 或者,根据引用[3]中的Events部分,可能没有直接提到插槽,但用户可能需要通过CSS来实现。例如,当数据为空时,Element-UI可能在面板中显示“无数据”的文本,可以通过CSS选择器找到该元素,隐藏它,并添加背景图片。 例如,检查生成的DOM结构,找到无数据时的类名,如.el-transfer-panel__empty,然后通过CSS覆盖: .el-transfer-panel__empty { background: url(...) no-repeat center; color: transparent; } 然后在HTML中插入自定义内容,可能需要使用伪元素或绝对定位的div。 或者,在Transfer组件外层包裹一个容器,当数据为空时显示自定义的占位图,否则显示Transfer组件。但这可能会影响布局,因为需要隐藏原有的Transfer组件。 但用户可能希望在Transfer组件原本的位置显示占位图,而不是覆盖在外层。因此,方案二可能更合适,但需要确保CSS正确应用。 另外,可能需要使用/deep/或::v-deep来穿透scoped样式,特别是在Vue的单文件组件中。例如: <style scoped> ::v-deep .el-transfer-panel__empty { background: url(...) no-repeat center; height: 100px; } </style> 这样可以在scoped样式中修改子组件的样式。 结合以上分析,正确的步骤可能是: 1. 使用CSS覆盖.el-transfer-panel__empty的样式,设置背景图片,并调整文字。 2. 可能同时需要隐藏原有的“无数据”文本,通过设置font-size:0或颜色透明。 3. 添加自定义的提示文字,可能需要通过伪元素添加内容,或者使用绝对定位的元素。 例如: .el-transfer-panel__empty { background: url('placeholder.png') no-repeat center / contain !important; color: transparent !important; position: relative; height: 100px; } .el-transfer-panel__empty::after { content: "暂无数据"; position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); color: #999; font-size: 14px; } 但需要验证这个类名是否正确,以及是否能够通过这种方式插入内容。 如果用户无法找到正确的类名,可能需要检查Element-UI生成的DOM结构,使用开发者工具查看无数据时元素的类名,然后进行覆盖。 另外,用户可能需要动态判断数据是否为空,以决定是否应用这些样式。或者,无论数据是否存在,都应用该样式,但图片只在无数据时显示。 综上,回答应该包括以下步骤: - 使用CSS覆盖Transfer面板中的无数据提示区域的样式。 - 设置背景图片并调整布局。 - 隐藏原有文本或替换为自定义内容。 - 可能需要使用插槽或条件渲染,但根据引用中的信息,可能更倾向于CSS方法。 此外,需要注意引用中的内容,引用[1]提到在button组件中添加自定义指令,可能意味着用户对自定义指令有一定了解,但这可能不需要用到指令,而是直接使用CSS或插槽。 最后,生成相关问题,可能需要围绕Element-UI的样式修改、插槽使用、常见问题等提问。</think>### 自定义Element-UI Transfer组件无数据样式的实现方法 #### 步骤说明 1. **定位目标元素** 使用浏览器开发者工具检查无数据时的DOM结构,发现默认显示类名为`.el-transfer-panel__empty`的容器,包含文本"无数据"。 2. **样式覆盖实现** 通过CSS覆盖默认样式并添加背景图(需使用`::v-deep`穿透scoped样式限制): ```html <style scoped> ::v-deep .el-transfer-panel__empty { background: url('your-image.png') no-repeat center/80px auto !important; color: transparent !important; /* 隐藏原文本 */ height: 120px; /* 根据图片调整高度 */ position: relative; } ::v-deep .el-transfer-panel__empty::after { content: "暂无内容"; position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); color: #909399; font-size: 14px; } </style> ``` 3. **动态判断数据状态** 在组件逻辑中监听`data`属性变化,确保样式仅在空数据时生效: ```javascript watch: { dataSource(newVal) { if (newVal.length === 0) { this.$nextTick(() => { // 强制触发样式更新 }) } } } ``` #### 实现效果 - 数据为空时显示自定义图片和提示文字 - 保留Transfer组件原有布局结构 - 支持响应式尺寸调整
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值