vue - render 參數詳解


父組件

<template>
   <div>
      <vueRender msg="Render Test" :level="3" :items="items">
	 <div class="header">default header</div>
	 <p slot="header">slot header</p>
      </vueRender>   
   </div>
</template>

<script>
import vueRender from './vue-render.vue'
export default {
    name: 'app',
    components: { vueRender },
    data() {
      return {
	items: [{
	  name: 'hello'
	},
	{
	  name: 'vue'
        },
	{
	  name: 'js'
	}]
     }
   }
}
</script>

<style>
</style>

子組件

<template>
	<div class="render">
		<h1>{{ msg }}</h1>
		<renderComponent></renderComponent>
		<renderComponentList></renderComponentList>
	</div>
</template>

<script>
	export default {
		name: 'RenderTest',
		props: {
			msg: String,
			level: {
				type: Number,
				required: true
			},
			items: {
				type: Array,
				required: false
			}
		},
		components: {
			renderComponent: {
				/**
				 * render: 渲染函數
				 * 參數: createElement
				 * 參數類型: Function
				 */
				render: function(createElement) {
					let _this = this['$options'].parent // 我這個是在 .vue 文件的 components 中寫的,這樣寫才能訪問this
					let _header = _this.$slots.header // // $slots: vue中所有分發插槽,不具名的都在default里
					/**
					 * createElement 本身也是一個函數,它有三個參數
					 * 
					 * 返回值: VNode
					 * 
					 * 1. 一個 HTML 標簽字符串,組件選項對象,或者解析上述任何一種的一個 async 異步函數。必需參數。{String | Object | Function} - 就是你要渲染的最外層標簽
					 * 
					 * 2. 一個包含模板相關屬性的數據對象你可以在 template 中使用這些特性。可選參數。{Object} - 1中的標簽的屬性
					 * 
					 * 3. 子虛擬節點 (VNodes),由 `createElement()` 構建而成,也可以使用字符串來生成“文本虛擬節點”。可選參數。{String | Array} - 1的子節點,可以用 createElement() 創建,文本節點直接寫就可以
					 */
					return createElement(
						'h' + _this.level, // 標簽名稱 - 第一個參數
						{
							style: {
								color: 'gray',
								border: '1px solid pink'
							},
							class: { // 樣式類名 例如 cassname就是樣式類名
								cassname: true
							},
							// 正常的 HTML 特性
							attrs: {
								id: 'foo'
							},
							// 組件 props
							props: {
								myProp: 'bar'
							},
							// DOM 屬性
							domProps: {
								innerHTML: 'baz',
								value: '' // input select 
							},
							//  事件監聽器基於 `on`
							on: { // 綁定事件
								click: () => {
									console.log('點擊事件')
								},
								input: (event) => { // 用於input
									self.$emit('input', event.target.value)
								}
							},
							// 僅對於組件,用於監聽原生事件,而不是組件內部使用
							// `vm.$emit` 觸發的事件。
							nativeOn: {
								click: this.nativeClickHandler
							},
							// 自定義指令。注意,你無法對 `binding` 中的 `oldValue`
							// 賦值,因為 Vue 已經自動為你進行了同步。
							directives: [
								{
									name: 'my-custom-directive',
									value: '2',
									expression: '1 + 1',
									arg: 'foo',
									modifiers: {
										bar: true
									}
								}
							],
							// Scoped slots in the form of
							// { name: props => VNode | Array<VNode> }
							scopedSlots: {
								default: props => createElement('span', props.text)
							},
							// 如果組件是其他組件的子組件,需為插槽指定名稱
							slot: 'name-of-slot',
							// 其他特殊頂層屬性
							key: 'myKey',
							ref: 'myRef'
						}, // 第二個單數
						[
							'text', // 文本節點直接寫就可以
							_this.$slots.default, // 默認插槽
							createElement('div', _header)   // 具名插槽  createElement()創建的VNodes
						] // 子元素數組 - 第三個參數 也可以直接  文本'text'
					)
				}
			},
			renderComponentList: {
				render: function(createElement) {
					let _this = this['$options'].parent
					if (_this.items.length) {
						return createElement(
							'ul',
							_this.items.map(function(item) {
								return createElement('li', item.name)
							})
						)
					} else {
						return createElement('p', 'No items found.')
					}
				}
			}
		}
	}
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM