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>