來聊聊Vue中使用Render函數和JSX

2022-01-02 前端娛樂圈
前言

這些天好久沒更文了,最近又迷上打CF,耽擱了寫文時間(打遊戲真的有癮),還是勸大家合理安排遊戲時間(反正我是控制不住,哈哈哈)。

附上一圖

哈哈哈,當然有興趣的小夥伴加我wx,來「運輸船」約一下哦,"北部大區"。

回歸正題。

Render函數

render函數是組件渲染的重要核心,它跟template模板開發一樣,只不過這種形式開發,它(render)更接近底層,這樣能讓Vue編譯時少轉換一次。

讓我們來看一下哪裡能用到render函數。

我們都知道Vue項目入口文件main.js裡面有個render函數長下面這樣,將項目的App根組件,掛載到根實例上通過render渲染。

new Vue({
  render: h => h(App)
}).$mount('#app')

我們來解刨一下render函數身體。

render函數返回值是一個VNode -> "virtual node"虛擬節點

render函數的參數是一個createElement函數

createElement返回值也是一個VNode節點

「代碼演示:」

index.js

export default {
    data() {
        return {
            name: '蛙人'
        }
    },
    render(createElement) {
        return createElement(
            "div", 
            { attrs: {title: "蛙人"} }, 
            [
                createElement("span", null, "蛙人")
            ]
        )
    }
}

main.js

import config from "./index.js"
Vue.component("test", config)

上面會調用標籤會創建出一個div帶有span子級的內容,注意createElement第二個參數屬性這裡,這裡不能亂寫,必須遵守官網風格點擊這裡。

當然這裡肯定有人會問,這樣寫有什麼用,跟template寫不一樣嘛,render函數這樣寫還麻煩可讀性不強。

分情況,有時候用render更加靈活,咱就拿官網最典型的案例來「舉個例子」

封裝一個組件,進行傳入數字參數,就顯示數字參數的標籤,你肯定會先想到這樣。

<template>
    <div>
        <h1 v-if="num == 1"></h1>
        <h2 v-if="num == 2"></h2>
        <h3 v-if="num == 3"></h3>
        <h4 v-if="num == 4"></h4>
        <h5 v-if="num == 5"></h5>
        <h6 v-if="num == 6"></h6>
    </div>
</template>

上面這樣實現是沒問題的,但是代碼會冗餘,一堆判斷。我們再來看一下render函數的實現

<script>
  render: function (createElement) {
    return createElement(
      'h' + this.num,
    )
  },
  props: {
    num: {
      type: Number,
      required: true
    }
  }
</script>

上面兩種都實現了同樣的功能,是不是render函數這種方式看起來要簡潔的多。所以一般用render函數封裝東西是比較靈活的,尤其是配置和模板分離。深入理解配置這裡。

什麼是JSX

JSX是JavScript和XML結合一種的格式,是JavaScript的擴展語法。說白了就是可以在JavaScript代碼中使用JSX。JavaScript在解析JSX時會先創建虛擬DOM,JSX最後會被編譯為JavaScript代碼執行。

為什麼要用JSX

有的人肯定覺得用render函數寫如果嵌套子級太多層看著太彆扭了,可讀性太差。

export default {
    render(createElement) {
        return createElement(
            "div", 
            { attrs: {title: "蛙人"} }, 
            [
                createElement(
                    "span", 
                    null, 
                    "蛙人"
                ),
                createElement(
                    "span", 
                    null, 
                    createElement(
                        "b", 
                        null, 
                        "前端娛樂圈"
                    )
                ),
                createElement(
                    "span", 
                    null, 
                    createElement(
                        "b", 
                        null, 
                        createElement(
                            "i", 
                            null, 
                            "關注前端娛樂圈"
                        )
                    )
                )
            ]
        )
    }
}

比如上面這種,嵌套多層,可讀性太差,時間一長自己還得捋半天。

所以為了解決這問題,JSX就登場了,JSX相當於就是createElement的語法糖,這種形式可以直接使用template模板那種格式在render函數裡寫。

我們用這種形式來還原一下上面的createElement寫的,是不是這種很簡潔易讀。

export default {
    render() {
        return (<div>
            <span>蛙人</span>
            <span>
                <b>前端娛樂圈</b>
            </span>
            <span>
                <b>
                    <i>關注前端娛樂圈</i>
                </b>
            </span>
        </div>)
    }
}

