vue 渲染函数和函数式组件

117 阅读1分钟

1.render与createElement方法


   <myhead level="1" title="提示信息" >
      {{title}}
    </myhead>
    
    
    Vue.component('myhead', {
      props: {
        level: {
          type: String,
          required: true
        },
        title: {
          type: String,
          default: ''
        },
      },
      //h 是createElement创建方法的简写
      render(h) {
        const vnode = h(
          'h' + this.level , //动态标签 h1,h2,h3
          {attrs: {title: this.title}}, // 动态设置 prop
          this.$slots.default //获取插槽的内容
        )
        return vnode //每次都通过h方法返回vnode
      }
    })

2.嵌套渲染

    .myClass p{
      color: red;
      border: 1px solid red;
    }
    .myClass img{
      width: 30px;
      height: 30px; 
    } 
<mysection class="myClass" title="提示信息" imgurl="http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" >
      测试内容
    </mysection>
//注意:data-title,class,style就是非prop属性,无需定义相应的prop,这些属性都会被添加到组件的根元素上
Vue.component('mysection', {
      props: {
        title: {
          type: String,
          default: ''
        },
        imgurl: {//注意千万不要用驼峰写法会无效
          type: String,
          default: ''
        }, 
         class: {
          type: String,
          default: ''
        }, 
      },
      render(h) { 
        let children = []  
        //先插入子节点
        children.push(h(
            'p', 
            [this.$slots.default[0],  h('img', { attrs: { 'src' : imgurl } })] 
          ))
        //再插入主信息 
        const vnode = h(
          'div',
          {attrs: {title: title,'class': class}},
          children
        )
        return vnode
      }
    })


image.png

3.函数式组件

定义:

组件没有生命周期方法,没有管理任何状态,也没有监听任何传递给他的状态。
则可以定义他为functional 类型组件,即没有状态组件(没有响应式),也没有实例,不能用this访问上下文
<mysection class="myClass" title="提示信息" imgurl="http://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" >
      测试内容
    </mysection>
//style="color:red;" class="myClass" 此时 style和class不会继承传递下去

Vue.component('mysection', {
      functional:true,
      props: {
        title: {
          type: String,
          default: ''
        },
        imgurl: {
          type: String,
          default: ''
        }, 
      },
      render(h,context) { // 通过传入上下文获取props信息,原来的this取消 
        let {title,imgurl} = context.props
        let children = []  
        //先插入子节点
        children.push(h(
            'p', 
            [context.children[0],  h('img', { attrs: { 'src' :imgurl } })] 
          ))
        //再插入主信息 
        const vnode = h(
          'div',
          {attrs: {title: this.title}},
          children
        )
        return vnode
      }
    })