首页 > 其他分享 >解锁 Vue 3 神奇技巧:让模板复用达到极致

解锁 Vue 3 神奇技巧:让模板复用达到极致

时间:2023-10-07 18:31:41浏览次数:32  
标签:Vue 模版 解锁 复用 content item vue 组件 jsx

引出

在vue的日常开发当中,我们可能会遇到这样的一种情况:

某一部分的模版需要重复利用, 但又不至于到新开1个组件的地步。

比如:

js
复制代码
<template> 
    <div v-for="item in list">
        // 条件渲染
        <div v-if="isCase1(item.id)" class="case1Class ...">
            <h2>{{ item.title }}</h2> 
            <p class="...">{{ item.content }}</p> 
            <span> {{ item.cases }} </span>
        </div>
        <p v-else-if="isCase2(item.id)" class="case2Class ...">{{ item.content }}</p> 
        <span v-else> {{ item.cases }} </span>
        // 条件可能有更多....
    </div> 
</template>

这里面的<p> <span> 都是可以复用的,但为此新开俩组件又没有必要。

那么又有什么解决方案呢?

来自react的提示

在react 当中啊,碰到这种情况,可以定义1个 局部的函数式组件

示例:

jsx
复制代码
function Com ()  { 
    // 局部组件
    const  ReuseP = ({content,className})=> (<p className={`${className} ...其余复用class`}>{ content }</p> )
    
    return (
        list.map(i=>{
            if(isCase1(i.id)){
                return (
                    <div>
                        {/* ... */}
                        {/* 在这里去复用 */}
                        <ReuseP  {...i}  className="case2Class" />
                    </div>
                )
            }
        })
    )
}

回到vue

那么在Vue当中能不能实现呢? 答案显然是可以的

其实在Vue3当中,可以支持在.vue文件即SFC当中去使用jsx/tsx语法的

看看文档

解锁 Vue 3 神奇技巧:让模板复用达到极致_Vue

是不是很熟悉,这不就是react当中的函数式组件么

也就是说,可以将上面的例子改写成这样

diff
复制代码
<template> 
    <div v-for="item in list">
        // 条件渲染
        <div v-if="isCase1(item.id)" class="case1Class ...">
            <h2>{{ item.title }}</h2> 
-           <p class="...">{{ item.content }}</p>
+           <reuseP v-bind="item"/> 
            <span> {{ item.cases }} </span>
        </div>
-        <p v-else-if="isCase2(item.id)" class="case2Class ...">{{ item.content }}</p> 
+        <reuseP v-else-if="isCase2(item.id)" v-bind:content="item.content" v-bind:your-class="'case2Class'" ></reuseP>
        <span v-else> {{ item.cases }} </span>
        // 条件可能有更多....
    </div> 
</template>

+ // ⚠️ 注意这里的lang
+ <script setup lang="jsx">
+    const reuseP = ({ content }) => (
+     <p className={`${args['your-class']} ...其余复用class`}>{ content }</p>
+ )
+ </script>

可以清晰的看到在.vue文件即Vue但文件组件(SFC)里面通过jsx去实现了一个组件内的小组件,进而达到了组件内模版复用的效果。

ps: 当然这里只是举例了可以复用<p>的例子,你也可以更加优雅的去实现,比如把整个v-for都用jsx写一下

大概的代码结构会是这样

解锁 Vue 3 神奇技巧:让模板复用达到极致_前端源码_02

当然,这里只是给大家提供一个思路,jsx与template的结合是相当灵活的,不过相信聪明的看官们能够轻松应对。

也许有看官还不了解jsx

回顾

首先回顾一下vue模版语法的编译产物

解锁 Vue 3 神奇技巧:让模板复用达到极致_商城源码_03

它其实是将模版也解析成渲染函数的形式

这里的createElementVNode其实就是h函数,作用是创建VNode

解锁 Vue 3 神奇技巧:让模板复用达到极致_商城源码_04

那么整一个渲染函数的作用就是结合 上下文对象 生成VNode

VNode就是用对象去描述DOM节点(WEB端)

比如这样一个真实DOM