JSX和Render函數有什麼不同

除了寫法不一樣外,沒什麼不同,屬性都是遵循Vue文檔上的。

我們來使用JSX語法,看看怎麼使用,這裡玩過React的同學估計都會使用。

export default {
 data() {
  return {
   name: "前端娛樂圈",
   dataList: {
    title: "前端娛樂圈",
    href: "www.baidu.com"
   }
  }
 },
    render() {
        return <div onClick={this.xxx} {...{attrs: this.dataList}}>{ this.name }</div>
    }
}

使用

「如果你的項目是Webpack搭建,babel@6的情況」

npm i @babel/core @vue/babel-preset-jsx babel-loader

根目錄.babelrc文件

{
 "plugins": ["transform-vue-jsx"]
}

webpack.config.js

{
    test: /\.js/,
    use: "babel-loader"
}

「如果你的項目是Webpack搭建,babel@7的情況」

npm i @babel/core @vue/babel-preset-jsx babel-loader @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

根目錄.babelrc文件

文檔說明babel7兼容JSX問題

{
 "presets": ["@vue/babel-preset-jsx"]
}

webpack.config.js

{
    test: /\.js/,
    use: "babel-loader"
}

「如果你的項目是Vue-cli」

最新版本的cli是會默認支持JSX語法的,如果你的版本較老請跟上面一樣的配置。

npm i @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

babel.config.js

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

結語

感謝觀看,有問題隨時找我哈,「如果有想運輸船約一下的記得私聊我哦,嘿嘿」

