vue render 3种写法

vue render 3种写法

一,嵌套元素


<script>
export default {
    render: function (h) {
        let self = this
        return h(
            //第一个参数:写一个 HTML 标签名、组件选项对象
            //或者resolve 了上述任何一种的一个 async 函数。必填项。    
            'div',
            //第二个参数:一个与模板中 attribute 对应的数据对象。
            //可选
            {
                // // 与 `v-bind:class` 的 API 相同,
                // 接受一个字符串、对象或字符串和对象组成的数组 可直接在style中使用
                class: {
                    child: true,
                    more: false
                },
              //html属性
                attrs: {
                    id: 'foo',
                    name: 'child',
                    // class: 'child'

                },
                // 事件1直接运行
                // on: {
                //     click:
                //         () => {
                //             console.log('执行');
                //         }
                // },
                  //2
                      on: {
                         click:
                        this.nativeClickHandler //指定methods中方法
                    },
                // 仅用于组件,用于监听原生事件,而不是组件内部使用
                // `vm.$emit` 触发的事件。
                nativeOn: {
                    // click: this.nativeClickHandler
                },
                // 组件 prop
                props: {
                    teext: 'bar'
                },
                style: {
                    color: 'red'
                }
                ,
                //  domProps: {
                //     innerHTML: '我是render渲染的子组件'
                // },
                // 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
                // 赋值,因为 Vue 已经自动为你进行了同步。
                // directives: [
                //     {
                //         name: 'my-custom-directive',
                //         value: '2',
                //         expression: '1 + 1',
                //         arg: 'foo',
                //         modifiers: {
                //             bar: true
                //         }
                //     }
                // ],
                // 如果组件是其它组件的子组件,需为插槽指定名称
                slot: 'name-of-slot',
                // 其它特殊顶层属性
                key: 'myKey',
                ref: 'myRef',
                // 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
                // 那么 `$refs.myRef` 会变成一个数组。
                refInFor: true

            }

             //第三个参数:子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
             //也可以使用字符串来生成“文本虚拟节点”。可选。 
            //可省略不写 domProps: { innerHTML:}  //     domProps: { innerHTML: '我是render渲染的子组件' }
           
            ,
           '我是render渲染的子组件'
            [
                //作用域插槽
                self.$scopedSlots.default({
                    text: this.teext
                }),


                // 添加子标签

                h('h2', '标题'),
                h('div', {
                    class: 'content',
                    attrs: {
                        id: 'content',
                    },
                    on: {
                        click:
                            () => {
                                console.log('执行');
                            }
                    },
                    style: {
                        width: '800px',
                        height: '100px'
                    },
                    domProps: {
                        innerHTML: '我是内容'
                    }
                })

            ]
        )

        // )
    },
    props: {
        teext: {
            type: String,
        }
    },
    data() {
        return {
            a: '1'
        }
    },
    methods: {
        nativeClickHandler() {
            console.log('我是方法');
        }
    },
    created() {
        // console.log(this.teext);
    }
}
</script>

<style lang="scss" scoped>
.child {
    background-color: #5cd727;
    width: 300px;
    height: 200px;
}
</style>

二,返回的是平级(同一层)元素, 用slot插槽;

render(h, context) {

const { icon, title } = context.props

const vnodes = []

if (icon) {

vnodes.push(<svg-icon icon-class={icon}/>) 
} 
if (title) {
 vnodes.push(<span slot='title'>{(title)}</span>) 
} 
return vnodes
 }

三,创建vue组件 ,返回 html模板 - 里面的元素可直接访问 vue组件里的事件、属性

    render: function (h,record) {

            return (
                <div class="renderClass" style='background:#409EFF' onClick={() => 
                this.DisStatus(record)  class={this.isActive ? 'active sidebar-item' : 'sidebar-item'}}
                >
                    {text}
                </div >
            )
    },

oncLick={()=>this.xxx()} 方法后的()不能省略

需要注意最好用函数不是箭头函数,箭头函数this指向问题会使on不能直接使用methods方法,作用域插槽也会报错,具体可查看this的绑定模式

也可直接render(h){}

组件中自定义reader函数组件

我们将组件记为 functional,它无状态(没有 data),无实例(没有 this 上下文)。

在添加 functional: true 之后,组件的 render 函数之间将增加 ctx 参数
组件需要的一切都是通过 ctx 传递,包括:

  • props: 提供 props 的对象
  • children: VNode 子节点的数组
  • slots: slots 对象
  • data: 传递给组件的 data 对象
  • parent: 对父组件的引用
render组件
<script>
export default {
  name: 'RenderCol',
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null
    }
  },
  render (h, ctx) {
    console.log( ctx.props.render(ctx.props.row[ctx.props.column.prop], ctx.props.row, ctx.props.index));
    const params = {
      row: ctx.props.row,
      index: ctx.props.index
    }
    
    if (ctx.props.column) params.column = ctx.props.column
    return ctx.props.render(ctx.props.row[ctx.props.column.prop], ctx.props.row, ctx.props.index)
  }
}
</script>
<template>
//根据上下文定义render位置
<el-table:data="listDate" >
   <template slot-scope="scope" >
    <renderTest v-if="rscope.row.render"  :index="scope.$index" :render="scope.row.render" :row="scope.row" ></renderTest>
  </template>
  </el-dable>
</template>
<script>
import renderTest from './renderTest.vue'
export default {
  name: 'lists',
  components: { renderTest },
  props: {
    listDate: {
      type: Array
    },
  }
}
</script>

使用组件

<template>
  <div class="text">
       <ttable :table="lable"></ttable>

</div>
</template>
<script>
import ttablefrom './ttable.vue'
export default {
  name: 'text',
  components: { ttable},
  data() {
    return {
            topicColumns: [{
                label: "排名", prop: "xmdmc", 
                render: (text) => {
                            if (text <= 3) {
                        return (
                            <div class="renderClass" style='background:#409EFF'
                            >
                                {text}
                            </div >
                        )
                    } else {
                        return (
                            <div class="renderClass" style='background:#C0C4CC'
                            >
                                {text}
                            </div >)
                    }
                }
            },
            { label: "#话题名称", prop: "yskze",  },
            { label: "话题下文章数", prop: "srze", },
         ],
    }
  }
}
</script>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值