如何在 Vue 中使用 JSX 以及使用它的原因


vue.js 具有簡單的 API 和幾個選項,可用於在我們的組件中定義html模板。

我們可以使用<template>標簽選項,在根組件實例上定義template屬性,或者使用單文件組件。

上面的選項很棒並且可以完美地工作,但是,在您的應用程序的生命周期中,有時會感到笨拙,設計過度或非常不靈活。

那么,我們為什么要使用 jsX 而不是其他模板定義呢?

  • JSX 更易讀,<div></div> 的寫法一看就是比 this.$createElement('div', {}, [...]) 簡潔很多。
  • JSX 也是 JavaScript。
  • vue支持JSX。
  • JSX 使自定義 Vue 組件更容易導入和管理。

 

簡介

先舉一個例子來說明為什么 JSX 是好的。

我們要構建一個<TextField/>組件,該組件可以是普通的單行文本輸入或多行輸入(文本區域)。 我們的模板聲明可能看起來像這樣。

 <div> <textarea v-if="multiline" v-model="content" :name="name" :placeholder="placeholder" :aria-invalid="false"> <input v-else v-model="content" :name="name" :placeholder="placeholder" :aria-invalid="false"> </div>

從上面的代碼片段中可以看到,我們很快就會遇到一些問題,比如重復代碼等等。想象一下,必須支持input上面所列的各種屬性。上面的這個小片段將會增長並成為一個難以維護的噩夢。

要解決這個問題,我們需要使用Vue進行降級處理,因此需要使用理接近Vue的內部API來解決這個問題。

 

render() 方法

注意:這里並不是說沒有JSX就沒有一種簡單的方法來處理上面的問題,只是說將這個邏輯移動到帶有JSX的render()方法可以使組件更直觀。

我們在 Vue 中創建的每個組件都有一個render方法。這個就是 Vue 選擇渲染組件的地方。即使我們不定義這個方法,Vue 也會為我們做這件事。

這意味着當我們在 Vue 中定義 html 模板時,Vue 的模板編譯器將其編譯為一個createElement函數,該函數帶有幾個參數並從render函數返回結果。

為了修復上一節中的代碼,我們刪除了template屬性或template標簽,並在組件上定義了render()方法。 如果在組件上定義了render方法,則 Vue 將忽略template定義。

...
 export default { name: 'TextField', render (createElement) { const tag = this.multiline ? 'textarea' : 'input' return createElement(tag, { class: { 'text-input': true, 'is-disabled': false }, attrs: { name: this.name, placeholder: this.placeholder, 'aria-invalid': false } }) } } ...

上面的代碼做了幾件事:

  1. render方法從Vue獲取一個createElement助手。
  2. 我們以編程方式定義我們的標簽。
  3. 然后,我們創建標簽並將其屬性,類等作為對象傳遞。 我們可以傳遞給createElement的選項很多。
  4. 我們返回新創建的元素進行渲染。

我們為 Vue 組件定義的每個模板都將轉換為可返回createElement函數的render方法。 因為這個原因,render方法將優先於模板定義。

舉個例子:

// HTML
<div> <p>Only you can stop forest fires</p> </div> 

模板編譯器將把上面的 HTML 轉換成:

...
render (createElement) {
  return createElement( 'div', {}, createElement( 'p', {}, 'Only you can stop forest fires' ) ) } ...

現在你可能會問這個問題:“對可讀性來說這不好嗎?” 答案是肯定的。 一旦定義了具有許多元素嵌套級別或具有多個同級元素的組件,我們就會遇到這個新問題。

這就是 JSX 出現的原因,它可以很好的解決此類問題。

 

JSX 是什么

JSX 是 Facebook 工程團隊創造的一個術語。

JSX 是 JavaScript 的類似XML的語法擴展,沒有任何定義的語義。

JSX 不打算由引擎或瀏覽器實現。相反,我們將使用 Babel 之類的轉置器將JSX轉換成常規的 JS 。

// 此行是JSX的示例 const heading = <h1>Welcome to Scotch</h1>;

基本上,JSX 允許我們在 JS 中使用類似 Html 的語法。

 

配置 Vue 以使用 JSX

如果使用的 Vue-cli 大於或等於 3.0 版本,那么就直接可以使用JSX的語法了。

如果您使用的是不支持 JSX 的Vue-cli較舊版本,則可以通過安裝babel-preset-vue-app來添加它,並將其添加到您的.babelrc文件中。

 # Using npm npm install --save-dev babel-preset-vue-app # Using yarn yarn add --dev babel-preset-vue-app 

在.babelrc文件中,添加:

{
 "presets": ["vue-app"] } 

我們現在可以在組件的render函數中使用 JSX。

 

在 Vue 中使用 JSX 需要注意的地方

在 Vue 中使用JSX需要注意幾點。

要監聽 JSX 中的事件,我們需要“on”前綴。 例如,將onClick用於單擊事件。

 render (createElement) {
     return ( <button onClick={this.handleClick}></button> ) } 

要修改事件,請使用

 render (createElement) {
     return ( <button onClick:prevent={this.handleClick}></button> ) } 

綁定變量,注意這里不是使用 :

 render (createElement) {
     return ( <button content={this.generatedText}></button> ) } 

將HTML字符串設置為元素的內容,使用domPropsInnerHTML而不是使用v-html

 render (createElement) {
     return ( <button domPropsInnerHTML={htmlContent}></button> ) } 

我們也可以展開一個大對象:

 render (createElement) {
     return ( <button {...this.largeProps}></button> ) }

 

在 render 中使用JSX

回到我們最初的“TextField”組件。現在我們已經在 Vue 應用程序中啟用了 JSX,我們現在可以這樣做了。

 render (createElement) {
     const inputAttributes = { class: 'input-field has-outline', // class definition onClick: this.handleClick // event handler backdrop: false // custom prop } const inputMarkup = this.multiline ? <textarea {...inputAttributes}></textarea> : <input {...inputAttributes}/> return inputMarkup }

 

導入 Vue JS 組件

在 Vue 中使用JSX的另一個好處是,我們不再需要注冊所需的每個組件。 我們只是導入和使用。

import {Button} from '../components' export default { render (createElement) { return <Button primary={true}>Edit</Button> } }

廣州設計公司https://www.houdianzi.com 我的007辦公資源網站https://www.wode007.com

如何使 JSX 與 TypeScript 一起使用

TypeScript 用作一種向 JavaScript添加類型檢查的機制。要在 JSX 支持 TypeScript中,需要修改 tsconfig.json。

要在 TypeScript 中啟用 JSX,請先將該文件另存為.tsx文件,然后將tsconfig.json修改為包括:

 {
   "compilerOptions": { .... "jsx": "preserve", } } 

將jsx選項設置為“preserve”意味着 TypeScript 不應處理JSX。 這樣做使 Babel 可以控制所有JSX 和 TypeScript 堅持使用類型,因為它尚不支持 Vue JSX。

然后在項目中創建一個jsx.d.ts文件,並為 Vue 添加 TypeScript JSX 聲明。

import Vue, {VNode} from 'vue' declare global { namespace JSX { interface Element extends VNode {} interface ElementClass extends Vue {} interface ElementAttributesProperty { $props: {} } interface IntrinsicElements { [elemName: string]: any } } } 

確保 TypeScript 可以加載聲明文件。 或者,可以通過以下方式在tsconfig.json中為其添加自動加載功能:

 {
   "compilerOptions": { ... "typesRoot": ["./node_modules/@types", "./types"] } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM