Ici, nous prenons le projet vite comme exemple Pour utiliser JSX dans le projet, nous devons installer un plug-in @vitejs/plugin-vue-jsx
. -in nous permet d'utiliser JSX dans le projet. Utilisez JSX/TSX@vitejs/plugin-vue-jsx
,这个插件可以让我们在项目中使用 JSX/TSX
npm i @vitejs/plugin-vue-jsx -D
安装完成之后在vite.config.ts
进行一个配置即可
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import vueJsx from "@vitejs/plugin-vue-jsx"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue(), vueJsx()], });
接下来我们看一下如何使用 JXS?
首先第一种方式就是在.vue
文件中使用,需要将 script 中的 lang 设置为tsx
,在 setup 函数中返回模板
<script lang="tsx"> import { defineComponent } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => <div>Hello World</div>; }, }); </script>
或者将.vue
改成.tsx
,注意:如果后缀为.tsx
,需要将引入到这个组件的路径后缀去掉
import { defineComponent } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => <div>Hello World</div>; }, });
//main.ts中引入 import { createApp } from "vue"; import "./style.css"; import App from "./App"; createApp(App).mount("#app");
此时页面上就会展示一个Hello World
第二种方式是函数式组件,因为函数式组件里没有 this 引用,所以 Vue 把 props 当作第一个参数传入,第二个参数 ctx 包含三个属性:attrs、emit 和 slots。它们分别相当于组件实例的 attrs、attrs、attrs、emit 和 $slots 这几个属性。
//App.tsx export default (props, ctx) => <div>Hello World</div>;
到这里我们不难发现,TSX 相比于 SFC 有一个特点,那就是它可以在一个文件中定义多个组件模板,比如
const Component1 = () => <div>Component1</div>; const Component2 = () => <div>Component2</div>; export default () => ( <div> <Component1 /> <Component2 /> </div> );
此时页面中便出现了我们定义的两个组件
接下来我们来看一下 JSX 在 vue 中的具体用法
在 SFC 中使用插值的时候我们可以使用{{}}
进行包裹,而在 JSX 中是使用{}
进行包裹,例如
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const text = ref("Hello World"); return () => <div>{text.value}</div>; }, });
这里需要注意的是在 SFC 模板中是不需要加.value
的,但是 JSX 模板中则需要加.value
在 SFC 中我们可以使用v-if
进行条件渲染,如
<div> <div v-if="showyes">yes</div> <span v-else>no</span> </div>
而在 JSX 中则没有了v-if
,而是采用更接近原生的写法
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const showyes = ref(true); return () => <div>{showyes.value ? <div>yes</div> : <div>no</div>}</div>; }, });
除了v-if
,大家可能还会想到另一个条件渲染方式v-show
,JSX 中是支持使用v-show
的
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const showyes = ref(true); return () => ( <div> <div v-show={showyes.value}>yes</div> <div v-show={!showyes.value}>no</div> </div> ); }, });
在 SFC 中我们经常使用v-for
进行列表循环渲染,如
<ul> <li v-for="{ index, item } in list" :key="index">{{ item }}</li> </ul>
而在 JSX 中我们则需要改成使用 map 进行列表循环渲染
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const list = ref(["one", "two", "three"]); return () => ( <div> {list.value.map((item, index) => ( <div key={index}>{item}</div> ))} </div> ); }, });
注意,JSX 中列表循环也是要加 key 的
事件绑定其实 JSX 与 SFC 就是写法上的区别,以click
为例,在 SFC 中使用@click
或者v-on:click
进行事件绑定,在 JSX 中则使用onClick
进行事件绑定
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClick={() => { console.log("我被点击"); }} > 点击 </div> ); }, });
这里需要注意绑定的函数要使用箭头函数
事件修饰符可以使用 vue 提供的withModifiers
进行设置,如.self
import { defineComponent, ref, withModifiers } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClick={withModifiers(() => { console.log("我被点击"); }, ["self"])} > 点击 </div> ); }, });
但是对于 .passive、.capture 和 .once 事件修饰符,使用withModifiers
并不生效,这里可以采用链式驼峰的形式进行设置,不如.once
import { defineComponent } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClickOnce={() => { console.log("我被点击"); }} > 点击 </div> ); }, });
v-model 在绑定modelValue
或者在input
标签中使用的时候其实和 SFC 差不多
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const num = ref(0); return () => <input type="text" v-model={num.value} />; }, });
当在组件中使用绑定自定义事件的时候和 SFC 就有了区别,比如绑定一个msg
,在 SFC 中直接v-model:msg
即可,而在 JSX 中则需要使用一个数组。我们直接看下面两个例子你就会明白,假如我们组件名叫ea_button
,这个组件发送了一个update:changeMsg
的方法,父组件的msg
变量需要接受update:changeMsg
函数传来的参数
SFC:
<ea-button v-model:changeMsg="msg"></ea-button>
JSX:
<ea-button v-model={[msg.value, 'changeMsg']}></ea-button>
先看下默认插槽,我们定义一个子组件 Child 接收一个默认插槽
import { defineComponent, ref } from "vue"; const Child = (props, { slots }) => { return <div>{slots.default()}</div>; }; export default defineComponent({ name: "app", setup(props, ctx) { const num = ref(0); return () => <Child>默认插槽</Child>; }, });
如果想使用具名插槽则需要在父组件中传入一个对象,对象的 key 值就是插槽的名字
import { defineComponent, ref } from "vue"; //@ts-ignore const Child = (props, { slots }) => { return ( <div> <div>{slots.slotOne()}</div> <div>{slots.slotTwo()}</div> <div>{slots.slotThree()}</div> </div> ); }; export default defineComponent({ name: "app", setup(props, ctx) { const num = ref(0); return () => ( <Child> {{ slotOne: () => <div>插槽1</div>, slotTwo: () => <div>插槽2</div>, slotThree: () => <div>插槽3</div>, }} </Child> ); }, });
如果我们想在父组件的插槽内容中获取到子组件中的变量,此时便涉及到了作用域插槽。在 JSX 中我们可以在子组件调用默认插槽或者某个具名插槽的时候传入参数,如下面的插槽一为例
import { defineComponent, ref } from "vue"; //@ts-ignore const Child = (props, { slots }) => { const prama1 = "插槽1"; return ( <div> <div>{slots.slotOne(prama1)}</div> <div>{slots.slotTwo()}</div> <div>{slots.slotThree()}</div> </div> ); }; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <Child> {{ slotOne: (pramas: string) => <div>{pramas}</div>, slotTwo: <div>插槽2</div>, slotThree: <div>插槽3</div>, }} </Child> ); }, });
我们可以看到prama1=插槽1
是子组件中的变量,我们通过slots.slotOne(prama1)
npm i @vitejs/plugin-vue-jsx -D🎜🎜Une fois l'installation terminée, effectuez simplement une configuration dans <. code>vite.config.ts🎜rrreee 🎜Voyons ensuite comment utiliser JXS ?🎜🎜Tout d'abord, la première façon est de l'utiliser dans le fichier
.vue
. Vous devez définir la langue dans le script sur tsx
. Renvoyez le modèle 🎜rrreee🎜 dans la fonction de configuration ou remplacez .vue
par .tsx. Remarque : Si le suffixe est <code>.tsx
, vous devez l'importer dans Supprimer le suffixe de chemin de ce composant🎜rrreeerrreee🎜À ce moment, un Hello World
sera affiché sur la page🎜🎜La deuxième méthode concerne les composants fonctionnels, car il n'y a pas de référence this dans les composants fonctionnels, donc Vue utilise les accessoires transmis comme premier paramètre, le deuxième paramètre ctx contient trois attributs : attrs, submit et slots. Ils sont respectivement équivalents aux attributs attrs, attrs, attrs, submit et $slots de l'instance du composant. 🎜rrreee🎜À ce stade, il n'est pas difficile de constater que TSX a une fonctionnalité par rapport à SFC, c'est-à-dire qu'il peut définir plusieurs modèles de composants dans un seul fichier. Par exemple, 🎜rrreee🎜À ce stade, les deux composants que nous avons définis. apparaître sur la page 🎜🎜 🎜🎜 Ensuite, examinons l'utilisation spécifique de JSX dans vue🎜🎜Interpolation🎜🎜Lors de l'utilisation de l'interpolation dans SFC, nous pouvons utiliser {{}}
pour l'encapsulation, tandis qu'en JSX, utilisez {} pour l'emballage, tel que 🎜rrreee🎜Il convient de noter ici qu'il n'est pas nécessaire d'ajouter .value
dans le modèle SFC, mais vous devez ajouter .value
dans le modèle JSX >🎜🎜Rendu conditionnel (v-if)🎜🎜Dans SFC, nous pouvons utiliser v-if
pour le rendu conditionnel, comme 🎜rrreee🎜, mais en JSX il n'y a pas de v-if, mais utilise une méthode d'écriture plus proche du natif 🎜rrreee🎜En plus de <code>v-if
, vous pouvez aussi penser à un autre rendu conditionnel méthode v-show
, en JSX Elle prend en charge l'utilisation de v-show
🎜rrreee🎜list loop (v-for)🎜🎜Dans SFC, nous utilisons souvent v-for
pour le rendu des boucles de liste, comme 🎜rrreee 🎜Dans JSX, nous devons utiliser map pour le rendu des boucles de liste🎜rrreee🎜Notez que les boucles de liste dans JSX doivent également ajouter des clés🎜🎜Liaison d'événement🎜🎜Liaison d'événement En fait, la différence entre JSX et SFC réside dans la méthode d'écriture. En prenant click
comme exemple, utilisez @click
ou v-on:click
. pour la liaison d'événement dans SFC et utilisez onClick
pour la liaison d'événement🎜rrreee🎜Il convient de noter que la fonction liée doit utiliser la fonction de flèche🎜🎜Modificateur d'événement🎜🎜Le modificateur d'événement peut être défini à l'aide de withModifiers
fourni par vue. Tel que .self
🎜rrreee🎜Mais pour les modificateurs d'événements .passive, .capture et .once, l'utilisation de withModifiers
ne prend pas effet. Ici, vous pouvez le définir sous la forme d'un chameau enchaîné, ce n'est pas aussi bon que .once
🎜rrreee🎜v-model🎜🎜v-model lors de la liaison de modelValue
. ou l'utiliser dans la balise input
est presque la même chose🎜rrreee🎜Lors de la liaison d'événements personnalisés dans des composants, c'est différent de SFC. Par exemple, la liaison d'un msg
, directement v-model:msg suffit, mais dans JSX, vous devez utiliser un tableau. Si l'on regarde directement les deux exemples suivants, vous comprendrez que si notre composant s'appelle <code>ea_button
, ce composant envoie une méthode update:changeMsg
, et le La variable msg
doit accepter les paramètres passés par la fonction update:changeMsg
🎜🎜SFC:🎜rrreee🎜JSX:🎜rrreee🎜Slot🎜🎜Premier regard sur le slot par défaut, nous définir un sous Le composant Child reçoit un slot par défaut🎜rrreee🎜Si vous souhaitez utiliser un slot nommé, vous devez transmettre un objet dans le composant parent La valeur clé de l'objet est le nom du slot🎜rrreee🎜If. nous voulons l'utiliser dans le contenu des slots du composant parent. L'obtention des variables dans le sous-composant implique des slots de portée. Dans JSX, nous pouvons transmettre des paramètres lorsque le sous-composant appelle l'emplacement par défaut ou un emplacement nommé, comme l'emplacement 1 ci-dessous à titre d'exemple🎜rrreee🎜Nous pouvons voir que prama1=slot 1
est une variable dans le composant enfant. Nous le transmettons au contenu du slot du composant parent via slots.slotOne(prama1)
🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!