Vue3 JSX 寫法筆記

題葉發表於2022-12-28

Vue3 是可以用 JSX 語法直接寫的, 大體可以從 https://sfc.vuejs.org/ 的示例看到,
其中 <div> 會編譯為 h('div'), 具體參考 https://vuejs.org/guide/extra... .

完整的元件定義形如:

import { defineComponent, PropType } from 'vue';
import { onMounted, ref, watch } from 'vue';

const App = defineComponent({
  name: "App"
  props: {
    appId: {
      type: String as PropType<string>,
      default: '',
    },
  },
  emits: [],
  setup(props, {emit, expose, slots}) {

    return () => (
      <div>TODO</div>
    );
  },
});

export default App;

其中

  • name 除錯中元件的名字,
  • props 需要用這樣的寫法用 Object 格式傳入, 型別部分用 PropType<T> 做標記,
  • emits 可以用字串格式指定事件, 而 emit 函式從引數中拿到,
  • slots 也是從引數當中拿到,
  • expose 也是從引數當中得到的,
  • 注意最終的 render 函式, 範圍與 setup 函式有區別, 其中 setup 函式只會被執行一次, 而 render 函式可能多次執行. 而需要響應式追蹤的邏輯, 需要寫在 setup 函式里邊, 否則行為不能達到預期,

有了 JSX, 原有的 v-ifv-else 可以和 React 一樣直接寫了,

<div>
  {!!a ? <span>true</span> : null}
</div>

v-model 較為特殊, 轉換後需要手動繫結 modelValue 的行為:

<A modelValue={a.value} onUpdate:modelValue={(v) => a.value = v} />

expose 的用法, 傳入一個物件, 參考 https://www.vuemastery.com/bl...

expose({ reset })

@click 寫法統一變成 on 加上大寫首字元,

<div onClick={() => console.log("TODO")} >

v-slots 用法比較複雜, 參考 https://github.com/vuejs/babe... :

const A = (props, { slots }) => (
  <>
    <h1>{ slots.default ? slots.default() : 'foo' }</h1>
    <h2>{ slots.bar?.() }</h2>
  </>
);

有個 slot/template 寫法比較繞, 定製插槽的寫法:

<NSelect>
  <template #optionEmptyRender>
    <div>Demo</div>
  </template>
</NSelect>

寫成:

<NSelect
  v-slots={{
    optionEmptyRender: () => {
      return (
        <div>Demo</div>
      );
    },
  }}
/>

TODO

相關文章