Vue3如何使用JSX

前端开发   发布日期:2023年07月01日   浏览次数:311

这篇文章主要介绍“Vue3如何使用JSX”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue3如何使用JSX”文章能帮助大家解决问题。

    1. Vue3 中 JSX 的基本应用

    • 使用 .jsx 格式文件和 defineComponent

    • defineComponent 可传入 setup 函数 或 组件的配置

    • 插值使用单括号 {}

    1.1 在 .vue 文件中使用 jsx

    // 父
     
    <template>
      <div class="home">
        <JSXDemo1 />
      </div>
    </template>
     
    <script>
    import JSXDemo1 from '@/components/JSXDemo1.vue'
    export default {
      name: 'HomeView',
      components: {
        JSXDemo1
      }
    }
    </script>
     
    // JSXDemo1.vue
     
    <script>
    import { ref } from 'vue'
    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 'vue'
    import JSXChild from './JSXChild.jsx'
     
    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 'vue'
     
    export default defineComponent({ // 传入组件配置
      props: ['a'],
      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 'vue'
    import WatchEffect from '@/components/WatchEffect.vue'
    export default {
      name: 'HomeView',
      components: {
        WatchEffect,
      },
      setup () {
        const msgRef = ref('123')
        return {
            msgRef
        }
      }
    }
    </script>
     
    // jsx 组件名称不可变,要和引入名字保持一致
     
    import { defineComponent, ref } from 'vue'
    import JSXChild from './JSXChild.jsx'
     
    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 'vue'
    import JSXChild from './JSXChild.jsx'
     
    export default defineComponent(() => {
      const countRef = ref(300)
     
      function onChange () {
        console.log('onChange')
      }
      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 'vue'
    export default {
      setup () {
        const flagRef = ref(true)
     
        function changeFlagRef () {
          flagRef.value = !flagRef.value
        }
     
        return {
          flagRef,
          changeFlagRef
        }
      }
    }
    </script>
     
    // jsx &&符号判断
     
    import { defineComponent, ref } from 'vue'
    import JSXChild from './JSXChild.jsx'
     
    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 'vue'
    export default {
      setup () {
        const state = reactive({
          list: ['a', 'b', 'c']
        })
     
        return {
          state
        }
      }
    }
    </script>
     
    // jsx 数组 .map 函数
     
    import { defineComponent, reactive } from 'vue'
     
    export default defineComponent(() => {
      const state = reactive({
        list: ['a1', 'b1', 'c1']
      })
     
      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的详细内容,更多关于Vue3如何使用JSX的资料请关注九品源码其它相关文章!