解锁 Vue 3 神奇技巧:让模板复用达到极致_Vue_05

对应的虚拟VNode的核心描述

js
复制代码
const vnode = {
  tag: 'div', // 标签名为 'div'
  data: {},   // 无属性、样式和事件等信息
  children: [
    {
      tag: undefined, // 文本节点没有标签名
      data: {},       // 无属性、样式和事件等信息
      children: undefined,
      text: 'Hello JetTsang' // 文本内容为 'Hello JetTsang'
    }
  ],
  text: undefined,
  //。。。省略
};

当然,在Vue和React中,对于VNode结构的描述存在一些区别,包括不同的属性等等。然而,它们的本质都是以一种数据结构来描述真实节点。

这例子当中VNode就是外面的这个div(当然忽略_openBlock这个块级容器 )

jsx

其实JSX和模版语法一样,借助@vue/babel-plugin-jsx,也能转换成渲染函数

拿一个最简单的例子

标签:Vue,模版,解锁,复用,content,item,vue,组件,jsx
From: https://blog.51cto.com/u_15723831/7741126

相关文章

  • vue3 新增 mitt 的使用
    在Vue3中,你可以使用 mitt 库来实现事件总线,以便在组件之间进行通信。下面是详细的介绍如何使用 mitt:安装 mitt 库: 首先,确保你已经安装了 mitt 库。你可以使用npm或yarn来安装它:插入代码复制代码npminstallmitt或插入代码复制代码yarnaddmitt......
  • 记录--Vue 右键菜单的秘密:自适应位置的实现方法
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助下图这个情景,你是否也遇到过?当你右键点击网页上的某个元素时,弹出的菜单被屏幕边缘遮挡了,导致你无法看清或选择菜单项?上图中右键菜单的选项并不是固定不变的,它会根据不同的元素或场景来显示不同的选项。也就是......
  • vue2自定义指令实现el-dropdown下拉菜单项最小宽度等于内容宽度
    //在main.js添加Vue.directive('siem-dropdown',function(el,binding,vNode){letul=el.querySelector("ul")letuid=vNode.componentInstance._uid;//获取下拉菜单实例的uidletsiemDropdownClass=`siem-dropdown-${uid}`;ul.cla......
  • getRefs is undefined html vue2项目 报错
    vue2项目提示getRefsisundefined在div上面写了,ref,还写了v-if然后再watch中操作了ref导致报错。分析:组件因为v-if为false没有注册和渲染,在操作的时候还使用了this.$refs函数就会获取不到解决办法:v-if换成v-show ......
  • 创建vue3项目、setup函数、ref函数、reactive函数、计算监听属性、生命周期、torefs、
    创建vue3项目#两种方式-vue-cli:vue脚手架---》创建vue项目---》构建vue项目--》工具链跟之前一样-vite:https://cn.vitejs.dev/-npmcreatevue@latest一路选择即可#运行vue3项目-vue-cli跟之前一样-vi......
  • vue3中defineComponent 的作用详解
    转自:https://www.jb51.net/article/263096.htm 这篇文章主要介绍了vue3中defineComponent 的作用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 vue3中,新增了defineComponent,它并没有实现任何的逻辑,只是把接收的......
  • 是用非构建工具开始使用Vue3
     <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • Vue3中shallowReactive 与 shallowRef 的用法
    转自:https://blog.csdn.net/qq_54527592/article/details/119840044  shallowReactive与shallowRef   shallowReactive:只处理对象最外层属性的响应式(浅响应式)。   shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。   什么时候使用?     ......
  • Vue3
    vue3.3.4+vite4.4.91.组件安装1.1ElementPlusnpminstallelement-plus--savemain.jsimportElementPlusfrom'element-plus'import'element-plus/dist/index.css'constapp=createApp(App);app.use(ElementPlus).mount('#app'......
  • Vue3 Div 与 v-for 的配合应用,超出自动带滚动条
    效果图 代码<li><ahref="javascript:;"class="IndReaflexCHuans"><i></i><p>当前会议[0]</p></a><divstyle="height:80%;overflow:auto;"><divv-for="......