Home > Web Front-end > Vue.js > How to use jsx/tsx in Vue3

How to use jsx/tsx in Vue3

王林
Release: 2023-05-11 14:07:06
forward
2047 people have browsed it

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()],
});
Copy after login

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>
Copy after login

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>;
  },
});
Copy after login
//main.ts中引入
import { createApp } from "vue";
import "./style.css";
import App from "./App";

createApp(App).mount("#app");
Copy after login

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>;
Copy after login

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>
);
Copy after login

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>;
  },
});
Copy after login

. 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>
Copy after login

, 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>;
  },
});
Copy after login

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>
    );
  },
});
Copy after login

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>
Copy after login

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>
    );
  },
});
Copy after login

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>
    );
  },
});
Copy after login

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>
    );
  },
});
Copy after login

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>
    );
  },
});
Copy after login

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} />;
  },
});
Copy after login

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>
Copy after login

JSX:

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

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>;
  },
});
Copy after login

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>
    );
  },
});
Copy after login

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>
    );
  },
});
Copy after login
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!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template