主頁 > 企業開發 > 擁抱jsx,開啟vue3用法的另一種選擇

擁抱jsx,開啟vue3用法的另一種選擇

2023-06-10 08:37:42 企業開發

??背景

公司高級表單組件ProForm高階組件都建立在jsx的運用配置上,專案在實踐落地程序中積累了豐富的經驗,也充分感受到了jsx語法的靈活便捷和可維護性強大,享受到了用其開發的樂趣,獨樂樂不如眾樂樂,為了幫助大家更好的運用jsx,開發提效,特此總結分享,

??效果對比

以前

以往我們開發一個串列的增加、編輯、查看詳情三個操作要準備3個form表單檔案,表單中ui元素共性部分我們要復制三次,例如:

// addForm.vue
<template>
<el-form :model="form" >
 <el-form-item label="活動名稱">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活動區域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活動形式">
 <el-input v-model="form.type" />
 </el-form-item>
 </el-form>
  <el-form-item>
      <el-button >新增</el-button>
    </el-form-item>
</template>


<script setup>
import { reactive } from 'vue'
const form = reactive({
  name: '',
  region: '',
  type: '',
})
...
</script>

// editForm.vue

<template>
<el-form :model="form" >
 <el-form-item label="活動名稱">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活動區域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活動形式">
 <el-input v-model="form.type" />
 </el-form-item>
  <el-form-item>
      <el-button >編輯</el-button>
    </el-form-item>
  </el-form>
</template>


<script setup>
import { reactive,inject } from 'vue'
const form = reactive({})
form=inject('detailData')
...
</script>

// detailForm.vue

<template>
<el-form :model="form" :disabled="true" >
 <el-form-item label="活動名稱">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活動區域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活動形式">
 <el-input v-model="form.type" />
 </el-form-item>
  <el-form-item>
      <el-button >關閉詳情</el-button>
    </el-form-item>
  </el-form>
</template>


<script setup>
import { reactive,inject  } from 'vue'
const form = reactive({})
form=inject('detailData')
...
</script>

如果遇到改欄位名的情況,如把活動名稱的name改成activityName,對應的3個檔案都得去修改,表單改動多的話還有可能存在有得檔案改漏的情況,

現在

現在使用ProForm結合jsx配置,如下



// add.vue
<template>
 <activity-form
 ref="formRef"
 mode="Add"
 />
      <el-button >新增</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>


// edit.vue
<template>
<activity-form
 ref="formRef"
 mode="Edit"
 />
   <el-button >編輯</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>
// detail.vue
<template>
 <activity-form
 ref="formRef"
 mode="detail"
 />
   <el-button >關閉詳情</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>

Form.vue

<template>
  <yun-pro-form
    ref="formRef"
    :form="form"
    :columns="columns"
    :form-props="{ labelPosition: 'top',disabled:mode==='detail' }"
  />
</template>

<script lang="jsx" setup>
import { reactive, ref, computed } from 'vue'
...
const formRef = ref()
const form = reactive({
  name: '',
  region: '',
  type: '',
})
const props = defineProps({
  mode: {
    type: String,
    default: 'Add',
  },
});
const columns = [
  {
    prop: 'name',
    label: '活動名稱',
    type: 'input',
  },
  {
      prop: 'region',
      label: '活動區域',
      // jsx部分
      render: (form) => (
        <el-input clearable  v-model={form.region} />
      ),
   },
    {
      prop: 'type',
      label: '活動形式',
      // jsx部分
      render: (form) => (
        <el-input clearable  v-model={form.type} />
      ),
   },
]

...
</script>

改成上面的形式后,一處改動,3處對應生效,開發的重點也轉移到form表單中對columns的配置上,columns配置則建立在對jsx的運用,當然舉的這個例子只是一個簡單案例,復雜的例子在專案中,下面我們正式開啟jsx之旅吧

??JSX是什么

JSX(JavaScript 和 XML),是一個 HTML-in-JavaScript 的語法擴展,首先在 React 中被進入,它允許我們在JavaScript中撰寫類似HTML的代碼,并將其轉換為JavaScript物件,Vue3中引入了對JSX的支持,使得我們可以更加靈活地撰寫組件模板,不再局限于Vue2.x中的模板語法,JSX 可以很好地描述 UI 應該呈現出它應有互動的本質形式,

形如:

const element = <div id="root">Hello World</div>

function getGreeting(user) {
    if (user) {
        return <h1>Hello, {formatName(user)}!</h1>;
    }
    return <h1>Hello, Stranger.</h1>;
}

