在 Vue 中使用 JSX 及使用它的原因浅析

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

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>
  }
 }

如何使 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"]
 }
 }

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

总结

以上所述是小编给大家介绍的在 Vue 中使用 JSX 及使用它的原因浅析,希望对大家有所帮助!

(0)

相关推荐

  • 在vue中使用jsx语法的使用方法

    什么是JSX? JSX就是Javascript和XML结合的一种格式.React发明了JSX,利用HTML语法来创建虚拟DOM.当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析. 我为什么要在vue中用JSX? 想折腾一下呗,开玩笑.最开始是因为近期在学习react,在里面体验了一把jsx语法,发现也并没有别人说的很难受的感觉啊,于是就想尝试在vue中也试下,废话不多说,先来用代码来看下两者的区别吧. ps:vue中大部分场景是不需要用render函数的,还是用模板更简洁直观

  • 详解利用jsx写vue组件的方法示例

    前言 本文主要给大家介绍的是关于利用jsx写vue组件,下面话不多说,来一起看看详细的介绍吧. 我们平常写vue的组件时,一般都是用的是模版,这种方式看起来比较简洁,而且vue作者也推荐使用这个方式,但是这种方式也有一些它的弊端,例如模版调试麻烦,或者在一些场景下模版描述可能没那么简单和方便. 下面我们要讲的是如何在vue里面写jsx,知道react的人应该都知道jsx,jsx的一个特性就是非常灵活,虽然有的人觉得jsx很丑陋,把逻辑都写到模版的感觉,但萝卜青菜各有所爱,适合自己适合团队的就是最

  • vue jsx 使用指南及vue.js 使用jsx语法的方法

    vue  jsx  语法与 react  jsx  还是有些不一样,在这里记录下. let component = null// if 语句 if (true) { component = ( <div></div> ); } else { component = ( <div></div> ); } var ul = ( <ul> {component} </ul> ); // map 语句 var coms = limit.map

  • 详解Vue如何支持JSX语法

    通常开发vue我们使用的是模板语法,其实还有和react相同的语法,那就是render函数,同样支持jsx语法. Vue 的模板实际是编译成了 render 函数. 1.传统的createElement方法 createElement( 'anchored-heading', { props: { level: 1 } }, [ createElement('span', 'Hello'), ' world!' ] ) 渲染成下面这样 <anchored-heading :level="1

  • 详解如何使用webpack在vue项目中写jsx语法

    本文介绍了如何使用webpack在vue项目中写jsx语法,分享给大家,具体如下: 我们知道Vue 2.0中对虚拟DOM的支持.我们可以通过JavaScript动态的创建元素,而不用在template中写HTML代码.虚拟DOM最终将被渲染为真正的DOM. data: { msg: 'Hello world' }, render (h) { return h( 'div', { attrs: { id: 'my-id' }, [ this.msg ] ); } 渲染后的内容为: <div id=

  • Vue中jsx不完全应用指南小结

    前言:文章不介绍任务背景知识,没有原理说明,偏向于实践的总结和经验分享. 文章所有的代码是基于Vue CLI 3.x版本,不会涉及到一步步通过Webpack来配置JSX所需要的知识点. 在使用Vue开发项目时绝大多数情况下都是使用模板来写HTML,但是有些时候页面复杂又存在各种条件判断来显示/隐藏和拼凑页面内容,或者页面中很多部分存在部分DOM结构一样的时候就略显捉襟见肘,会写大量重复的代码,会出现单个.vue文件过长的情况,这个时候我们就需要更多的代码控制,这时候可以使用渲染函数. 渲染函数想

  • vue组件jsx语法的具体使用

    如果使用render函数来写比较复杂的vue组件,对于可读性和可维护性都很不友好,而使用jsx就会让我们回到更接近于模板的语法.babel转译器会将jsx转译为render函数渲染. 配置 需要用到babel插件 安装 npm install\ babel-plugin-syntax-jsx\ babel-plugin-transform-vue-jsx\ babel-helper-vue-jsx-merge-props\ babel-preset-env\ --save-dev .babelr

  • 在 Vue 中使用 JSX 及使用它的原因浅析

    本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料.欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西. Vue.js 具有简单的 API 和几个选项,可用于在我们的组件中定义HTML模板. 我们可以使用 <template> 标签选项,在根组件实例上定义 template 属性,或者使用单文件组件. 上面的选项很棒并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会

  • 如何在 Vue 中使用 JSX

    JSX 是什么 JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javascript 的灵活性,同时又兼具 html 的语义化和直观性 为什么要在 Vue 中使用 JSX 有时候,我们使用渲染函数(render function)来抽象组件,渲染函数不是很清楚的参见官方文档, 而渲染函数有时候写起来是非常痛苦的 createElement( 'anchored-h

  • 如何在vue中使用jsx语法

    目录 为什么需要在vue中使用jsx 在vue中如何使用jsx template转jsx的语法转换 为什么需要在vue中使用jsx 几年前面试的时候,被问过这个问题,当时我一脸懵,这两个东西为啥要混用呢? 直到后来,我遇到了这种场景. tab切换展示组件,大部分组件展示表格,除了2个tab需要展示不同,这个不同,怎么处理呢? 当然可以直接改封装的tab组件,v-if条件渲染嘛 那如果后面再有其他需求,tab组件继续写if么 这个时候,组件就过于冗余啦 那怎么让组件统一处理呢?当然可以用rende

  • 在vue中写jsx的几种方式

    目录 版本 render函数 jsx/tsx 使用jsx的几种方式 使用js对象注册component 使用.vue文件 vue2.7在.vue文件中结合compositionApi和jsx 版本 本文版本配置 vue: 2.7.2 vue-cli: ~4.5.18: 本文代码github仓库地址 render函数 render函数和vue中的template是互斥的,template最终是要编译成virtual Dom的,而render函数可以更直接构建virtual Dom: virtual

  • Vue中动态引入图片要是require的原因解析

    目录 1.什么是静态资源 2. 为什么动态添加的src会被当做的静态的资源? 3. 没有进行编译,是指的是什么没有被编译? 4. 加上require为什么能正确的引入资源,是因为加上require就能编译了? 4.1 require是什么: 是一个node方法,用于引入模块,JSON或本地文件 4.2 调用require方法引入一张图片之后发生了什么: 5. 问题3中,静态的引入一张图片,没有使用require,为什么返回的依然是编译过后的文件地址? 6. 按照问题6中所说,那么动态添加src的

  • vue中正确使用jsx语法的姿势分享

    目录 前言 虚拟DOM 什么是虚拟DOM 虚拟DOM的优点 渲染函数是什么 jsx 在vue3中编写jsx的两种方式 用法 最后 参考 前言 又到了愉快的摸鱼时间,我觉得不能荒废,H5页面我一直用的vant,出于对源码的好奇,我从git上拉了一份vant源码,里面竟然都是jsx写的组件,于是我开始了对在vue中使用jsx的探索 虚拟DOM 什么是虚拟DOM 在这之前,先了解下虚拟DOM,vue和react框架都在内部使用了虚拟DOM,这样做的原因是通过js操作DOM的计算成本很高,虽然js更新速

随机推荐