Home >Web Front-end >Vue.js >How to use jsx/tsx in Vue3
Here we take the vite project as an example. If we want to use JSX in the project, we need to install a plug-in @vitejs/plugin-vue-jsx
. This plug-in can Let's use JSX/TSX in the project
npm i @vitejs/plugin-vue-jsx -D
After the installation is complete, in vite.config.ts
Just make a configuration
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()], });
Next let’s take a look at how to use JXS?
First of all, the first way is to use it in the .vue
file, which requires Set the lang in the script to tsx
, return the template
<script lang="tsx"> import { defineComponent } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => <div>Hello World</div>; }, }); </script>
in the setup function or change .vue
to .tsx
, please note : If the suffix is .tsx
, you need to remove the suffix
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");
from the path introduced to this component. At this time, a Hello World
//App.tsx export default (props, ctx) => <div>Hello World</div>;At this point it is not difficult to find that TSX has a feature compared to SFC, that is, it can define multiple component templates in one file, such as
const Component1 = () => <div>Component1</div>; const Component2 = () => <div>Component2</div>; export default () => ( <div> <Component1 /> <Component2 /> </div> );At this time, the page The two components we defined appeared Next let’s take a look at the specific usage of JSX in vueInterpolationIn When using interpolation in SFC, we can use
{{}} for wrapping, while in JSX we use
{} for wrapping, such as
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { const text = ref("Hello World"); return () => <div>{text.value}</div>; }, });. You need to pay attention here. What's more, you don't need to add
.value in the SFC template, but you need to add
.value
v-if for conditional rendering, such as
<div> <div v-if="showyes">yes</div> <span v-else>no</span> </div>, but in JSX there is no
v-if, but Use a writing method that is closer to native
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>; }, });In addition to
v-if, you may also think of another conditional rendering method
v-show, which is supported in 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> ); }, });List loop (v-for)In SFC we often use
v-for for list loop rendering, such as
<ul> <li v-for="{ index, item } in list" :key="index">{{ item }}</li> </ul>In JSX, we need to change to using map for list loop rendering
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> ); }, });Note that list loops in JSX also need to add keyEvent bindingEvent binding is actually the difference between JSX and SFC. Taking
click as an example, use
@click or
v-on:click in SFC For event binding, in JSX, use
onClick for event binding
import { defineComponent, ref } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClick={() => { console.log("我被点击"); }} > 点击 </div> ); }, });It should be noted here that the bound function must use the arrow function Event modification SymbolEvent modifiers can be set using the
withModifiers provided by vue, such as
.self
import { defineComponent, ref, withModifiers } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClick={withModifiers(() => { console.log("我被点击"); }, ["self"])} > 点击 </div> ); }, });But for .passive, .capture and. Once event modifier, using
withModifiers does not take effect. It can be set in the form of chained camel case. It is not as good as
.once
import { defineComponent } from "vue"; export default defineComponent({ name: "app", setup(props, ctx) { return () => ( <div onClickOnce={() => { console.log("我被点击"); }} > 点击 </div> ); }, });v-model
modelValue or using it in the
input tag
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} />; }, });When using binding customization in a component There are differences between events and SFC. For example, to bind a
msg, in SFC you can directly use
v-model:msg, but in JSX you need to use an array. If we look directly at the following two examples, you will understand that if our component is named
ea_button, this component sends a
update:changeMsg method, the parent component’s
msgVariables need to accept the parameters passed by the
update:changeMsg function
<ea-button v-model:changeMsg="msg"></ea-button>JSX:
<ea-button v-model={[msg.value, 'changeMsg']}></ea-button>SlotLet’s look at the default slot first. We define a sub-component Child to receive a default slot
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>; }, });If you want to use a named slot, you need to pass in an object in the parent component, and the key value of the object is the slot. The name
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> ); }, });If we want to get the variables in the child component from the slot content of the parent component, this involves the scope slot. In JSX, we can pass in parameters when the sub-component calls the default slot or a named slot, such as the following slot one as an example
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> ); }, });We can see
prama1=slot 1 is a variable in the child component, we pass it to the slot content of the parent component through
slots.slotOne(prama1)
The above is the detailed content of How to use jsx/tsx in Vue3. For more information, please follow other related articles on the PHP Chinese website!