Home  >  Article  >  Web Front-end  >  How to use jsx/tsx in Vue3

How to use jsx/tsx in Vue3

王林
王林forward
2023-05-11 14:07:061989browse

How to use JSX

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

# will be displayed on the page. ##The second method is functional components. Because there is no this reference in functional components, Vue passes props as the first parameter. The second parameter ctx contains three attributes: attrs, emit and slots. They are respectively equivalent to the attrs, attrs, attrs, emit and $slots attributes of the component instance.

//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

How to use jsx/tsx in Vue3

Next let’s take a look at the specific usage of JSX in vue

Interpolation

In 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

in the JSX template. Conditional rendering (v-if)

In SFC we can use

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 methodv-show, which is supported in JSXv-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 key

Event binding

Event 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 Symbol

Event 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

v-model is actually similar to SFC when binding

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

SFC:

<ea-button v-model:changeMsg="msg"></ea-button>

JSX:

<ea-button v-model={[msg.value, &#39;changeMsg&#39;]}></ea-button>

Slot

Let’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!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete