首頁  >  文章  >  web前端  >  怎麼在Vue3中使用jsx/tsx

怎麼在Vue3中使用jsx/tsx

王林
王林轉載
2023-05-11 14:07:061990瀏覽

JSX 如何用

這裡以vite專案為例,要想在專案中使用JSX,我們需要安裝一個插件@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>
);

此時頁面中便出現了我們定義的兩個元件

怎麼在Vue3中使用jsx/tsx

接下來我們來看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

##條件渲染(v-if)

在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>
    );
  },
});

列表循環(v-for)

在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 中使用@clickv-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

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, &#39;changeMsg&#39;]}></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)將其傳到了父元件的插槽內容中

以上是怎麼在Vue3中使用jsx/tsx的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除