vue3组件的N种写法

3,800 阅读1分钟

0. 结论

模板最后都会被转成VNode,所以template的不同写法就是生成VNode的不同方式

  • <template></template>
  • render + h
  • render + jsx

1. SFC: 带有模板部分

全局都是简单加法器的实现

<template>
  <div>
    <p>{{count}}</p>
    <button @click="addCount">Add</button>
  </div>
</template>
1.因为vue3向后兼容,所以可以直接使用vue2的方式
export default {
  data() {
    return {
      count: 1
    }
  },
  methods: {
    addCount() {
      this.count++
    }
  }  
}
2. template + defineComponent + setup
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
  setup() {
    const count = ref(1)
    const addCount = () => {
      count.value++
    }
    return {
      count,
      addCount
    }
  }
})
</script>

2.render函数 + h 方式

大部分情况,带有template的组件都能完成你的需求,但有时候你需要完全的js能力。

h是

import { h } from 'vue'

export default {
  data() {
    return {
      count: 1
    }
  },
  render() {
    return h('div', {}, [
      h('p', {}, this.count),
      h('button', {onClick: this.AddCount}, 'Add')
    ])
  },
  methods: {
    AddCount() {
      this.count++
    }
  }
}

3.render函数 + jsx 方式

react中,jsx只是React.createElement的语法糖,vue中也支持jsx来创建vnode

所以将2中的render换成jsx的方式

render() {
  return <div>
    <p>{ this.count }</p>
    <button onClick={ this.AddCount }>Add</button>
  </div>
}

4.functional

vue2中可以在选项中配置functional: true来判断是否是函数组件,vue3中支持直接用plain function定义函数组件,类似reactpureComponent的函数组件。

function (props, context) {
  return <p>{ props.msg }</p>
}

5.对比

  • 相比render函数,SFC的方式写起来更简单,更易读,更重要的是:vue在内部对模板进行了很多优化,比如静态节点优化等等。
  • jsxh函数的语法糖,jsx的优势当然是灵活,可以完全发挥js的编程能力。



写在最后:...多总结...多思考...