Open husky-dot opened 4 years ago
作者:JT 译者:前端小智 来源:https://scotch.io/ 点赞再看,养成习惯 本文 GitHub https://github.com/qq449245884/xiaozhi 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
作者:JT 译者:前端小智 来源:https://scotch.io/
点赞再看,养成习惯
本文 GitHub https://github.com/qq449245884/xiaozhi 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
GitHub
Vue.js 具有简单的 API 和几个选项,可用于在我们的组件中定义HTML模板。
我们可以使用<template>标签选项,在根组件实例上定义template属性,或者使用单文件组件。
<template>
template
上面的选项很棒并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会感到笨拙,设计过度或非常不灵活。
那么,我们为什么要使用 JSX 而不是其他模板定义呢?
<div></div>
this.$createElement('div', {}, [...])
先举一个例子来说明为什么 JSX 是好的。
我们要构建一个<TextField/>组件,该组件可以是普通的单行文本输入或多行输入(文本区域)。 我们的模板声明可能看起来像这样。
<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上面所列的各种属性。上面的这个小片段将会增长并成为一个难以维护的噩梦。
input
要解决这个问题,我们需要使用Vue进行降级处理,因此需要使用理接近Vue的内部API来解决这个问题。
注意:这里并不是说没有JSX就没有一种简单的方法来处理上面的问题,只是说将这个逻辑移动到带有JSX的render()方法可以使组件更直观。
render()
我们在 Vue 中创建的每个组件都有一个render方法。这个就是 Vue 选择渲染组件的地方。即使我们不定义这个方法,Vue 也会为我们做这件事。
render
这意味着当我们在 Vue 中定义 HTML 模板时,Vue 的模板编译器将其编译为一个createElement函数,该函数带有几个参数并从render函数返回结果。
createElement
为了修复上一节中的代码,我们删除了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 } }) } } ...
上面的代码做了几件事:
我们为 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 是 Facebook 工程团队创造的一个术语。
JSX 是 JavaScript 的类似XML的语法扩展,没有任何定义的语义。
JSX 不打算由引擎或浏览器实现。相反,我们将使用 Babel 之类的转置器将JSX转换成常规的 JS 。
// 此行是JSX的示例 const heading = <h1>Welcome to Scotch</h1>;
基本上,JSX 允许我们在 JS 中使用类似 Html 的语法。
如果使用的 Vue-cli 大于或等于 3.0 版本,那么就直接可以使用JSX的语法了。
如果您使用的是不支持 JSX 的Vue-cli较旧版本,则可以通过安装babel-preset-vue-app来添加它,并将其添加到您的.babelrc文件中。
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需要注意几点。
要监听 JSX 中的事件,我们需要“on”前缀。 例如,将onClick用于单击事件。
“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
domPropsInnerHTML
v-html
render (createElement) { return ( <button domPropsInnerHTML={htmlContent}></button> ) }
我们也可以展开一个大对象:
render (createElement) { return ( <button {...this.largeProps}></button> ) }
回到我们最初的“TextField”组件。现在我们已经在 Vue 应用程序中启用了 JSX,我们现在可以这样做了。
“TextField”
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 中使用JSX的另一个好处是,我们不再需要注册所需的每个组件。 我们只是导入和使用。
import {Button} from '../components' export default { render (createElement) { return <Button primary={true}>Edit</Button> } }
TypeScript 用作一种向 JavaScript添加类型检查的机制。要在 JSX 支持 TypeScript中,需要修改 tsconfig.json。
tsconfig.json
要在 TypeScript 中启用 JSX,请先将该文件另存为.tsx文件,然后将tsconfig.json修改为包括:
.tsx
{ "compilerOptions": { .... "jsx": "preserve", } }
将jsx选项设置为“preserve”意味着 TypeScript 不应处理JSX。 这样做使 Babel 可以控制所有JSX 和 TypeScript 坚持使用类型,因为它尚不支持 Vue JSX。
jsx
“preserve”
然后在项目中创建一个jsx.d.ts文件,并为 Vue 添加 TypeScript JSX 声明。
jsx.d.ts
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。
原文:https://scotch.io/tutorials/using-jsx-with-vue-and-why-you-should-care
文章每周持续更新,可以微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,另外关注公众号,后台回复福利,即可看到福利,你懂的。
Vue.js 具有简单的 API 和几个选项,可用于在我们的组件中定义HTML模板。
我们可以使用
<template>
标签选项,在根组件实例上定义template
属性,或者使用单文件组件。上面的选项很棒并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会感到笨拙,设计过度或非常不灵活。
那么,我们为什么要使用 JSX 而不是其他模板定义呢?
<div></div>
的写法一看就是比this.$createElement('div', {}, [...])
简洁很多。简介
先举一个例子来说明为什么 JSX 是好的。
我们要构建一个
<TextField/>
组件,该组件可以是普通的单行文本输入或多行输入(文本区域)。 我们的模板声明可能看起来像这样。从上面的代码片段中可以看到,我们很快就会遇到一些问题,比如重复代码等等。想象一下,必须支持
input
上面所列的各种属性。上面的这个小片段将会增长并成为一个难以维护的噩梦。要解决这个问题,我们需要使用Vue进行降级处理,因此需要使用理接近Vue的内部API来解决这个问题。
render() 方法
我们在 Vue 中创建的每个组件都有一个
render
方法。这个就是 Vue 选择渲染组件的地方。即使我们不定义这个方法,Vue 也会为我们做这件事。这意味着当我们在 Vue 中定义 HTML 模板时,Vue 的模板编译器将其编译为一个
createElement
函数,该函数带有几个参数并从render
函数返回结果。为了修复上一节中的代码,我们删除了
template
属性或template
标签,并在组件上定义了render()
方法。 如果在组件上定义了render
方法,则 Vue 将忽略template
定义。上面的代码做了几件事:
render
方法从Vue获取一个createElement
助手。createElement
的选项很多。我们为 Vue 组件定义的每个模板都将转换为可返回
createElement
函数的render
方法。 因为这个原因,render
方法将优先于模板定义。举个例子:
模板编译器将把上面的 HTML 转换成:
现在你可能会问这个问题:“对可读性来说这不好吗?” 答案是肯定的。 一旦定义了具有许多元素嵌套级别或具有多个同级元素的组件,我们就会遇到这个新问题。
这就是 JSX 出现的原因,它可以很好的解决此类问题。
JSX 是什么
JSX 是 Facebook 工程团队创造的一个术语。
JSX 不打算由引擎或浏览器实现。相反,我们将使用 Babel 之类的转置器将JSX转换成常规的 JS 。
基本上,JSX 允许我们在 JS 中使用类似 Html 的语法。
配置 Vue 以使用 JSX
如果使用的 Vue-cli 大于或等于 3.0 版本,那么就直接可以使用JSX的语法了。
如果您使用的是不支持 JSX 的Vue-cli较旧版本,则可以通过安装
babel-preset-vue-app
来添加它,并将其添加到您的.babelrc
文件中。在
.babelrc
文件中,添加:我们现在可以在组件的
render
函数中使用 JSX。在 Vue 中使用 JSX 需要注意的地方
在 Vue 中使用JSX需要注意几点。
要监听 JSX 中的事件,我们需要
“on”
前缀。 例如,将onClick
用于单击事件。要修改事件,请使用
绑定变量,注意这里不是使用
:
将HTML字符串设置为元素的内容,使用
domPropsInnerHTML
而不是使用v-html
我们也可以展开一个大对象:
在 render 中使用JSX
回到我们最初的
“TextField”
组件。现在我们已经在 Vue 应用程序中启用了 JSX,我们现在可以这样做了。导入 Vue JS 组件
在 Vue 中使用JSX的另一个好处是,我们不再需要注册所需的每个组件。 我们只是导入和使用。
如何使 JSX 与 TypeScript 一起使用
TypeScript 用作一种向 JavaScript添加类型检查的机制。要在 JSX 支持 TypeScript中,需要修改
tsconfig.json
。要在 TypeScript 中启用 JSX,请先将该文件另存为
.tsx
文件,然后将tsconfig.json
修改为包括:将
jsx
选项设置为“preserve”
意味着 TypeScript 不应处理JSX。 这样做使 Babel 可以控制所有JSX 和 TypeScript 坚持使用类型,因为它尚不支持 Vue JSX。然后在项目中创建一个
jsx.d.ts
文件,并为 Vue 添加 TypeScript JSX 声明。确保 TypeScript 可以加载声明文件。 或者,可以通过以下方式在
tsconfig.json
中为其添加自动加载功能:代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://scotch.io/tutorials/using-jsx-with-vue-and-why-you-should-care
交流
文章每周持续更新,可以微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,另外关注公众号,后台回复福利,即可看到福利,你懂的。