Ты пришел с фронта, ты должен знать фронт. Требования время от времени меняются, и ошибки не могут быть исправлены.
Несколько статей подряд, каждая с богиней, копатели жаловались, и сегодня я не буду упоминать богиню, все равно, богиня чужая (убитая горем). В последние два дня редактор наблюдал за делами Tencent и Laoganma, и ему очень интересно есть паровой хлеб с Laoganma ночью. Сегодняшняя статья даст вам некоторый практический опыт использования JSX в проекте. На самом деле обычно пишутVue
Все еще рекомендуюtemplate
Способ написания, но иногда нам действительно нужно быть более гибкими, чтобы выполнять некоторые функции, тогда нам нужно использоватьJSX
.
Читайте наши последние хиты
Vue
За статьи по теме, спасибо за поддержку и группу друзей, до встречи каждый понедельник
Впереди высокая энергия, это последняя волна боевых навыков Vue, это бесполезно и потрясающе.900+ лайков
Практические навыки, Vue тоже умеет так писать2300+ лайков
Абсолютно сухой материал~! Изучите эти советы Vue, вы сможете уйти с работы пораньше и встречаться с богиней1100+ лайков
Смотрите заработало! Перечитывая руководство по стилю vue 2.0, я сформулировал эти ключевые правила.Понравилось 140+
представлятьJSX
Введение в JSX
JSX — это синтаксическое расширение Javascript,JSX
= Javascript
+ XML
, то есть вJavascript
написать внутриXML
,потому чтоJSX
Это свойство , поэтому он имеетJavascript
гибкость и одновременноhtml
Семантический и интуитивно понятный.
Сценарии применения
Чтобы всем было понятноJSX
Роль и использование, Xiaobian сначала перечислил несколько для вас, которые могут быть использованыJSX
сценарии применения.
добавить в окно сообщенияhtml
В процессе разработки часто используется окно сообщения, и возможный способ использования окна сообщения следующий.
Message.alert({
messge: '确定要删除?',
type: 'warning'
})
Но иногда продукт или пользовательский интерфейс требуютmessage
Вы можете настроить некоторые стили, в этом случае вам может понадобиться сделатьMessage.alert
служба поддержкиJSX
(конечно, вы также можете использовать слот /html
и так далее)
Message.alert({
// 此处使用了JSX
messge: <div>确定要删除<span style="color:red">学习子君Vue系列文章</span>的笔记?</div>,
type: 'warning'
})
функциональные компоненты
Статьи перед редакторомПрактические навыки, Vue тоже умеет так писатьОбъясняет, зачем использовать функциональные компоненты, а также разницу между функциональными компонентами и обычными компонентами. Хотя вVue.2.5
После этого функциональные компоненты также могут использовать синтаксис шаблона, но использоватьJSX
Может быть удобнее (личное понимание)
export default {
// 通过配置functional属性指定组件为函数式组件
functional: true,
/**
* 渲染函数
* @param {*} h
* @param {*} context 函数式组件没有this, props, slots等都在context上面挂着
*/
render(h, context) {
const { props } = context
if (props.avatar) {
return <img src={props.avatar}></img>
}
return <img src="default-avatar.png"></img>
}
}
требование к форме
Чтобы облегчить быструю разработку системы управления, редактор инкапсулирует формы в библиотеке пользовательского интерфейса, используемой дважды.Эффект после инкапсуляции выглядит следующим образом (только для справки):
<template>
<custom-form v-model="formData" :fields="fields" />
</template>
<script>
export default {
data() {
return {
formData: {},
fields: Object.freeze([
{
label: '字段1',
props: 'field1',
type: 'input'
},
{
label: '字段2',
props: 'field2',
type: 'number'
}
])
}
}
}
</script>
После этой инкапсуляции при определении формы вам нужно только определить простойJSON
Вы можете быстро завершить разработку формы, но иногда есть некоторые особые требования, такие как добавление кнопки или значка в конце поля ввода, тогда вам нужно рассмотреть возможность использованияJSX
иметь дело с
{
label: '字段2',
props: 'field2',
type: 'number',
// 会渲染到表单元素后面
renderSuffix() {
return <button onClick={this.$_handleSelect}>选择</button>
}
}
некоторые другие сцены
Например, нам нужно определить различные методы представления для фрагмента данных в соответствии с различными состояниями.В настоящее время вы можете подумать об использовании режима стратегии.В настоящее время, если каждая стратегия написана какJSX
, то нет необходимости определять однофайловый компонент для каждой политики. Конечно, если вы говорите, мне нравится использоватьJSX
, то вы можете использовать его во всех сценариях.
Чтобы сделать чтение более удобным, когда вы читаете следующий контент, рекомендуется сначала щелкнуть значок большого пальца на левой стороне компьютера или внизу мобильного телефона, чтобы сделать цвет страницы более насыщенным.
УчитьJSX
, сначала поймиcreateElement
упомянулJSX
, нельзя не упомянутьcreateElement
, Когда вы прочитаете этот раздел, вы обнаружите, что странные знания увеличились.
отVue
Посмотрите на скомпилированный кодcreateElement
Вы читали написанноеVue
Код выглядит после компиляции, например, следующий код
<template>
<div>我是子君,我的公众号是<span class="emphasize">前端有的玩</span></div>
</template>
После компиляции этого кода я получаю следующий код
function () {
var e = this,
// e._self._c 对应源码里面的createElement
t = e._self._c;
// 返回了一个 createElement('div',[])
return t("div", [
// e._v 对应源码里面的createTextVNode
e._v("我是子君,我的公众号是"),
t("span", { staticClass: "emphasize" }, [e._v("前端有的玩")]),
]);
}
Анализируя приведенный выше код, нетрудно обнаружить, чтоVue
Каждый элемент в шаблоне будет соответствоватьcreateElement
, то этоcreateElement
Какого черта, ну, вы могли упомянуть об этом во время интервью.
Так что жеcreateElement
Будь тоVue
ещеReact
, оба существуютcreateElement
, и эффект в основном тот же. может быть ты правcreateElement
Я не очень хорошо это знаю Перевод имени функции - добавить элемент, но вы должны знать его возвращаемое значение.createElement
Значение, возвращаемое функцией, называется виртуальным узлом, т. е.VNode
, а поVNode
Дерево, образованное в результате собраний, известно, и его нужно задать на собеседовании.虚拟DOM
.
createElement
Параметры функции, здесь Xiaobian ворует ленивую копиюVue
официальная документация
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签名、组件选项对象,或者
// resolve 了上述任何一种的一个 async 函数。必填项。
'div',
// {Object}
// 一个与模板中 attribute 对应的数据对象。可选。
{
// (详情见下一节)
},
// {String | Array}
// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
// 也可以使用字符串来生成“文本虚拟节点”。可选。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
Как видно из вышеизложенногоcreateElement
Всего есть три параметра, три параметра
-
Первый параметр — это компонент, который необходимо визуализировать, это может быть метка компонента, например
div
; или компонентный объект, который вы пишете каждый деньexport default {}
; или может быть асинхронной функцией. -
Второй параметр это атрибут этого компонента, который является объектом, если у компонента нет параметров, то можно передать null (атрибуты компонента будут введены по очереди)
-
Третий параметр — это дочерний компонент этого компонента, который может быть строкой (textContent) или массивом VNodes.
использоватьcreateElement
написать компонент
пример формы
Предположим, нам нужно разработать форму, подобную следующей (element-ui)
Разработка с кодом шаблона
Если мы используем код шаблона для разработки этой формы, код, вероятно, будет выглядеть так:
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.region" placeholder="活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
использоватьcreateElement
реализовать
Если мы напрямую преобразуем приведенный выше код для использованияcreateElement
реализовать, то код будет таким
export default {
methods: {
$_handleChangeUser(value) {
this.formInline.user = value
}
},
render(createElement) {
return createElement(
'ElForm',
{
props: {
inline: true,
model: this.formInline
},
staticClass: 'demo-form-inline'
},
[
createElement(
'ElFormItem',
{
props: {
label: '审批人'
}
},
[
createElement('ElInput', {
props: {
value: this.formInline.user
},
attrs: {
placeholder: '审批人'
},
on: {
input: this.$_handleChangeUser
}
})
]
),
createElement(
'ElFormItem',
{
props: {
label: '活动区域'
}
},
[
createElement(
'ElSelect',
{
props: {
value: this.formInline.region,
placeholder: '活动区域'
}
},
[
createElement('ElOption', {
props: {
label: '区域一',
value: 'shanghai'
}
}),
createElement('ElOption', {
props: {
label: '区域二',
value: 'beijing'
}
})
]
)
]
),
createElement('ElFormItem', null, [
createElement(
'ElButton',
{
props: {
type: 'primary'
},
on: {
click: this.$_handleSubmit
}
},
'查询'
)
])
]
)
}
}
Когда вы видите приведенный выше код, вы можете воскликнуть, там так много кода, это так больно, я хочу изобрести его тогдаJSX
Люди, которые только начали писать каждый деньcreateElement
, Писать прямые волосы было слишком больно, и тогда я сильно почесал затылок.Когда мой лоб блестел, я, наконец, подумал о новом синтаксисе, которым является JSX. После этого волосы снова отрастают (этот абзац чисто выдуманный).
Глядя на приведенный выше код, вы обнаружите, что существуетrender
функция, эта функция называется функцией рендеринга, что эквивалентно передачеcreateElement
илиJSX
Основной метод входа для реализации функции. и вы знакомы сv-model
тоже не видел, но пользуюсьvalue
+ input
вместо.
пора использоватьJSX
заменятьcreateElement
охватывать
см. выше сcreateElement
Реализовать компоненты слишком хлопотно, не говоря уже об улучшении эффективности работы, здорово, что эти вложения можно правильно вложить, поэтому нужно использоватьJSX
упростить всю логику.
methods: {
$_handleInputUser(value) {
this.formInline.user = value
},
$_handleChangeRegion(value) {
this.formInline.region = value
},
$_handleSubmit() {}
},
/**
*将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。从 Vue 的 Babel 插件的 3.4.0 *版本开始,我们会在以 ES2015 语法声明的含有 JSX 的任何方法和 getter 中 (不是函数或箭头函数中) 自动注入
*const h = this.$createElement,这样你就可以去掉 (h) 参数了。对于更早版本的插件,如果 h 在当前作用域中不可用,应用会抛错。
*/
render(h) {
return (
<ElForm inline model={this.formInline} class="demo-form-inline">
<ElFormItem label="审批人">
<ElInput
value={this.formInline.user}
onInput={this.$_handleInputUser}
placeholder="审批人"
></ElInput>
</ElFormItem>
<ElFormItem label="活动区域">
<ElSelect
value={this.formInline.region}
onChange={this.$_handleChangeRegion}
placeholder="活动区域"
>
<ElOption label="区域一" value="shanghai"></ElOption>
<ElOption label="区域二" value="beijing"></ElOption>
</ElSelect>
</ElFormItem>
<ElFormItem>
<ElButton type="primarty" onClick={this.$_handleSubmit}>
查询
</ElButton>
</ElFormItem>
</ElForm>
)
}
Прочитав приведенный выше код, вы на самом деле обнаружите, что использованиеJSX
а такжеtemplate
грамматика принадлежитxml
Способ написания похож, но отличий по сути все же много, следующий редактор разберет их по порядку для всех.
нетv-model
Что делать, есть ли другие команды, которые я могу использовать?
когда вы решите использоватьJSX
когда будете готовы попрощаться с командованием, вJSX
, единственные директивы, которые вы можете использовать, этоv-show
, Кроме того, другие команды недоступны, вы чувствуете панику, это правильно. Однако, если подумать об этом с другой стороны, инструкции простоVue
Синтаксический сахар, представленный в коде шаблона, теперь можно написатьJs
Ну, эти синтаксические сахара используютсяJs
можно заменить.
v-model
v-model
даVue
Синтаксический сахар, предоставляемыйvalue
свойство (по умолчанию) +input
состав события (по умолчанию), если для пользовательскогоv-model
Студентам, которые не знают, рекомендуется прочитать статью редактора, чтобы понятьАбсолютно сухой материал~! Изучите эти советы Vue, вы сможете уйти с работы пораньше и встречаться с богиней. Итак, вJSX
, мы можем вернуться к сути, передавvalue
свойство и слушатьinput
События для реализации двусторонней привязки данных
export default {
data() {
return {
name: ''
}
},
methods: {
// 监听 onInput 事件进行赋值操作
$_handleInput(e) {
this.name = e.target.value
}
},
render() {
// 传递 value 属性 并监听 onInput事件
return <input value={this.name} onInput={this.$_handleInput}></input>
}
}
После проверки редактором, в новой версии строительных лесов
vue-cli4
, был интегрирован по умолчанию дляv-model
поддержка, вы можете использовать его напрямую<input v-model={this.value}>
, если ваш проект старше, вы также можете установить плагиныbabel-plugin-jsx-v-model
поддерживать
По аналогии,JSX
в течение.sync
Его также необходимо реализовать со свойствами + событиями, как показано в следующем коде:
export default {
methods: {
$_handleChangeVisible(value) {
this.visible = value
}
},
render() {
return (
<ElDialog
title="测试.sync"
visible={this.visible}
on={{ 'update:visible': this.$_handleChangeVisible }}
></ElDialog>
)
}
}
v-если и v-для
В коде шаблона мы передаемv-for
перебирать элементы,v-if
Чтобы определить, отображать ли элемент, вjsx
в, дляv-for
,вы можете использоватьfor
цикл,array.map
вместо этого дляv-if
,можно использоватьif
утверждение,三元表达式
вместо этого подождите
цикл по списку
const list = ['java', 'c++', 'javascript', 'c#', 'php']
return (
<ul>
{list.map(item => {
return <li>{item}</li>
})}
</ul>
)
Используйте условное суждение
const isGirl = false
return isGirl ? <span>小妹,哥哥教你写Vue</span> : <span>鸟你干啥</span>
v-bind
В коде шаблона мы обычно передаемv-bind:prop="value"
или:prop="value"
Чтобы привязать свойства к компонентам, вJSX
Так же написано
render() {
return <input value={this.name}></input>
}
v-html и v-текст
говорящийv-html
а такжеv-text
Прежде чем нам нужно понятьVue
свойства в ,Vue
В нем три вида атрибутов, первый чаще всего используется при написании багов.props
, то есть свойства компонента custom, второе этоattrs
, который ссылается на свойства, переданные в родительской области, но не определенные в дочернем компоненте. Третий, более особенный,domProps
, после неполной проверки редактора, вVue
середина,domProps
Существует три основных компонента, а именноinnerHTML
,textContent/innerText
а такжеvalue
.
-
v-html
: В коде шаблона мы используемv-html
директива для обновления элементаinnerHTML
содержание, находясь вJSX
Внутри, если вы хотите манипулировать компонентомinnerHTML
, необходимо использоватьdomProps
export default { data() { return { content: '<div>这是子君写的一篇新的文章</div>' } }, render() { // v-html 指令在JSX的写法是 domPropsInnerHTML return <div domPropsInnerHTML={this.content}></div> } }
-
v-text
: см. вышеv-html
, вы сразу подумали оv-text
существуетJSX
написаниеdomPropsInnerText
, да ты правexport default { data() { return { content: '这是子君写的一篇新的文章的内容' } }, render() { return <div domPropsInnerText={this.content}></div> } }
Но на самом деле нам не нужно использовать
domPropsInnerText
, но используйте текст как дочерний узел элемента<div>{this.content}</div>
Фактически, дляdomProps
,ТолькоinnerHTML
просто нужно использоватьdomPropsInnerHTML
Метод письма, другие могут использовать обычный метод письма
Мне также нужно слушать события
События прослушивания и нативные события
Когда мы разрабатываем компонент, мы обычно передаемthis.$emit('change')
способ выставить события внешнему миру, а затем передатьv-on:change
способ прослушивания событий, к сожалению, вJSX
ты не можешь использоватьv-on
команду, но вы разблокируете новую позу
render() {
return <CustomSelect onChange={this.$_handleChange}></CustomSelect>
}
JSX
в, черезon
+ Большой верблюжий регистр имени события для отслеживания, например, событиеicon-click
,существуетJSX
написано какonIconClick
Иногда мы хотим прослушивать нативные события корневого элемента компонента, который будет использоваться в это время..native
Модификаторы, немного отчаянно, модификаторы использовать нельзя, но, к счастью, есть альтернативы, следующий код
render() {
// 监听下拉框根元素的click事件
return <CustomSelect nativeOnClick={this.$_handleClick}></CustomSelect>
}
Правила прослушивания нативных событий такие же, как и у обычных событий, нужно только изменить предыдущийon
заменитьnativeOn
В дополнение к описанному выше методу прослушивания событий мы также можем использовать объектный метод для прослушивания событий.
render() {
return (
<ElInput
value={this.content}
on={{
focus: this.$_handleFocus,
input: this.$_handleInput
}}
nativeOn={{
click: this.$_handleClick
}}
></ElInput>
)
}
модификатор события
Подобно директивам, за исключением нескольких, большинство модификаторов событий нельзя использовать вJSX
Вы должны привыкнуть к этому в это время, и должны быть альтернативы.
-
.stop
: остановить всплывающую подсказку события, вJSX
используется вevent.stopPropagation()
заменить -
.prevent
: предотвратить поведение по умолчанию, вJSX
используется вevent.preventDefault()
заменить -
.self
: обратный вызов запускается только тогда, когда событие запускается из самого элемента, привязанного к слушателю, вместо этого используйте следующее условное суждение.if (event.target !== event.currentTarget){ return }
-
.enter
а такжеkeyCode
: Обратный вызов запускается только при нажатии определенной клавиши.if(event.keyCode === 13) { // 执行逻辑 }
В дополнение к вышеупомянутым модификаторам You Da, чтобы позаботиться о нашей группе мальчиков CV, сделал некоторые оптимизации..once
,.capture
,.passive
,.capture.once
, особенно предоставляет синтаксис префикса, чтобы помочь нам упростить код
render() {
return (
<div
on={{
// 相当于 :click.capture
'!click': this.$_handleClick,
// 相当于 :input.once
'~input': this.$_handleInput,
// 相当于 :mousedown.passive
'&mousedown': this.$_handleMouseDown,
// 相当于 :mouseup.capture.once
'~!mouseup': this.$_handleMouseUp
}}
></div>
)
}
да, слоты есть
Слот — это заполнитель, предоставленный в дочернем компоненте для родительского компонента.Слоты делятся на слоты по умолчанию, именованные слоты и слоты с областью действия.Следующий редактор предоставит вам каждый тип слота по очереди.JSX
Использование и как определить слоты в .
слот по умолчанию
- использовать слот по умолчанию
использоватьelement-ui
изDialog
, содержимое всплывающего окна использует слот по умолчанию.JSX
Использование слота по умолчанию в основном такое же, как использование обычного слота, как показано в следующем коде:
render() {
return (
<ElDialog title="弹框标题" visible={this.visible}>
{/*这里就是默认插槽*/}
<div>这里是弹框内容</div>
</ElDialog>
)
}
-
пользовательский слот по умолчанию
существует
Vue
случайthis
Есть свойство выше$slots
, этот монтирует все слоты внутри этого компонента, используяthis.$slots.default
Вы можете добавить слот по умолчанию к компонентуexport default { props: { visible: { type: Boolean, default: false } }, render() { return ( <div class="custom-dialog" vShow={this.visible}> {/**通过this.$slots.default定义默认插槽*/} {this.$slots.default} </div> ) } }
именованный слот
-
Используйте именованные слоты
Иногда нам нужно несколько слотов для компонента, поэтому нам нужно дать каждому слоту имя, например
element-ui
Всплывающее окно может определять содержимое области кнопки внизу, то есть имяfooter
слот
render() {
return (
<ElDialog title="弹框标题" visible={this.visible}>
<div>这里是弹框内容</div>
{/** 具名插槽 */}
<template slot="footer">
<ElButton>确定</ElButton>
<ElButton>取消</ElButton>
</template>
</ElDialog>
)
}
- пользовательский именованный слот
Упоминается при настройке слотов по умолчанию в предыдущем разделе.$slots
, для использования слота по умолчаниюthis.$slots.default
И назван для слота, вы можете использоватьthis.$slots.footer
чтобы настроить
render() {
return (
<div class="custom-dialog" vShow={this.visible}>
{this.$slots.default}
{/**自定义具名插槽*/}
<div class="custom-dialog__foolter">{this.$slots.footer}</div>
</div>
)
}
слот с прицелом
-
Используйте слоты с ограниченной областью действия
Иногда бывает полезно разрешить содержимому слота доступ к данным, доступным только в дочернем компоненте.
JSX
, потому что нетv-slot
директива, поэтому слоты с заданной областью используются не так, как в коде шаблона. например, вelement-ui
, мы используемel-table
Когда вы можете настроить содержимое ячейки таблицы, вам нужно использовать слот областиdata() { return { data: [ { name: '子君' } ] } }, render() { return ( {/**scopedSlots即作用域插槽,default为默认插槽,如果是具名插槽,将default该为对应插槽名称即可*/} <ElTable data={this.data}> <ElTableColumn label="姓名" scopedSlots={{ default: ({ row }) => { return <div style="color:red;">{row.name}</div> } }} ></ElTableColumn> </ElTable> ) }
-
слот с пользовательской областью действия
В отличие от использования слотов с областью действия, определение слотов с областью действия также отличается от кода шаблона. Мы настроили компонент элемента списка. Пользователи хотят настроить заголовок элемента списка. В настоящее время данные списка необходимо передавать через слот области.
render() { const { data } = this // 获取标题作用域插槽 const titleSlot = this.$scopedSlots.title return ( <div class="item"> {/** 如果有标题插槽,则使用标题插槽,否则使用默认标题 */} {titleSlot ? titleSlot(data) : <span>{data.title}</span>} </div> ) }
только вrender
используется в функцииJSX
ты
Конечно нет, вы можете определитьmethod
, затем вmethod
вернуться внутрьJSX
, затем вrender
Этот метод вызывается в функции, мало того,JSX
Вы также можете присваивать значения непосредственно переменным, например следующий код
methods: {
$_renderFooter() {
return (
<div>
<ElButton>确定</ElButton>
<ElButton>取消</ElButton>
</div>
)
}
},
render() {
const buttons = this.$_renderFooter()
return (
<ElDialog visible={this.visible}>
<div>这里是一大坨内容</div>
<template slot="footer">{buttons}</template>
</ElDialog>
)
}
Чувак, ты забыл заказ
Извините, я сейчас исправлюсь.
Основное использование
Хотя большую часть встроенной команды нельзя напрямуюJSX
используется внутри, но пользовательские директивы можно найти вJSX
внутрь, приниматьelement-ui
изv-loading
команду, вы можете использовать
render() {
/**
* 一个组件上面可以使用多个指令,所以是一个数组
* name 对应指令的名称, 需要去掉 v- 前缀
* value 对应 `v-loading="value"`中的value
*/
const directives = [{ name: 'loading', value: this.loading }]
return (
<div
{...{
directives
}}
></div>
)
}
модификатор
Некоторые директивы также могут использовать модификаторы, например, в приведенном выше примере.v-loading
, через модификатор можно указать закрывать ли на весь экран и блокировать ли прокрутку экрана.В это время нужно писать такv-loading.fullscreen.lock = "loading"
render() {
/**
* modifiers指定修饰符,如果使用某一个修饰符,则指定这个修饰符的值为 true
* 不使用可以设置为false或者直接删掉
*/
const directives = [
{
name: 'loading',
value: this.loading,
modifiers: { fullscreen: true, lock: false }
}
]
return (
<div
{...{
directives
}}
></div>
)
}
Эпилог
Не истощайте свое вдохновение и воображение, не будьте рабом своих моделей. - Винсент Ван Гог
В этой статье используетсяmdniceнабор текста