首頁 >web前端 >Vue.js >如何在Vue3中使用JSX?

如何在Vue3中使用JSX?

WBOY
WBOY轉載
2023-05-09 21:09:192249瀏覽

    1. Vue3 中JSX 的基本應用

    • 使用.jsx 格式檔案與 defineComponent

    • defineComponent 可傳入setup 函數或元件的設定

    • 插值使用單括號 {}

    #1.1 在.vue 檔案中使用jsx

    // 父
     
    <template>
      <div class="home">
        <JSXDemo1 />
      </div>
    </template>
     
    <script>
    import JSXDemo1 from &#39;@/components/JSXDemo1.vue&#39;
    export default {
      name: &#39;HomeView&#39;,
      components: {
        JSXDemo1
      }
    }
    </script>
     
    // JSXDemo1.vue
     
    <script>
    import { ref } from &#39;vue&#39;
    export default {
      setup () {
        const countRef = ref(200)
     
        const render = () => {
          return <p>DEMO1--{countRef.value}</p> // jsx就是js语法,所以要加 .value
        }
        return render
      }
    }
    </script>

    1.2 .jsx檔案格式

    // 父组件
     
    import { defineComponent, ref } from &#39;vue&#39;
    import JSXChild from &#39;./JSXChild.jsx&#39;
     
    export default defineComponent(() => { // 传入 setup 函数
      const countRef = ref(300)
     
      const render = () => {
        return <>
          <p>DEMO2--{countRef.value}</p>
          <JSXChild a={countRef.value + 100}></JSXChild>
        </>
      }
      return render 
    })
     
    // 子组件 JSXChild.jsx
     
    import { defineComponent } from &#39;vue&#39;
     
    export default defineComponent({ // 传入组件配置
      props: [&#39;a&#39;],
      setup (props) {
        const render = () => {
          return <>
            <p>child {props.a}</p>
          </>
        }
        return render
      }
    })

    2. JSX 和template 的差異

    • 語法上有很大差異

    • #JSX 本質上是js 程式碼,可以使用js 的任何能力

    • template 只能嵌入簡單的js 表達式,其他需要指令,如v-if

    • JSX 已成為ES 規範,template 還是Vue 自家規範

    • 本質是相同的:

    • #都會被編譯成js 程式碼(render 函數)

    2.1 插值

    • #template 使用雙括號{{ }}

    • ##jsx 使用單括號{ }

    // template
     
    <template>
      <p>{{ name }} -- {{ age }}</p>
    </template>
     
    // jsx
     
    const render = () => {
        return <>
            <p>child {props.a}</p>
        </>
    }
    2.2 自訂元件

    • template 元件名稱使用時可改變大小寫或是駝峰,jsx 不可更改

    • 引入動態參數,template使用冒號參數名稱(:msg='msg'),jsx 不需要冒號

    #
    // template
     
    <template>
      <div class="home">
        <watch-effect :msg="msgRef"/>
      </div>
    </template>
     
    <script>
    import { ref } from &#39;vue&#39;
    import WatchEffect from &#39;@/components/WatchEffect.vue&#39;
    export default {
      name: &#39;HomeView&#39;,
      components: {
        WatchEffect,
      },
      setup () {
        const msgRef = ref(&#39;123&#39;)
        return {
            msgRef
        }
      }
    }
    </script>
     
    // jsx 组件名称不可变,要和引入名字保持一致
     
    import { defineComponent, ref } from &#39;vue&#39;
    import JSXChild from &#39;./JSXChild.jsx&#39;
     
    export default defineComponent(() => {
      const countRef = ref(300)
     
      const render = () => {
        return <>
          <p>DEMO2--{countRef.value}</p>
          <JSXChild a={countRef.value + 100}></JSXChild>
        </>
      }
      return render
    })
    2.3 屬性和事件

    template 區分屬性和事件的寫法,jsx 不區分
    // jsx 属性和事件的写法一样
     
    import { defineComponent, ref } from &#39;vue&#39;
    import JSXChild from &#39;./JSXChild.jsx&#39;
     
    export default defineComponent(() => {
      const countRef = ref(300)
     
      function onChange () {
        console.log(&#39;onChange&#39;)
      }
      const render = () => {
        return <>
          <p>DEMO2--{countRef.value}</p>
          <JSXChild a={countRef.value + 100} change={onChange}></JSXChild>
        </>
      }
      return render
    })
    2.4 條件和循環 

    #條件template 使用v-if 指令,jsx 在表達式中使用&& (類似if( a && b))
    // template v-if
     
    <template>
      <p v-if="flagRef">template demo</p>
      <button @click="changeFlagRef">click</button>
    </template>
    <script>
    import { ref } from &#39;vue&#39;
    export default {
      setup () {
        const flagRef = ref(true)
     
        function changeFlagRef () {
          flagRef.value = !flagRef.value
        }
     
        return {
          flagRef,
          changeFlagRef
        }
      }
    }
    </script>
     
    // jsx &&符号判断
     
    import { defineComponent, ref } from &#39;vue&#39;
    import JSXChild from &#39;./JSXChild.jsx&#39;
     
    export default defineComponent(() => {
      const flagRef = ref(true)
     
      function changeFlagRef () {
        flagRef.value = !flagRef.value
      }
     
      const render = () => {
        return <>
          <p onClick={changeFlagRef}>DEMO2--{flagRef.value.toString()}</p>
          {flagRef.value && <JSXChild a={flagRef.value}></JSXChild>}
        </>
      }
      return render
    })
     循環template 使用v-for 指令,jsx 使用陣列的.map 函數
    // template v-for
     
    <template>
      <ul>
        <li v-for="item in state.list" :key="item">{{ item }}</li>
      </ul>
    </template>
    <script>
    import { reactive } from &#39;vue&#39;
    export default {
      setup () {
        const state = reactive({
          list: [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]
        })
     
        return {
          state
        }
      }
    }
    </script>
     
    // jsx 数组 .map 函数
     
    import { defineComponent, reactive } from &#39;vue&#39;
     
    export default defineComponent(() => {
      const state = reactive({
        list: [&#39;a1&#39;, &#39;b1&#39;, &#39;c1&#39;]
      })
     
      const render = () => {
        return <>
          <ul>
            {state.list.map(item => <li>{item}</li>)}
          </ul>
        </>
      }
      return render
    })
    3. JSX 和slot (體會JSX 的優越性)

    • slot 是Vue 發明的概念,為了完善template 的能力

    • slot 一直是Vue 初學者的“噩夢”,特別是:作用域slot

    • 但使用JSX 將很容易理解,因為JSX 本質就是js

    以上是如何在Vue3中使用JSX?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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