相關焦點

  • 如何在Vue項目中使用JSX?
    JSX是一種JavaScript和XML的結合,即JavaScript + XML = JSX,JSX源於Facebook,可以在JavaScript裡寫XML,因為這個特性,所以具備了JavaScript的靈活性,同時又兼具html的語義化和直觀性為什麼使用 JSX?
  • 用 jsx 寫 vue 組件
    的組件時,一般都是用的是模版,這種方式看起來比較簡潔,而且vue作者也推薦使用這個方式,但是這種方式也有一些它的弊端,例如模版調試麻煩,或者在一些場景下模版描述可能沒那麼簡單和方便。在使用jsx之前我們需要安裝一個babel插件(babel-plugin-transform-vue-jsx )安裝方式:npm install\  babel-plugin-syntax-jsx\  babel-plugin-transform-vue-jsx\  babel-helper-vue-jsx-merge-props
  • Vue 中 render 函數有點意思
    但是,有一些用例,如基於輸入或插槽值創建動態組件方式,render 函數會比模板完成的更好也更出色。用過 React 開發的人對 render 函數應該非常熟悉,因為React組件通過 JSX和 render 函數來構建的。儘管Vue render 函數也可以用JSX編寫,但在這裡我們使用原生 JS方式,因為這樣,我們可以更輕鬆地了解Vue組件系統的一些基礎。
  • 【Vue】徹底理解Vue中render函數與template的區別
    一、render函數與template對比VUE一般使用template來創建HTML
  • vue中ast生成render
    我們先使用 vue 的模板編譯庫 vue-template-compiler 驗證一下輸出結果。
  • 全面了解 Vue.js 函數式組件
    lt;h1>Hello, {props.name}</h1>; }結合 TypeScript 的話,還可以使用 type 和 FC<propsType> 來對這個返回了 jsx 的函數約束入參:type GreetingProps
  • 一個niubility的Vue遊戲,真厲害!(收藏)
    (每20行增加一個級別);4、開發中的經驗梳理,以及如何把 React 項目重構為 Vue 版本Vue 版本和 React 版本核心代碼基本相同,但在編寫組件的時候遇到了幾個問題,比如:如何把 React 組件改寫成 Vue 的,我的思路是把組件當成函數,保證一個輸入(props)能得到一個確定的輸出(view),然後對不同方法也是做同樣處理, React 的 setState
  • 【乾貨】Vue的class語法與常規語法對照表
    Vue的class語法配合TypeScript 來進行組件開發,我也簡單總結了一下Class語法與常規語法的對照,便於記憶和查閱。項目中使用的是vue-class-component、vue-property-decorator配合TypeScript來進行開發的,其中vue-class-component提供了class語法,而vue-property-decorator提供了一些裝飾器來方便代碼的組織和編寫。
  • 面試官:聊聊對Vue.js框架的理解
    在Vue中可以使用 EventBus 來作為溝通橋梁的概念,每一個Vue的組件實例都繼承了 EventBus,都可以接受事件$on和發送事件$emit。如上面一個例子,child.vue 組件想修改 parent.vue 組件的 parentMsg 數據,怎麼辦呢?
  • Vue全家桶&vue-router原理
    原理 Vue全家桶:vue + vue-router(路由)+ vuex(狀態管理)+ axios(請求)本次主要分析並實現簡版vue-router,從源碼中學習借鑑它和 Vue.js 的核⼼深度集成,讓構建單⻚⾯應⽤變得易如反掌。
  • 【組件庫從0到1】Vite + Vue3 + TSX開發指南
    村長的回答中大多數會提到兩個關鍵點:加強工程化實踐能力和底層原理源碼知識。工程化能力對於小夥伴們在工作中解決問題有直接影響,如果你想成為小組內的核心程式設計師,拿更高的職位和薪資,能夠給大家搭架子,解決問題,重難點突破是非常關鍵的幾個考察點。實踐中,我們如何刻意提升自己這方面的能力,我覺得給公司搭建一套組件庫就很好。
  • Vue中的Class Component使用指南
    /App'new Vue({ el: '#app', render: h => h(App)})在註冊完這些鉤子後,在類組件中,可以把它們當成類的原型方法來使用:import Vue from 'vue'import Component from 'vue-class-component
  • Vue常見面試題攻略
    而模板編譯的目的僅僅是將template轉化為render function,這個過程,正好可以在項目構建的過程中完成,這樣可以讓實際組件在 runtime 時直接跳過模板渲染,進而提升性能,這個在項目構建的編譯template的過程,就是預編譯。那template和jsx的有什麼分別?
  • React合集:深入理解JSX
    簡單來理解JSX就是 JavaScript 和 html 可以混著寫,開發者在開發過程中可以更加靈活快速,並且可以一目了然的看清楚DOM結構。JSX的特性及使用嵌入表達式如果我們的JSX中的內容是動態的,可以使用大括號{},來插入一個 JavaScript 表達式, 大括號中可以是變量、字符串、數組、函數調用等任意js表達式:let title ="Hello JSX"const comics = ["哪吒",
  • Vue 新版腳手架工具,300 行代碼輕盈新生!
    本文就是通過調試和大家一起學習這個300餘行的源碼。閱讀本文,你將學到:1. 學會全新的官方腳手架工具 create-vue 的使用和原理2. 學會使用 VSCode 直接打開 github 項目3. 學會使用測試用例調試源碼4. 學以致用,為公司初始化項目寫腳手架工具。5. 等等2.
  • 一文搞定前端自動化測試(Vue 實戰)
    ,這裡選用了 `Vite`[5] 作為構建工具來創建項目,用 @vitejs/app 創建一個 vue-ts 項目。@vitejs/plugin-vue-jsx:提供開發時在 Vue 中使用 JSX/TSX 語法的 Vite Plugin。vite-plugin-windicss:提供開發時在 Vue 中使用 Windi CSS 能力的 Vite Plugin。
  • Vue隱藏技能:運行時渲染用戶寫入的組件代碼!
    其實主要是為了服務於 template 模板語法,當你在 template 中寫了 <compA propA='value'/>,有了這個註冊聲明才能在編譯時找到compA。如果不使用 template,那麼這個註冊就可以省了。不使用 template 怎麼渲染呢,使用render 函數[6]呀!
  • React系列二 - 核心JSX語法一
    JSX的書寫規範:JSX的頂層只能有一個根元素,所以我們很多時候會在外層包裹一個div原生(或者使用後面我們學習的Fragment);為了方便閱讀,我們通常在jsx的外層包裹一個小括號(),這樣可以方便閱讀,並且jsx可以進行換行書寫;JSX的本質,我們後面再來討論;3.2.
  • 【Vuejs】1024- 手摸手教你玩轉 Vue render 函數
    $refs['child-input'].focus()   }}</script>我們只要在render函數中添加這一行判斷就行<script> export default {  render() {
  • 前端神器:一行命令,React 組件轉 Vue 組件!
    而基本react component的定義更多是基於props和state來渲染的組件,其中也可以包括發請求。本文先介紹兩個框架的組件共性和不兼容的地方,再介紹react-to-vue的使用和原理。在實際業務中,陸金所100多個的react基礎業務組件,react-to-vue可以轉化90%以上,變成vue組件。