??JSX 和 template 的區別

--語法上有很大區別:

?JSX 本質就是 js 代碼,可以使用 js 的任何能力 ?template 只能嵌入簡單的 js 運算式,其他需要指令,如 v-if ?插值不同,jsx 使用單括號 { },template 使用雙括號 {{ }} ?JSX 已經成為 ES 規范,template 還是 Vue 自家規范 ?--本質是相同的: ?都會被編譯為 js 代碼(render 函式) ?

??基本用法

安裝使用

vite 官方提供了官方的插件來支持在 vue3 中使用 jsx

yarn add @vitejs/plugin-vue-jsx

安裝完之后在 vite.config.js 檔案中的 plugins 欄位中添加 jsx 支持:


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

插值運算式

// template
<template>
  <span>{{ a + b }}</span>
</template>
 
// jsx
 render: () => {
    return (
       <span>{ a + b }</span>
    )
}

條件渲染

?jsx只保留了 v-show指令,沒有 v-if指令 ?使用 if/else和三目運算式來實作判斷
// template v-if  v-show
<template>
  <div v-if="show">是</div>
  <div  v-else>否</div>
   <div v-show="show">我是v-show</div>
</template>
 
// jsx
 render: () => {
    const show = ref(true);
    return (
    <div>
       <div>{show.value ? <div>是</div> : <div>否</div>}</div>
        <div v-show={!show.value}>我是v-show</div> 
     </div>
    )
}
// jsx  if-else

 render: () => {
    const isShow = false
      const element = () => {
       if (isShow) {
           return <div>是</div>
       } else {
           return <div>否</div>
       }
   }
    return (
    <div>
           {
               element()
           }
        <div v-show={!show.value}>我是v-show</div> 
     </div>
    )
}


樣式系結

?class類名系結有兩種方式,使用模板字串或者使用陣列, ?style系結需要使用 雙大括號
// template
<template>
 <div   :></div>
 <div :></div>
 <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
</template>


// jsx
// jsx 模板字串
<div className={`static  ${ isActive ? 'active' : '' }`}>header</div>
//jsx 陣列
<div class={ [ 'static', isActive && 'active' ] } >header</div>

// jsx 樣式系結需要使用雙大括號,
 render: () => {
    const width = '100px'
    return (
      <button style={{ width, fontSize: '16px' }}></button>
    )
}

串列回圈

// template v-for

<template>
  <ul>
    <li v-for="item in list" :key="item">{{ item }}</li>
  </ul>
</template>

// jsx 陣列 .map 函式
 
 render: () => {
    return <>
      <ul>
        { list.map(item => <li>{item}</li>)}
      </ul>
    </>
  }

事件處理

?jsx系結事件使用的是 單大括號 {},事件系結不是以 @為前綴了,而是改成了 on,例如:click 事件是 onClick ?如果需要使用事件修飾符,就需要借助withModifiers方法啦,withModifiers 方法接收兩個引數,第一個引數是系結的事件,第二個引數是需要使用的事件修飾符,或者在有些修飾符不生效的情況下采用鏈式駝峰的形式進行設定,如@click.once變為 onClickOnce
// template 

<template>
 <button @click="clickButton('button1')"> 點擊</button>
 <!-- 單擊事件將停止傳遞 -->
  <a @click.stop="doThis"></a>
 <!-- 點擊事件最多被觸發一次 -->
 <a @click.once="doThis"></a>
</template>

// jsx 陣列 .map 函式
 
 render: () => {
     const clickButton = val => {
        console.log(val)
    }
    return (
      <div>
      <button  onClick={() =>clickButton('button1')}>點擊</button>
       <a onClick={withModifiers(() => doThis(), ['stop'])}></a>
       <a onClickOnce={doThis}></a>
      </div>
    )
  }


標簽屬性系結

// template 
<template>
<div v-bind="properties"></div>
</template>

//jsx
 render: () => {
    return (
      <div {...properties}></div>
    )
  }

V-model


// 一般用法
<input v-model="value" /> //  template
<input v-model={value} /> // jsx

// 指定系結值寫法
<input v-model:modelValue="https://www.cnblogs.com/mrwh/archive/2023/06/09/value" /> //  template
<input v-model={[value,'modelValue']} /> // jsx

// 修飾符寫法
<input v-model:modelValue.trim="value" /> //  template
<input v-model={[value,'modelValue',['trim']]} /> // jsx

插槽

定義插槽

