• 用JSX来写Vue3,瞬间找到React 的感觉


    Ⅰ. vue3 的 JSX 写法

    • 对于熟悉react 的小伙伴, 可以通过 jsx 来 做 vue3

    • 让我们一起来踩坑 👇


    在这里插入图片描述

    Ⅱ. JSX 安装和配置

    1. 通过 webpack 构建的

    如果是通过官方 vue-cli 脚手架去创建的则需要如下操作 👇

    安装 [ 第 一 步 ]

    npm install @vue/babel-plugin-jsx -D
    
    • 1

    配置 [ 第 二 步 ]

    配置根目录 babel.config.js 👇

    module.exports = {
      plugins: ["@vue/babel-plugin-jsx"]   // 省略其他配置
    }
    
    • 1
    • 2
    • 3

    2. 通过 vite 构建的

    如果是通过去 vite 去创建的则需要如下操作 👇

    安装 [ 第 一 步 ]

    npm i @vitejs/plugin-vue-jsx
    
    • 1

    配置 [ 第 二 步 ]

    配置根目录 vite.config.js 👇

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    
    import vueJsx from "@vitejs/plugin-vue-jsx";
    export default defineConfig({
      plugins: [
      	vue(),
      	vueJsx()  //添加 jsx
      ]
      //...省略其他配置
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11


    Ⅳ. JSX 的 在vue 的应用

    1. JSX => 两种写法

    ① 写法一 : ⭐⭐⭐

    不需要 props 来传参 , 简写

    import { defineComponent } from 'vue';
    export default defineComponent((props, {emits}) => {
      return () => <div> 写法1  </div>
    })
    
    • 1
    • 2
    • 3
    • 4
    • defineComponent 去传入一个 函数 ( 会默认为 setup )

    • 写法方便, 因为 无法去定义 props , 所以 props 一直为空对象

    • 但是可以正常使用 emitsslots

    ② 写法二 : ⭐⭐⭐⭐⭐

    需要 props 传参

    import { defineComponent } from 'vue';
    export default defineComponent({
      props:{
    	params:{ 
    	  type: String, 
    	  defualt: ()=> ''
    	}	
      },
      setup(props) {
        return () => <div>  写法2  ,  父组件传过来的值 { props.params }  </div>
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • defineComponent 去传入一个 整个对象
    • 可以定义props ,可以使用 (父组件 => 子组件) 值
    • 复杂的场景,更加推荐,使用起来更加灵活
    2.JSX => 父子组件通信

    父组件: (Father.jsx) 👇

    import { defineComponent, ref } from 'vue';
    import Child from './Child.jsx'
    export default defineComponent(() => {
      const params = ref('123')
      function getChild(val){ 
      	console.log(val)
      }
     
      return () => <div>
      	 <h3>子组件↓ </h3>
        <Child   params={  params.value }  onFather={ getChild }  />
      </div>;
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    子组件 : (Child.jsx) 👇

    import { defineComponent, ref } from 'vue';
    export default defineComponent({
      props: ['params'],
      setup(props , { emit }) {
      	const text = ref('传给父组件的值')
        return () => 
        <div>
          	父组件传来的值: { props.params }
          	<button onClick = {()=>{ emit('father', text.value) } }> 传给 father </button>
        </div>
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 第二种可以定义 props 的写法,才可以接收 父组件传递的参数
    • emit 给父组件通信,父组件自定义 方法 要 加 on + 大写开头方法

    3. JSX => 用v-if 、v-show
    const visble = ref(true)
    const onOff =() => { visble.value = !visble.value }
    return () => <div>
        <button onClick= { onOff }> 开关 </button>
    	{ visble.value && <span>'内容...'</span> }
    </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • v-if 没办法正常使用 , 可以通过表达式代替
    • v-show 可以正常使用

    4. JSX => 用 v-for

    v-for 可以通过 map 代替

    const list = [ {name:'张三'}, {name: '李四'}]
    const onOff =() => { visble.value = !visble.value }
    return () => <ul>
       {list.map(res => <li>{res.name}</li>)}
    </ul>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5. JSX => 插槽的使用

    父组件: 👇

    <Page2  v-slots={{  
            aaa: () => <span>123</span> ,
            bbb: () => <span>456</span> 
     }} />
    
    • 1
    • 2
    • 3
    • 4

    子组件: 👇

     setup(props, { slots }) {
        return () => 
        <div>
           我是插槽aaa:  {slots.aaa && slots.aaa()}  <br>
           我是插槽bbb:  {slots.bbb && slots.bbb()}
        </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 通过 v-slots 返回对象,对象的每个属性为一个函数 ,返回对应的文本标签
    • 根据函数的名称,调用对应的方法,来放置具名插槽的位置
    • 先做个插槽的判空操作,会更加严谨

    Ⅳ. JSX 从头搭建 vue3

    我们用 jsx 去替代所有的 vue 文件, 从头搭建开始如下 👇

    1. 主文件和入口

    我们将App.vue 改成 App.jsx

    参考如下 : 主文件(main.js) 👇

    import { createApp } from "vue";
    import App from "./App.jsx";
    import router from './router';
    
    const app = createApp(App);
    app
    .use(router)
    .mount("#app");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    参考如下 : App.jsx 👇 , 来实现人口文件

    import { defineComponent } from 'vue';
    import { useRouter } from "vue-router";
    export default defineComponent(() => {
      const router = useRouter();
      return () => <div>
      	<button onClick = { ()=> router.push('/page1') } > 页面1 </button>
      	<button onClick = { ()=> router.push('/page2') } > 页面2 </button>
        <router-view></router-view>
      </div>
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2. 配置路由

    参考如下 👇

    import { createRouter, createWebHistory } from 'vue-router'
    const routerHistory = createWebHistory()
    
     const router = createRouter({
        history: routerHistory,
        routes: [
          {
            path: '/',
            component: () => import('../App.jsx'),
            redirect:'/page1',
            children: [
              { path: '/page1',  component: () => import('../views/page1.jsx') }
              { path: '/page2',  component: () => import('../views/page2.jsx') }
            ]
          }
        ]
    })
    export default router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

    在这里插入图片描述

  • 相关阅读:
    Python中的迭代器、生成器和装饰器
    Spring Boot中RedisTemplate的使用
    【Git】一文带你入门Git分布式版本控制系统(简介,安装,Linux命令)
    Shell脚本基本语法
    阿里笔试题目——网络
    C++初阶 | [三] 类和对象(中)
    c刷题[6]
    LeetCode //C - 94. Binary Tree Inorder Traversal
    Gen4Gen:多概念个性化图像生成的数据驱动革新
    腾讯网关TGW基础原理入门
  • 原文地址:https://blog.csdn.net/weixin_42232622/article/details/128049329