vue中创建组件的几种方式,你都会吗?

h函数

h() 函数是用于创建虚拟 DOM 节点的函数。

h() 函数的参数

  • type 参数可以是字符串或组件。如果它是字符串,则表示元素标签名。如果它是组件,则表示要创建的组件。
  • props 参数可以是对象或 null。如果它是对象,则表示元素的属性。如果它是 null,则表示元素没有属性。
  • children 参数可以是数组或 null。如果它是数组,则表示元素的子节点。如果它是 null,则表示元素没有子节点。

h() 函数可以用来创建任何类型的虚拟 DOM 节点,包括元素、文本节点、组件等。

例如要实现如下效果

js 复制代码
import { createApp, h } from '../lib/vue.esm-browser.js'

const app = createApp(h('div', {
    style:{backgroundColor: 'red', width: 'fit-content', height: '50px'}, 
    onClick:()=>alert('父盒子')
}, [
    h('div', null, '子盒子')
]))

app.mount('#app')

render函数

用于编程式地创建组件虚拟 DOM 树的函数。实际内部使用的是h()

js 复制代码
const app = createApp({ 
    render() {
        return h('div', {
            style: { backgroundColor: 'red', width: 'fit-content', height: '50px' },
            onClick: () => alert('父盒子')
        }, [
            h('div', null, '子盒子')
        ])
    }
})

实现的效果和上面的一样

组件的几种形式

对象形式的组件

适用于有构建步骤和无构建步骤的项目

js 复制代码
import { createApp } from '../lib/vue.esm-browser.js' 

const app = createApp({
    template: `
        <h1 style="color:red" @click='handler'>{{count}}</h1>
        <button @click='sumHandler'>{{sum}}</button>
    `,
    setup() {
        let sum = 0
        let sumHandler = () => alert(sum)
        return { sum, sumHandler }
    },
    data() {
        let count = 0
        return { count }
    },
    methods: {
        handler() {
            alert(this.count)
        }
    }
})

app.mount('#app') 

可以把template节点换成render节点,但那样子编写成本会变高,因为你要通过编写h()返回虚拟dom。你也可以直接编写template节点,最后它会被编译为render函数。

单文件组件

适用于有构建步骤的项目

export default 那个对象的写法和对象形式的组件的写法一致

js 复制代码
<template>
	<h1 style="color: red" @click="handler">{{ count }}</h1>
	<button @click="sumHandler">{{ sum }}</button>
</template>

<script>
	import { ref } from 'vue'
    
	export default {
		data() {
			let count = 0
			return { count }
		},
		methods: {
			handler() {
				this.count++
			},
		},
		setup() {
			let sum = ref(0)
			let sumHandler = () => sum.value++
			return { sum, sumHandler }
		},
	}
</script>

<style></style>

另一种写法是在<script setup>节点里编写所有代码,上面的例子完全可以写成这样:

js 复制代码
<template>
	<h1 style="color: red" @click="handler">{{ count }}</h1>
	<button @click="sumHandler">{{ sum }}</button>
</template>

<script setup>
	import { ref } from 'vue'
    
	let count = ref(0)
	let handler = () => count.value++
	let sum = ref(0)
	let sumHandler = () => sum.value++
</script>

<style></style>

函数式组件

函数式组件是一种定义自身没有任何状态的组件的方式。它们很像纯函数:接收 props,返回 vnodes。优点:高性能渲染代码复杂度低。这里不过多介绍这种组件

js 复制代码
<template>
	<CurrentTime mes="props属性" email="attr属性" />
</template>

<script setup>
	import { h } from 'vue'
	let CurrentTime = (props, context) => {
		const now = new Date()
		console.log(props.mes)
		console.log(context.attrs.email)
		return h('div', null, `当前时间:${now.toLocaleString()}`)
	}
	CurrentTime.props = ['mes']
</script>

<style></style>
相关推荐
倾颜1 小时前
从 textarea 到 AI 输入框:用 Tiptap 实现 / 命令、@ 引用和结构化请求
前端·langchain·next.js
kyriewen3 小时前
程序员连夜带团队跑路,省了23万:这AI太贵,真的用不起了
前端·javascript·openai
kyriewen3 小时前
你写的代码没有测试,就像出门不锁门——Jest + Testing Library 从入门到不慌
前端·单元测试·jest
yuzhiboyouye4 小时前
web前端英语面试
前端·面试·状态模式
canonical_entropy5 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
东方小月5 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构
我叫黑大帅5 小时前
为什么需要 @types/react?解决“无法找到模块 react 的声明文件”报错
前端·javascript·面试
之歆6 小时前
DAY_21JavaScript 深度解析:数组(Array)与函数(Function)(一)
前端·javascript
XinZong6 小时前
【AI社交】基于OpenClaw自研轻量化AI社交平台实战
前端
Le_ee7 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php