jsx/tsx中是沒有 slot 標簽的,定義插槽需要使用{}或者使用renderSlot函式

setup 函式默認接收兩個引數 1. props 2. ctx 背景關系 其中包含 slots、attrs、emit 等


// template
<template>
  <div>
   <slot></slot>
   <slot name="title"></slot>
  </div>
</template>

// jsx
import { renderSlot } from "vue"
export default defineComponent({
    // 從ctx中解構出來 slots
    setup(props, { slots }) {
        return () => (
            <div>
                { renderSlot(slots, 'default') } // 等價于  { slots.default?.() }
                { slots.title?.() }
            </div>
        )
    }
})


使用插槽

通過 v-slots 來使用插槽

// template
<template>
   <yun-table
  >
    <template #action="{ row }">
      <el-button type="action" @click="handleDel(row)">
        洗掉
      </el-button>
    </template>
  </yun-table>
</template>

// jsx
render: (form) => {
        const slots = {
          action: ({ row }) => <el-button type="action" onClick={() => handleDel(row)}>
          洗掉
        </el-button>,
        };
        return (
             <yun-table
              v-slots={slots}
            >
            </yun-table>
          
        );
      },



jsx基礎模板

import { defineComponent, onMounted, ref } from 'vue';

export default defineComponent({
  // props: ['xx'],
  setup(props,{ emit }) {
    onMounted(() => {
      // ...
    })
    return () => (
      <div></div>
    )
  }
})

組件運用

在 .vue 檔案中使用 jsx組件

// 父
 
<template>
  <div >
    <JSXDemo />
  </div>
</template>
 
<script setup lang="jsx">
import JSXDemo from '@/components/JSXDemo.vue'

</script>
 
// JSXDemo.vue
 
<script>
import { ref } from 'vue'
export default {
  setup () {
    const countRef = ref(200)
 
    const render = () => {
      return <p>DEMO1--{countRef.value}</p> 
    }
    return render
  }
}
</script>
 
 

在.jsx檔案格式中父子組件屬性傳遞

// 父組件
 
import { defineComponent, ref } from 'vue'
import JSXChild from './JSXChild.jsx'
 
export default defineComponent(() => { // 傳入 setup 函式
  const countRef = ref(360)
 
  const render = () => {
    return <>
      <p>數量--{countRef.value}</p>
      <JSXChild a={countRef.value + 100}></JSXChild>  // vue3的template會自動決議ref的.value,在jsx中ref的.value是不會被自動決議的
    </>
  }
  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
  }
})


??經驗總結

我們該怎么選擇 JSX 和 template ?

template優勢:template 的語法是固定的,有 v-if、v-for 等等語法,按照這種固定格式的語法書寫的代碼, Vue3 在編譯層面就可以很方便地去做靜態標記的優化,減少Diff程序,比如靜態提升,型別標記,樹結構打平等來提高虛擬 DOM 運行時性能,這也是 Vue 3 的虛擬 DOM 能夠比 Vue 2 快的一個重要原因,

JSX優勢:template 因為語法限制原因,不能夠像 JSX 那樣可以支持更動態的需求,每一個 .vue 檔案結尾的檔案都是一個組件,而且只能 export default 出一個組件,JSX 則不同 ,是可以在一個檔案內回傳多個組件的,比如我們寫一個頁面的時候其實可能會需要把一些小的節點片段拆分到小組件里面進行復用,這些小組件在jsx里面,寫個簡單的函陣列件就能搞定,例如:

那如何選擇呢?

在實作業務需求的時候,優先使用 template,盡可能地利用 Vue 本身的性能優化,如串列、彈窗和抽屜,而對于動態性要求較高的組件可以使用 JSX 來實作,比如動態表單,封裝動態遞回組件,而對于公司專案來說,大多數業務需求都是表單類的,那就趕緊用上jsx吧,用久了你就會發現,哎,真香,

如果你覺得不錯的話,右下角,隨手點個推薦,鼓勵支持hhh^_^

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/554820.html

標籤:其他

上一篇:記錄--開始使用Vue 3時應避免的10個錯誤

下一篇:返回列表

