Vue3中使用render函数实例代码,对照官网文档,补全官网例子

<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8" />
	<title></title>
	<script src="https://unpkg.com/vue@next"></script>
	<link rel="stylesheet" type="text/css" href="./css/style.css" />
	<style>

	</style>
</head>

<body>
	<div id="app">
		<custom-input :model-value="searchText" @update:model-value="searchText=$event"></custom-input>
		{{ searchText }}
		<custom-list :items="items"></custom-list>
		<custom-div :text="searchText">
			<!-- cool -->
			<!--相当于 <template v-slot:default>
				cool
			</template> -->
			<template #default>
				default slot<br>
			</template>
			<template #header>header slot</template>
		</custom-div>

		<custom-div-1 :title="person"></custom-div-1>
		
		<todo-list v-slot="slotProps">
				<span style="color: green;">{{slotProps.item}}</span>
		</todo-list>
		
	</div>
</body>
<script>
	const app = Vue.createApp({
		data() {
			return {
				items: [{ name: 'Jack' }, { name: 'Pony' }],
				searchText: 'Null',
				person: { name: 'Jack' }
			}
		},
		methods: {
			change(value) {
				// console.log(value)
				this.searchText = value
			}
		},
		// render函数使用 example2
		// render() {
		// 	//<todo-list v-slot="slotProps"><span>{{slotProps.item}}</span></to-list>
		// 	return Vue.h(Vue.resolveComponent('todo-list'), {}, {
		// 		default: (slotProps) => {
		// 			console.log(slotProps.item)
		// 			return Vue.h('span', slotProps.item)
		// 		}
		// 	})
		// }

	})

	//render函数中渲染子组件
	app.component('custom-list', {
		props: ['items'],
		methods: {
			show() {
				console.log("cool");
			}
		},
		render() {
			if (this.items.length) {
				return Vue.h('ul', this.items.map((item) => {
					return Vue.h(
						'li',
						//用到Vue.resolveComponent方法
						[
							item.name,
							Vue.h(Vue.resolveComponent('custom-input'), {
								modelValue: item.name,
								//监听子组件事件	
								'onUpdate:modelValue': value => { item.name = value }
							},

							)]
					)
				}
				))
			}
		}
	})
	
	//组件中使用v-model 用render函数方式实现
	app.component('custom-input', {
		props: ['modelValue'],
		emits: ['update:modelValue'],
		render() {
			return Vue.h('input', {
				value: this.modelValue,
				//发起事件
				'onInput': event => this.$emit('update:modelValue', event.target.value)
			},
			)
		}
	})

	//render 函数中的插槽使用
	app.component('custom-div', {
		props: ['text'],
		render() {
			// `<div><slot></slot></div>`
			return Vue.h('div', [this.$slots.default(), this.$slots.header()])
		},

	})



	app.component('child', {
		props: ['item'],
		// 插槽属性(插槽prop)
		//`<div><slot :item="item"></slot></div>`
		// 父组件即child 可以通过 slotProps.item来访问子组件的item (slotProps名称可变,看父组件中如何定义)
		render() {
			return Vue.h('div', {}, this.$slots.default({
				item: this.item
			}))
		}
	})

	//将插槽传递给子组件
	app.component('custom-div-1', {
		props: ['title'],
		render() {
			//使用渲染函数将插槽传到子组件 span组件中去
			//`<div><child item='title' v-slot="slotProps"><span>{{slotProps.item.name}}</span></child></div>`
			return Vue.h('div', [
				Vue.h(
					Vue.resolveComponent('child'),
					{
						item: this.title
					},
					// 将插槽传递到子组件 
					{
						default: (slotProps) => Vue.h('span', slotProps.item.name)
					}

				)
			])
		}
	})

	//render函数使用 example2
	//实现作用域插槽中的例子
	app.component('todo-list', {
		data() {
			return {
				items: ['Feed a cat', 'Buy milk'],
			}
		},
		// <ul>
      	// 	<li v-for="(item, index) in items">
        // 	{{ item }}
      	// 	</li>
    	// </ul>
		//  ===>
		// <ul>
      	// 	<li v-for="(item, index) in items">
        // 	<slot :item="item"><slot>
      	// 	</li>
    	// </ul>
		render() {
			return Vue.h('ul', this.items.map((item)=>{
				return Vue.h('li', Vue.h('span', {}, 
					this.$slots.default({
						item: item
					})		
				))
			}))
		}
	})




	const vm = app.mount("#app")

</script>

</html>
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页