Разрабатывайте компоненты Vue3 с помощью JSX/TSX

Vue.js

Добро пожаловать в мою личную учетную запись WeChat «HcySunYang». Давайте программировать в удовольствие вместе!

После написания этой статьи

"Подробности оптимизации компилятора Vue3, как писать высокопроизводительные функции рендеринга"

Чтобы подумать или задаться целью разработать полный дизайн для Vue3 JSX, подключите его, поэтому будет:

GitHub.com/HC имеет Сунь Ян/…

Этот плагин уже доступен. Я использую этот плагин в другом проекте. Позвольте мне рассказать о принципах разработки и основном использовании этого плагина.

Используйте TSX напрямую

Vue3 действительно можно использовать напрямуюtsxразвитие, единственное, с чем нужно иметь дело, этоchildren, и с этим все еще относительно неприятно иметь дело, например, вы не можете написать:

<div>
    <p>1</p>
    <p>1</p>
</div> 

тебе следует:

<div>
    {
      [
        <p>1</p>,
        <p>1</p>
      ]
    }
</div> 

Это все еще довольно отвратительно, но не невозможно инкапсулировать функцию полезности:

function JSXFactory(tag: any, props: any, ...children: any) {
  if (
    typeof tag !== 'string' &&
    typeof tag !== 'symbol' &&
    !tag.__isTeleport &&
    !tag.__isKeepAlive
  ) {
    // Component
    children = children[0]
  }
  return createVNode(tag, props, children)
}

Затем настройте в tsconfig.jsonjsxFactoryЭта инкапсулированная для нас функция подойдет. Но эта функция ограничивает то, что мы можем передать для компонентаslotsКогда только:

const App = {
    setup() {
        const slots = {
            foo: () => <p>foo</p>,
            bar: () => <p>bar</p>,
        }
        return () => <Hello>{ slots }</Hello>
    }
}

Но это нормально.

имеютJSXFactoryПосле функции полезности мы можем использовать ее с удовольствием.tsxЯ же написал, зачем заморачиваться?jsxЧто насчет плагинов? Это потому, что использованиеjsxПосле синтаксиса мы теряем многие удобные возможности, предоставляемые в шаблонах, такие как модификаторы событий,v-modelи т. д., поэтомуjsxПлагины по-прежнему необходимы, но не обязательны.

Давайте поговорим оGitHub.com/HC имеет Сунь Ян/…Принципы и функции конструкции.

Поддерживает как JSX, так и TSX

tsxне поддерживается вamespaced attribute, видеть:GitHub.com/Microsoft/T…, но поддерживается в babel, а значит, в jsx можно написать:

<p v-on:click={ handler } ></p>

ноtsxЭто не разрешено в имени атрибута, ради единообразия синтаксиса я решил не разрешать его в имени атрибута.:, вместо этого используйте-Заменять :

<p v-on-click={ handler } ></p>

Преимущество унификации грамматики: уменьшение дополнительной нагрузки/проблем, вызванных различиями в разных проектах (некоторые люди используют : некоторые люди используют -).

Модификаторы не разрешены ни в jsx, ни в tsx., вместо этого используйте_заменять:

 <p v-on-click_stop={ handler } ></p>

Для событий,vue-next-jsxПоддерживаются все доступные в шаблонах синтаксисы, например:

<div v-on-click_middle={ handler }></div>
<div v-on-click_stop={ handler }></div>
<div v-on-click_right={ handler }></div>
<div v-on-keyup_esc={ handler }></div>

<div v-on={ obj }></div>

v-model

в Vue2.syncодеялоv-model:fooвместо этого, например:

<!-- Vue2 -->
<Comp :foo.sync="val" />
<!-- Vue3 -->
<Comp v-model:foo="val" />

В jsx поставить:заменить-:

<Comp v-model-foo={ refVal.value }/> 

также может иметь модификаторы, с_сегментация:

<Comp v-model-foo_a_b={ refVal.value }/> 

v-bind

существуетj/tsxне требуется вv-bind, Используйте напрямуюjsxExpressionContainerа такжеjsxSpreadAttributeзаменять:

<Comp foo={ refVal.value } { ...props } bar="bar" />

slots

Я не готов поддержатьv-slot, это потому, что это приводит к потере типа, например:

<Comp>
    <template v-slot-foo="props">
    </template>
</Comp> 

здесьpropsТипа нет, это просто строка, и я всегда рекомендую передавать слот компоненту следующим образом:

<Comp>{ mySlots }</Comp> 

Что касается слотаmySlotsМы можем построить его самостоятельно:

const mySlots = {
    default: () => [<p>默认插槽</p>]
} 

KeepAlive и Телепорт

Эти два компонента особенные, их дочерние узлы будут существовать не как слоты, а как обычные дочерние элементы, но вам не о чем беспокоиться, vue-next-jsx сделает это за вас.

Optimization mode

оптимизированный режим, т.zhuanlan.zhihu.com/p/150732926Как описано в этой статье, мы можем использовать эту информацию в плагинах jsx, чтобы максимально повысить производительность.

существуетbabel.config.jsonВключите оптимизированный режим в:

{
  "presets": [
    "@babel/env"
  ],
  "plugins": [
    ["@hcysunyang/vue-next-jsx", {
      // 开启优化模式
      "optimizate": true
    }]
  ]
}

На самом деле, вы можете посмотреть наvue-next-jsxсозданный тестовым примером и сVue3 CompilerНапротив, их поведение последовательно, в том числе в чрезвычайно сложных ситуациях.

указать источник

sourceОтноситсяImportDeclarationПредложениеsource,Например:

import { createApp } from 'vue'

здесьsourceто естьvue, но вы, возможно, не установилиvueно@vue/runtime-dom, то нужно указатьsource:

{
  "presets": [
    "@babel/env"
  ],
  "plugins": [
    ["@hcysunyang/vue-next-jsx", {
      // 指定 source
      "source": "@vue/runtime-dom"
    }]
  ]
} 

v-html / v-text

существуетjsxНет особого смысла поддерживать эти две директивы в

<p v-html={ refHtml.value }></p>
<p v-text={ refText.value }></p>

Добро пожаловать в мою личную учетную запись WeChat «HcySunYang». Давайте программировать в удовольствие вместе!