渲染函数render

在vue中我们除了可以用template来进行模板化的渲染输出,还可以用render方法进行编程式的渲染

模板有着看起来更易于阅读,更直接的优点,而render方法有着更好的灵活性,但是在vue3中依然保留了这个功能,而且还为Composition Api的编程理念做了调整。

在vue2中,render函数自动接收一个h函数,h作为参数传递进来

<body>
  <div id="app">
      <ren></ren>
  </div>
  <script>
      Vue.component("ren",{
          render(h){
            //   h()其实就是createElement函数的简写
            //第一个是标签名,第二个是标签属性,,第三个是内容
              return h('div',{
                //   给div添加了一个id的属性值为foo
                    attrs:{id:'foo'},
                    style:{color:'red'},  //添加一个行内样式
                    on:{click:this.onClick}//添加一个事件
              },'hello') 
          },
          methods:{
              onClick(){
                  console.log("我是render函数渲染")
              }
          }
      })
      new Vue({
          el:"#app"
      })
  </script>

 

 点击之后也会触发onClick方法

还可以在添加一个domProps属性

render(h){
            //   h()其实就是createElement函数的简写
            //第一个是标签名,第二个是标签属性,,第三个是内容
              return h('div',{
                //   给div添加了一个id的属性值为foo
                    attrs:{id:'foo'},
                    style:{color:'red'},  //添加一个行内样式
                    on:{click:this.onClick},//添加一个事件
                    domProps:{innerHTML:'word'}  //domProps是虚拟dom属性中的一个嵌套链表
              },'hello') 
          },

h函数的三个参数:

  • 第一个参数:类型,组件类型,字符串代表原生节点,对象或者方法表示自定义组件
  • 第二个参数:props 组件(原生节点)的属性,通过对象传入
  • 第三个参数:插槽 slots 组件插槽内容,原生节点的内容

在vue3中渲染函数会变得简单好用,主要的更改有:

  • h是全局导入,而不是作为参数传递给渲染函数
  • 渲染函数参数更改为在有状态组件和函数式组件之间更加一致
  • vnode现在有一个扁平的prop结构

由于render函数不再接收任何参数,它将主要用于setup函数内部,可以访问作用域中声明的响应式状态和函数,以及传递给setup的参数

ren.vue

<script>
import {h, reactive} from 'vue'
export default {
    setup(props,{slots,emit,attrs}){
        const state=reactive({
            count:0
        })
      function fun(){
        state.count++
      }
    //   返回render函数
      return ()=>
       h('div',{ //在vue3中,整个vnode props的结构是扁平的
           onClick:fun,
           class:['box'],
           style:{color:'#555'},
       },state.count)
    }
}
</script>

 

案例:实现一个计数器

count.vue

<script>
import {h,ref} from 'vue'
function useCount(){
   const count=ref(0)
   const increase=()=>{ count.value++ }
   const reset=()=>{count.value=0}
   return {count,increase,reset}
}
export default {
    setup(props,{attrs,emit,slots}){
       const {count,increase,reset} =useCount()
        return ()=>
          h('div',{class:'count'},[
              h('h4',null,'计数器'),
              h('div',{class:'count-main'},[
                  h('span',{class:'count-label'},'已经点击了'),
                  h('span',{class:'count-text'},count.value),
                  h('span',{class:'count-label'},'下')
              ]),
              h('div',{class:'count-btns'},[
                  h('button',{class:'btn',onClick:increase},'计数'),
                  h('button',{class:'btn',onClick:reset},'清零')
              ])
          ])
    }
}
</script>

 

posted @ 2021-11-11 16:28  keyeking  阅读(691)  评论(0编辑  收藏  举报