阅读 52

Vue中使用JSX

Vue的Template是如此的强大,大量的语法糖让我们爱不释手。通常,在Vue中使用Template已经足够。而Template其本质是render函数,JSX的本质也是render函数,这三者之间有哪些异同以及各自的优缺点是什么呢?让我们一探究竟吧!

先决条件

  • Node.js 10.0+ 和 Yarn/npm 5.0+
  • 基本的JavaScript、React、Vue知识
  • Vue-cli 3.0+
# 安装全局@vue/cli
# vue-cli 3.0+版本默认对JSX支持,不需要任何其他配置(https://cli.vuejs.org/zh/config/#babel)
yarn global add @vue/cli
复制代码

render 函数简介

render函数本质上只是一个普通的函数,其返回的是虚拟DOM。我们平时常用的Template,会在Vue的build过程中被编译成render函数。然后Vue再根据虚拟DOM生成最终的真实的浏览器DOM。

render函数怎么运作

一个典型的render函数长这样

render (createElement){
 return createElement( 'div', {}, [....]
)}
复制代码

createElement方法有三个参数:

  • 标签,可以是原生的HTML标签,也可以是组件
  • 配置对象,包含attributes、props、DOM props、styles、classes还有事件的配置
  • 子元素,也可以是数组或者普通文本

createElement通常简写成h,这是尤雨溪的习惯,代表着Hyperscript,超文本的意思,后来就被大家沿用了(毕竟大佬)

上面的代码可以写成这样:

render (h){
 return h( 'div', {}, [....]
)}
复制代码

render函数
来张图加深下render函数的概念

虚拟DOM

尤雨溪:

The Virtual DOM is a lightweight representation of what the actual DOM should look like at a given point in time

Vue使用虚拟DOM来跟踪和更新真实DOM,为了提升性能,新旧虚拟DOM会进行diff,进而只应用改变的那部分,这个过程被称为diffing

更多关于Vue的render函数和虚拟DOM的知识,请移步官网

JSX

JSX是一种和XML相似的语法来写JavaScript。它是render函数的语法抽象,这让render函数更简单与易读。JSX源自Facebook的React,其目的也是为了写出更简洁优雅的React代码

JSX,和Vue的Template很像,在构建时也会被编译成render函数

JSX能为Vue带来什么?

  • 允许使用熟悉的语法来定义HTML元素树
  • 提供更加语义化且移动的标签
  • 程序结构更容易被直观化
  • 可以随时掌控 HTML 标签以及生成这些标签的代码
  • JSX具备更多的原生JS能力
  • 不需要额外配置,官方原生支持

常见的Template特性在JSX中的实现

v-if

Template
<template>
   <div v-if="user.age > 18">
      Welcome, {{user.name}}
    </div>
</template>
复制代码
JSX
export default {
....
  methods: {
      checkStatement(){
        if (this.user.age > 18) {
           return <div> Welcome, { this.user.name }</div>;
        }
      }
    },
    render(){
      return(
        {this.checkStatement()}
      )
    }
}
复制代码

v-for

Template
 <template>
  <div v-for="item in items" :key="item.id">
      {{ item }}
  </div
</template>
复制代码
JSX
render(){
  return(
    {this.items.map(item => {
        return (
           <div> {item} </div>
          )
      }
  )}
复制代码

v-on

Template
<template>
    <div>
      <button v-on:click="handleButtonClick()"> click me</button>
    </div>
</template>
<script>
export default {
  methods: {
      handleButtonClick(e){
          e.preventDefault();
          alert('button clicked')
        }   
    }
</script>
复制代码
JSX
export default {
  methods: {
      handleButtonClick(e){
          e.preventDefault();
          alert('button clicked')
        }   
    },
  render(){
    return(
    <div>
       <button onClick={this.handleButtonClick}> click me</button>
    </div>
    )
  }
}
复制代码

v-html

Template
<template>
  <div>
     <div v-html="rawHtml"> </div>
  </div>
</template>
<script>
export default {
    data () {
      return {
        rawHtml: "<h1> This is some HTML </h1>",
      }
    }
}
</script>
复制代码
JSX
export default {
    data () {
      return {
        rawHtml: "<h1> This is some HTML </h1>",
      }
    },
    render(){
        return(
          <div>
            <div domPropsInnerHTML={this.rawHtml}> </div>
          </div>
        )
    }
}
复制代码

引入组件

Template
<template>
  <div>
    <NewComponent/>
  </div>
</template>
<script>
import NewComponent from "NewComponent.vue";
export default {
    components:{
        NewComponent,
    },
}
</script>
复制代码
JSX
import NewComponent from 'NewComponent.vue'
....
  render(){
    return(
     <div> <NewComponent/></div>
    )
  }
复制代码

总结

日常开发中用到最多的是Template,偶尔会用到render函数,而当我们用到render函数时,厌倦了render函数那冗长的三个参数,这时不妨试试JSX,还在等什么呢,官方都原生支持了!

原文地址