• 技术文章 >web前端 >Vue.js

    聊聊vue3中优雅使用 jsx/tsx 的方法

    青灯夜游青灯夜游2022-10-08 18:07:25转载655
    vue中如何优雅的使用 jsx/tsx?下面本篇文章给大家介绍一下vue3中优雅使用 jsx/tsx 的方法,希望对大家有所帮助!

    大前端零基础入门到就业:进入学习

    相信 react 的伙伴对于 jsx/tsx 都不陌生吧,现在在 vue3 中也可以使用 jsx/tsx 语法拉。【相关推荐:vuejs视频教程

    安装插件(@vitejs/plugin-vue-jsx)

    vite官方提供了官方的插件来支持在vue3中使用jsx/tsx,直接安装就行。

    yarn add @vitejs/plugin-vue-jsx -D

    安装完之后在vite.config.ts中插入一下代码

    import vueJsx from "@vitejs/plugin-vue-jsx";
    
    export default defineConfig({
      plugins: [
        vueJsx(),
      ]
    })

    配置完就可以在项目中使用jsx/tsx

    1、插值

    jsx/tsx 的插值与 vue 模板语法中的插值一样,支持有效的 Javascript表达式,比如:a + b, a || 5...

    只不过在 jsx/tsx中 由双大括号{{}} 变为了单大括号{}

    // vue3模板语法
    <span>{{ a + b }}</span>
    
    // jsx/tsx
    <span>{ a + b }</span>

    2、class与style 绑定

    class类名绑定有两种方式,使用模板字符串或者使用数组。

    // 模板字符串
    <div className={`header ${ isBg ? 'headerBg' : '' }`}>header</div>
    //数组
    <div class={ [ 'header', isBg && 'headerBg' ] } >header</div>

    style绑定需要使用 双大括号

    const color = 'red'
    const element = <sapn style={{ color, fontSize: '16px' }}>style</sapn>

    3、条件渲染

       setup() {
           const isShow = false
           const element = () => {
               if (isShow) {
                   return <span>我是if</span>
               } else {
                   return <span>我是else</span>
               }
           }
           return () => (
               <div>
                   <span v-show={isShow}>我是v-show</span>
                   {
                       element()
                   }
                   {
                       isShow ? <p>我是三目1</p> : <p>我是三目2</p>
                   }
               <div>
           )
       }

    4、列表渲染

    同样,jsx/tsx 中也没有 v-for指令,需要渲染列表我们只需要使用Js 的数组方法 map 就可以了

    setup() {
       const listData = [
           {name: 'Tom', age: 18},
           {name: 'Jim', age: 20},
           {name: 'Lucy', age: 16}
       ]
       return () => (
           <div>
               <div class={'box'}>
                   <span>姓名</span>
                   <span>年龄</span>
               </div>
               {
                   prop.listData.map(item => {
                       return <div class={'box'}>
                           <span>{item.name}</span>
                           <span>{item.age}</span>
                       </div>
                   })
               }
           </div>
       )
    }

    5、事件处理

    setup() {
        const clickBox = val => {
            console.log(val)
        }
        return () => (
            <div class={'box1'} onClick={() => clickBox('box1')}>
                <span>我是box1</span>
                <div class={'box2'} onClick={() => clickBox('box2')}>
                    <span>我是box2</span>
                    <div class={'box3'} onClick={withModifiers(() => clickBox('box3'), ['stop'])}>我是box3</div>
                </div>
            </div>
        )
    }

    6、v-model

    jsx/tsx是支持v-model语法的

    // 正常写法
    <input v-model="value" /> // vue
    <input v-model={value} /> // jsx
    
    // 指定绑定值写法
    <input v-model:modelValue="value" /> // vue
    <input v-model={[value,'modelValue']} /> // jsx
    
    // 修饰符写法
    <input v-model:modelValue.trim="value" /> // vue
    <input v-model={[value,'modelValue',['trim']]} /> // jsx

    7、slot插槽

    定义插槽

    jsx/tsx中是没有 slot 标签的,定义插槽需要使用{}或者使用renderSlot函数

    setup 函数默认接收两个参数 1. props 2. ctx 上下文 其中包含 slots、attrs、emit 等

    import { renderSlot } from "vue"
    export default defineComponent({
        // 从ctx中解构出来 slots
        setup(props, { slots }) {
            return () => (
                <div>
                    { renderSlot(slots, 'default') }
                    { slots.title?.() }
                </div>
            )
        }
    })

    使用插槽

    可以通过 v-slots 来使用插槽

    import Vslot from './slotTem'
    export default defineComponent({
        setup() {
            return () => (
                <div class={'box'}>
                    <Vslot v-slots={{
                        title: () => {
                            return <p>我是title插槽</p>
                        },
                        default: () => {
                            return <p>我是default插槽</p>
                        }
                    }} />
                </div>
            )
        }
    })

    8、使用 tsx 实现递归组件-菜单

    主要功能就是根据路由信息自动取生成菜单

    效果如下

    1.png

    代码如下,如果需要控制权限啥的,自己在路由信息的meta中添加对应的参数,然后在menuItem中自行控制

    // index.tsx
    
    import { routes } from '@/router/index'
    import MenuItem from './menuItem'
    import './index.scss'
    
    export default defineComponent({
        setup() {
            const isShowRoutes = computed(() => {
                return routes
            })
            const currentPath = computed(() => {
                return useRoute().path
            })
    
            return () => (
                <el-scrollbar class={`menuContent`}>
                    <el-menu
                        default-active={currentPath.value}
                        mode="vertical"
                        class={'menu'}
                    >
                        {
                            isShowRoutes.value.map((route) => {
                                return <MenuItem item={route} key={route.path}></MenuItem>
                            })
                        }
                    </el-menu>
                </el-scrollbar>
            )
        }
    })
    // menuItem.tsx
    
    import { defineComponent, PropType } from 'vue'
    import { RouteRecordRaw } from 'vue-router'
    import './index.scss'
    
    const MenuItem = defineComponent({
        name: 'MenuItem',
        props: {
            item: {
                type: Object as PropType<RouteRecordRaw>,
                required: true
            }
        },
        setup(props: { item: any }) {
            const router = useRouter()
            const jumpRoute = (path: string) => {
                router.push(path)
            }
            return () => {
                let { item } = props
                if (item.children) {
                    const slots = {
                        title: () => {
                            return <div>
                                <span>{item.meta.title}</span>
                            </div>
                        }
                    }
                    return <el-sub-menu index={item.path} v-slots={slots}>
                        {item.children.map((child: RouteRecordRaw) => {
                            return <MenuItem item={child} key={child.path}></MenuItem>
                        })}
                    </el-sub-menu>
                } else {
                    return <el-menu-item index={item.path} onClick={() => jumpRoute(item.path)}>{item.meta.title}</el-menu-item>
                }
            }
        }
    })
    
    export default MenuItem

    (学习视频分享:web前端开发编程基础视频

    以上就是聊聊vue3中优雅使用 jsx/tsx 的方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:vue3 Vue vue.js
    上一篇:Vue计算属性与侦听器和过滤器超详细介绍 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 如何监听Vue的插槽变化?试试这一招!• Vue如何实现拖拽穿梭框功能?四种方式分享(附代码)• 一文搞懂Vue Diff算法• 手把手教你使用webpack实现vue-cli• Vue计算属性与侦听器和过滤器超详细介绍
    1/1

    PHP中文网