標籤雲
其他(160735) Python(38219) JavaScript(25491) Java(18216) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7241) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4589) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2435) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) 功能(1967) HtmlCss(1957) Web開發(1951) C++(1933) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1880) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 擁抱jsx,開啟vue3用法的另一種選擇

    📝背景 公司高級表單組件ProForm高階組件都建立在jsx的運用配置上,專案在實踐落地程序中積累了豐富的經驗,也充分感受到了jsx語法的靈活便捷和可維護性強大,享受到了用其開發的樂趣,獨樂樂不如眾樂樂,為了幫助大家更好的運用jsx,開發提效,特此總結分享。 💎效果對比 以前 以往我們開發一個列 ......

    uj5u.com 2023-06-10 08:37:42 more
  • 記錄--開始使用Vue 3時應避免的10個錯誤

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 Vue 3 穩定已經有一段時間了。許多代碼庫正在生產中使用它,其他人最終也必須進行遷移。我有機會與它一起作業,并記錄了我的錯誤,這可能是你想避免的。 1.使用回應式助手宣告基本型別 資料宣告曾經很簡單,但現在有多個輔助工具可用。現在的一般 ......

    uj5u.com 2023-06-10 08:37:32 more
  • JavaScript語法學習

    # JS語法學習 **Javascript:客戶端的腳本語言** ## **1. JavaScript資料型別** ![](https://img2023.cnblogs.com/blog/3008601/202306/3008601-20230607170622855-1334758269.png ......

    uj5u.com 2023-06-10 08:37:23 more
  • 深入決議React DnD拖拽原理,輕松掌握拖放技巧!

    >我們是[袋鼠云數堆疊 UED 團隊](http://ued.dtstack.cn/),致力于打造優秀的一站式資料中臺產品。我們始終保持工匠精神,探索前端道路,為社區積累并傳播經驗價值。。 >本文作者:霽明 # 一、背景 ## 1、業務背景 業務中會有一些需要實作拖拽的場景,尤其是偏視覺方向以及移動端 ......

    uj5u.com 2023-06-10 08:37:09 more
  • 前端常見的字符編碼方案

    在前端開發中,最常見的字符編碼方案是 UTF-8。UTF-8是一種可變長度的 Unicode 編碼方案,可以表示幾乎所有的字符,并且與 ASCII 兼容。由于互聯網的廣泛應用和多語言的支持,UTF-8成為了前端開發中的首選字符編碼方案。 使用UTF-8編碼的好處: 1. 多語言支持 :UTF-8可以 ......

    uj5u.com 2023-06-10 08:36:58 more
  • Map

    ## 簡介 Map -- JS內置物件 Map物件保存鍵值對 -- 能夠記住鍵的原始插入順序 -- 任何值(資料型別包括物件)都可以作為一個鍵或一個值 Map物件是鍵值對的集合 -- Map中的一個鍵只能出現一次 Map物件按鍵值對迭代 -- for...of回圈在每次迭代后會回傳一個形式為[key ......

    uj5u.com 2023-06-10 08:35:47 more
  • JavaScript語法學習

    # JS語法學習 **Javascript:客戶端的腳本語言** ## **1. JavaScript資料型別** ![](https://img2023.cnblogs.com/blog/3008601/202306/3008601-20230607170622855-1334758269.png ......

    uj5u.com 2023-06-10 08:35:25 more
  • 前端常見的字符編碼方案

    在前端開發中,最常見的字符編碼方案是 UTF-8。UTF-8是一種可變長度的 Unicode 編碼方案,可以表示幾乎所有的字符,并且與 ASCII 兼容。由于互聯網的廣泛應用和多語言的支持,UTF-8成為了前端開發中的首選字符編碼方案。 使用UTF-8編碼的好處: 1. 多語言支持 :UTF-8可以 ......

    uj5u.com 2023-06-10 08:35:20 more
  • 深入決議React DnD拖拽原理,輕松掌握拖放技巧!

    >我們是[袋鼠云數堆疊 UED 團隊](http://ued.dtstack.cn/),致力于打造優秀的一站式資料中臺產品。我們始終保持工匠精神,探索前端道路,為社區積累并傳播經驗價值。。 >本文作者:霽明 # 一、背景 ## 1、業務背景 業務中會有一些需要實作拖拽的場景,尤其是偏視覺方向以及移動端 ......

    uj5u.com 2023-06-10 08:34:49 more
  • Map

    ## 簡介 Map -- JS內置物件 Map物件保存鍵值對 -- 能夠記住鍵的原始插入順序 -- 任何值(資料型別包括物件)都可以作為一個鍵或一個值 Map物件是鍵值對的集合 -- Map中的一個鍵只能出現一次 Map物件按鍵值對迭代 -- for...of回圈在每次迭代后會回傳一個形式為[key ......

    uj5u.com 2023-06-09 08:39:29 more