1. Что такое функция рендеринга
Проще говоря, в vue мы используем шаблонный синтаксис HTML для создания страниц, а с помощью функции рендеринга мы можем использовать язык js для построения DOM. Поскольку vue — это виртуальный DOM, когда вы получаете шаблон шаблона, вы также должны перевести его в функцию VNode и использовать функцию рендеринга для построения DOM, vue избегает процесса перевода.
При использовании функции рендеринга для описания виртуального DOM Vue предоставляет функцию, которая является инструментом, необходимым для построения виртуального DOM. Официальный сайт дал ему имя createElement. Существует также соглашение, что его аббревиатура называется h
[1] Использование формы компонентов
// 父组件
<template>
<div>
<child1 :level='level'>我是标题</child1>
</div>
</template>
<script>
const child1 = () => import("./child1.vue");
export default {
components: { child1 },
data() {
return {
level: 1
};
},
};
</script>
// 子组件 child1.vue
<template>
<div>
<h1 v-if="level == 1">
<slot></slot>
</h1>
<h2 v-if="level == 2">
<slot></slot>
</h2>
<h3 v-if="level == 3">
<slot></slot>
</h3>
<h4 v-if="level == 4">
<slot></slot>
</h4>
<h5 v-if="level == 5">
<slot></slot>
</h5>
<h6 v-if="level == 6">
<slot></slot>
</h6>
</div>
</template>
<script>
export default {
props: {
level: {
require: true,
type: Number,
}
}
};
</script>
[2] Использовать форму функции рендеринга (изменить подкомпонент child1)
<script>
export default {
props: {
level: {
require: true,
type: Number,
}
},
render(createElement) {
return createElement('h' + this.level, this.$slots.default);
}
};
</script>
Сравнив две реализации, мы обнаружили, что использование шаблона — не лучший выбор, мало того, что код многословен, так еще и
повторяется в названии каждого уровня. Кажется намного проще реализовать с помощью функции рендеринга, поэтому код намного проще, но вы должны быть хорошо знакомы со свойствами экземпляра Vue. В этом примере вам нужно знать, что при передаче дочерних узлов без директивы v-slot компоненту, например «Я — титул» в child1, эти дочерние узлы сохраняются в this.$slots.default в экземпляре компонента. середина.
Во-вторых, параметры функции рендеринга
Функция рендеринга — это функция рендеринга, это функция, и возвращаемое значение функции рендеринга — это VNode (т. е. виртуальный узел, который является узлом, который мы хотим отобразить).
createElement — это аргумент функции рендеринга, которая сама является функцией и имеет три аргумента. Далее мы сосредоточимся на этих трех параметрах
[1] Первый параметр createElement обязателен и может быть String | Object | Function
- Строка, представляющая имя тега HTML
- Object , объект параметров компонента, содержащий данные
- Function , которая возвращает асинхронную функцию с именем тега или объектом опций компонента.
Пример:
render: function (createElement) {
// String
return createElement('h1');
//Object
return createElement({
template: " <div>锄禾日当午</div> "
})
// Function
let domFun = function () {
return {
template: " <div> 锄禾日当午</div> "
}
}
return createElement(domFun())
}
[2] Второй параметр createElement является необязательным, это объект данных, соответствующий атрибуту в шаблоне.Обычно используются class | style | attrs | domProps | on
- класс: имя класса управления
- стиль : стиль
- attrs : используется для записи обычных атрибутов html id src и т. д.
- domProps: используется для записи собственных свойств dom.
- on:: используется для написания нативных методов
return createElement('div', {
// 与 `v-bind:class` 的 API 相同,
// 接受一个字符串、对象或字符串和对象组成的数组
'class': {
foo: true,
bar: false
},
// 与 `v-bind:style` 的 API 相同,
// 接受一个字符串、对象,或对象组成的数组
style: {
color: 'red',
fontSize: '14px'
},
// 普通的 HTML 特性
attrs: {
id: 'foo'
},
// 组件 prop
props: {
myProp: 'bar'
},
// DOM 属性
domProps: {
innerHTML: 'baz'
},
// 事件监听器在 `on` 属性内,
// 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
// 需要在处理函数中手动检查 keyCode。
on: {
click: this.clickHandler
},
// 仅用于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// 作用域插槽的格式为
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其它组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其它特殊顶层属性
key: 'myKey',
ref: 'myRef',
// 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
// 那么 `$refs.myRef` 会变成一个数组。
refInFor: true
})
[3] Третий параметр createElement является необязательным и представляет дочерний виртуальный узел (VNodes), который создается с помощью `createElement()`. Обычно он получает строку или массив. Как правило, массив использует больше
return createElement('div', {
attrs: {
id: "content"
}
}, [
createElement('h1', '我是H1标题'),
createElement('h6', '我是H6标题')
]
)
3. Использование v-модели в функции рендеринга
В функции рендеринга не предусмотрена реализация v-model, поэтому вам придется реализовывать соответствующую логику самостоятельно. Это цена углубления, но это дает вам больше контроля над деталями взаимодействия, чем v-model.
<template>
<div>
<child1 :name='name' v-model="name"></child1>
<p>{{name}}</p>
</div>
</template>
<script>
const child1 = () => import("./child1.vue");
export default {
components: { child1 },
data() {
return {
name: 'Demi'
};
},
};
</script>
// child1子组件
<script>
export default {
props: {
name: {
require: true,
}
},
render(createElement) {
let self = this
return createElement('input', {
domProps: {
value: self.name
},
on: {
input(event) {
self.$emit('input', event.target.value)
}
}
})
}
};
</script>
Результат выглядит следующим образом:
Функция рендеринга реализует двустороннюю привязку данных через метод ввода: при изменении имени дочернего компонента родительский компонент также обновляется вместе с ним.
В-четвертых, модификатор события в функции рендеринга
Для модификаторов событий, таких как .passive, .capture и .once, Vue предоставляет соответствующие префиксы, которые можно использовать дляon
| модификатор | префикс |
|---|---|
.passive |
& |
.capture |
! |
.once |
~ |
.capture.onceили.once.capture
|
~! |
on: {
'!click': this.doThisInCapturingMode,
'~keyup': this.doThisOnce,
'~!mouseover': this.doThisOnceInCapturingMode
}
5. Синтаксический сахар JSX
JSX — это формат, сочетающий Javascript и XML. React изобрел JSX, используя синтаксис HTML для создания виртуального DOM. Когда он встречает
Сложные функции рендеринга очень сложно писать, поэтому существует плагин Babel для использования синтаксиса JSX в Vue, который возвращает нас к чему-то более близкому к шаблонам.
render(h) {
return (
<Child1 level={1}>
<span>Hello</span> world!
</Child1>
)
}
Использование h в качестве псевдонима для createElement является распространенным соглашением в экосистеме Vue и фактически требуется для JSX. Начиная с версии 3.4.0 плагина Babel для Vue, мы автоматически внедряем const h = this.$createElement в любой метод и геттер, объявленные в синтаксисе ES2015, которые содержат JSX (но не в функциях или стрелочных функциях), поэтому вы можете (h ) параметр удален. Для более ранних версий плагина приложение выдаст ошибку, если h недоступен в текущей области.
Документ для изучения грамматики JSX:vuejs/JSX Введение в синтаксис JSX
Статья постоянно обновляется каждую неделю, вы можете искать в WeChat "Особенности интерфейса"Прочтите это в первый раз, ответьте [видео】【книги】 Получите 200 ГБ видеоматериалов и 30 книг в формате PDF.