vue3 - 23.h函数 / 函数式编程

vue3 支持 template 语法,和 JSX / TSX 语法,同样也支持 函数式编程

函数式编程会用到h函数,h函数接收三个参数,分别是:

h("
    1.type 元素类型,
    2.propsOrChildren 数据对象,比如props,attrs,dom props,class 和 style,
    2.children 子节点
")

h函数底层调用的是 createVNode

<template>
  <div>
    index
  </div>
</template>
<script setup lang='ts'>
  import { createVNode,render } from 'vue'
  const div = createVNode("div")
  render(div,document.body)
  console.log(div)
</script>

h函数拥有多种组合方式:

<template>
  <div>
    <dom1></dom1>
    <dom2></dom2>
    <dom3></dom3>
    <dom4></dom4>
    <dom5></dom5>
    <dom6></dom6>
    <dom7></dom7>
    <dom8></dom8>
    <dom9></dom9>
  </div>
</template>
<script setup lang='ts'>
  import { h } from 'vue'

  // <div></div>
  const dom1 = () => {
    return h('div')
  }

  // <div id="app"></div>
  const dom2 = () => {
    return h('div', { id: 'app' })
  }

  // <div class="box">hello</div>
  const dom3 = () => {
    return h('div', { class: 'box', innerHTML: 'hello' })
  }

  // <div width="100"></div>
  const dom4 = () => {
    return h('div', { '.name': 'some-name', '^width': '100' })
  }

  // <div class="case bar" style="color: red;"><div>hello</div></div>
  const dom5 = () => {
    return h('div', { class: [foo, { bar }], style: { color: 'red' } })
  }

  // <div>hello</div>
  // 声明点击函数
  const dom6 = () => {
    return h('div', {
      innerHTML: "hello",
      onClick: () => {
        alert()
      }
    })
  }

  // <div id="box">how are you</div>
  const dom7 = () => {
    return h('div', { id: 'box' }, "how are you")
  }

  // <div><span>hello world</span></div>
  const dom8 = () => {
    return h('div', [h('span', 'hello world')])
  }

  // <div>aaa<span>bbb</span></div>
  const dom9 = () => {
    return h('div', ['aaa', h('span', 'bbb')])
  }

  const foo = "case"
  const bar = true
</script>

案例1:通过 h函数 封装button,并且 props传参

<template>
  <div>
    <Btn text="default" @on-click="handleClick" />
    <Btn text="primary" type="primary" />
    <Btn text="success" type="success" />
    <Btn text="info" type="info" />
    <Btn text="warning" type="warning" />
    <Btn text="danger" type="danger" />
  </div>
</template>
<script setup lang='ts'>
import { h } from 'vue'
type Props = {
  text: string,
  type: string
}
const Btn = (props: Props,ctx:any) => {
  return h('button', { 
    class: ['btn-button',props.type],
    onClick:() => {
      ctx.emit('on-click','aaa')
    }
  }, props.text)
}
const handleClick = (str:string) => {
  alert(str)
}
</script>
<style scoped>
.btn-button {
  padding:8px 15px;
  font-size:14px;
  border:0px;
  cursor: pointer;
  border-radius: 4px;
  background: #ccc;
  margin:0 5px;
}
.primary {
  background: rgb(0, 68, 255);
}
.success {
  background: rgb(0, 255, 76);
}
.info {
  background: rgb(0, 132, 255);
}
.warning {
  background: rgb(255, 166, 0);
}
.danger {
  background: rgb(224, 0, 0);
}
</style>

案例2:通过插槽实现button

<template>
  <div>
    <Btn text="default">default</Btn>
  </div>
</template>
<script setup lang='ts'>
import { h } from 'vue'
type Props = {
  text?: string
}
const Btn = (props: Props,ctx:any) => {
  return h('button', { 
    class: ['btn-button']
  }, ctx.slots.default())
}
</script>
<style>
.btn-button {
  padding:8px 15px;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值