vue vue-jsx标签
Vue.js has an easy API and several options for defining HTML templates in our components.
Vue.js具有简单的API和几个选项,可用于在组件中定义HTML模板。
We can use the <template>
tag option, define a template
property on our root component instance, or use Single-File components.
我们可以使用<template>
标记选项,在我们的根组件实例上定义template
属性,或者使用Single-File组件 。
The options above are awesome and work perfectly, but, there comes a time in the lifecycle of your application where they either feel clunky, over-engineered or very inflexible.
上面的选项很棒,并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会感到笨拙,设计过度或非常不灵活。
So, why would we want to JSX instead of any of the other template definitions?
那么,为什么我们要使用JSX而不是其他任何模板定义?
<div>...</div>
is subjectively better than this.$createElement('div', {}, [...])
JSX易于阅读。 <div>...</div>
在主观上要优于this.$createElement('div', {}, [...])
Let me give you an example of why JSX is good.
让我举一个为什么JSX很好的例子。
We want to build a <TextField/>
component that can either be a normal single-line text input or a multiline input (textarea). Our template declaration might look like this.
我们想要构建一个<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>
As you can see from the snippet above, we'll quickly run into a few problems like duplicate code and many more. Imagine having to support a variety of properties on the input. This little snippet above will grow and be a nightmare to maintain.
从上面的代码片段中您可以看到,我们将很快遇到一些问题,例如重复代码等等。 想象一下必须在输入上支持各种属性。 上面的这个小片段将会增长,并且将成为噩梦。
To fix this, we need to go low-level with Vue. We need to get closer to Vue's internal API to fix this mess.
要解决此问题,我们需要对Vue进行低级处理。 我们需要更接近Vue的内部API来解决此问题。
NOTE: I'm not saying that the there's not a simple way or ways to handle the above problem without JSX, all I'm saying is that moving this logic to the
render()
method with JSX in tow can make for a more intuitive component. Keep reading to find out why?注意:我并不是说没有JSX来解决上述问题不是简单的方法,我只是说,将这个逻辑转移到JSX拖曳到
render()
方法上可以使操作更直观零件。 继续阅读以找出原因?
Every component we create in Vue has a render method. This is where Vue chooses to render the component. Even if we don't define this method, Vue will do it for us.
我们在Vue中创建的每个组件都有一个render方法。 这是Vue选择渲染组件的地方。 即使我们没有定义此方法,Vue也会为我们做到这一点。
This means that when we define HTML templates in Vue — Vue's template compiler compiles it to a createElement
function that takes a couple parameters and returns the result from the render
function.
这意味着当我们在Vue中定义HTML模板时,Vue的模板编译器将其编译为一个createElement
函数,该函数带有几个参数并从render
函数返回结果。
To fix the code in the previous section, we remove the template
property or the template tag and define a render()
method on the component. If the render
method is defined on a component, Vue will ignore the template definition.
为了修复上一节中的代码,我们删除了template
属性或template标签,并在组件上定义了render()
方法。 如果在组件上定义了render
方法,则Vue将忽略模板定义 。
...
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
}
})
}
}
...
The above code does a few things:
上面的代码做了几件事:
render
method takes a createElement
helper from Vue. render
方法使用Vue的createElement
帮助器。 createElement
. 然后,我们创建标签并将其属性,类等作为对象传递。 我们可以传递给createElement
选项很多。 Note: Every template we define for a Vue component will be converted into a render
method that returns a createElement
function. It's because of this reason the render
method will take precedence over a template definition.
注意: 我们为Vue组件定义的每个模板都将转换为可返回createElement
函数的render
方法。 因为这个原因, render
方法将优先于模板定义。
Take this example:
举个例子:
<div>
<p>Only you can stop forest fires</p>
</div>
The template compiler will convert the HTML above into:
模板编译器会将上面HTML转换为:
...
render (createElement) {
return createElement(
'div',
{},
createElement(
'p',
{},
'Only you can stop forest fires'
)
)
}
...
Okay! now you might ask this question, "Isn't this bad for readability?" The answer is yes. Once you define a component with many levels of elements nesting or has several sibling elements — we run into a new problem. We just sacrificed readability. Like they say, "we've moved from the frying pan to fire."
好的! 现在您可能会问这个问题:“对可读性来说这不好吗?” 答案是肯定的。 一旦定义了具有许多元素嵌套级别或具有多个同级元素的组件,我们就会遇到一个新问题。 我们只是牺牲了可读性。 就像他们说的那样:“我们已经从煎锅搬到了火上。”
Cue JSX. This is where we'll have JSX bring back the readability we lost.
提示JSX。 这是我们让JSX恢复丢失的可读性的地方。
If you already know about JSX, feel free to skip to the next section where I'll show you how to use JSX in Vue.
如果您已经了解JSX,请随时跳到下一节,我将向您展示如何在Vue中使用JSX。
JSX is a term coined by Facebook's engineering team.
JSX是Facebook工程团队创造的一个术语。
JSX is an XML-like syntax extension to JavaScript without any defined semantics.
JSX是JavaScript的类似XML的语法扩展,没有任何定义的语义。
JSX is NOT intended to be implemented by engines or browsers. Instead, we'll use transpilers like Babel to convert JSX to regular JavaScript.
JSX不能由引擎或浏览器实现。 相反,我们将使用像transpilers 巴贝尔以JSX转化为常规JavaScript。
// this line below is an example of JSX
const heading = <h1>Welcome to Scotch</h1>;
Basically, JSX lets us use an HTML-like syntax in JavaScript.
基本上,JSX允许我们在JavaScript中使用类似HTML的语法。
Unfortunately, this article assumes you already know JSX, so teaching JSX is beyond the scope of this article. I'll still point you in the right direction. JSX is very easy to grok and can be done in a couple minutes.
不幸的是,本文假设您已经了解JSX,因此教授JSX不在本文讨论范围之内。 我仍然会指出正确的方向。 JSX非常容易掌握,可以在几分钟内完成。
Use these links to learn The basics of JSX, Learn JSX in-depth, finally, if you really want to know about the specification that is JSX, visit its official website.
使用这些链接来学习JSX的基础知识 ,最后, 深入学习JSX ,如果您真的想了解JSX的规范,请访问其官方网站 。
If you use Vue-cli greater or equal to version 3.0 you are in luck as JSX is supported.
如果您使用大于或等于3.0版的Vue-cli ,那么您会很幸运,因为它支持JSX。
If you are using an older version of Vue-cli that doesn't support JSX, you can add it by installing babel-preset-vue-app
and add it to your .babelrc
file.
如果您使用的Vue-cli较旧版本不支持JSX,则可以通过安装babel-preset-vue-app
添加它,并将其添加到您的.babelrc
文件中。
To install:
安装:
# Using npm
npm install --save-dev babel-preset-vue-app
# Using yarn
yarn add --dev babel-preset-vue-app
In you .babelrc
file, all you have to do is:
在您的.babelrc
文件中,您要做的就是:
{
"presets": ["vue-app"]
}
There, we can now use JSX in our component's render
function.
在那里,我们现在可以在组件的render
函数中使用JSX。
There are few gotchas to using JSX in Vue.
在Vue中使用JSX的陷阱很少。
First, you can no longer use the :
and @
shortcuts for binding and listening to events. They are invalid JSX syntax and your code won't compile.
首先,您不再可以使用:
和@
快捷方式来绑定和监听事件。 它们是无效的JSX语法,因此您的代码无法编译。
To listen for events in JSX, we need the "on" prefix. For example, use onClick
for click events.
要监听JSX中的事件,我们需要“ on ”前缀。 例如,将onClick
用于单击事件。
render (createElement) {
return (
<button onClick={this.handleClick}></button>
)
}
To modify events, use:
要修改事件,请使用:
render (createElement) {
return (
<button onClick:prevent={this.handleClick}></button>
)
}
To bind a variable, instead of :
use:
要绑定一个变量,而不是:
使用:
render (createElement) {
return (
<button content={this.generatedText}></button>
)
}
To set HTML string as the content of an element, instead of v-html
use:
要将HTML字符串设置为元素的内容而不是v-html
使用:
render (createElement) {
return (
<button domPropsInnerHTML={htmlContent}></button>
)
}
We can also spread a large object.
我们还可以散布一个大物体。
render (createElement) {
return (
<button {...this.largeProps}></button>
)
}
Going back to our initial "TextField" component. Now that we have JSX enabled in our Vue app, we can now do this.
回到我们最初的“ 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
}
Another benefit to using JSX in Vue is that we no longer have to register every component we need. We just import and use.
在Vue中使用JSX的另一个好处是,我们不再需要注册所需的每个组件。 我们只是导入和使用。
import {Button} from '../components'
export default {
render (createElement) {
return <Button primary={true}>Edit</Button>
}
}
TypeScript is used as a mechanism that adds type-checking to JavaScript. You can read more.
TypeScript用作一种向JavaScript添加类型检查的机制。 您可以阅读更多内容 。
To add JSX support to TypeScript all we need to do is modify our tsconfig.json
.
要将JSX支持添加到TypeScript,我们要做的就是修改tsconfig.json
。
To enable JSX in TypeScript, first save the file as a .tsx
file and modify your tsconfig.json
to include:
要在TypeScript中启用JSX,请先将该文件另存为.tsx
文件,然后将tsconfig.json
修改为包括:
{
"compilerOptions": {
....
"jsx": "preserve",
}
}
Setting the jsx
option to "preserve" means that TypeScript should not process the JSX. Doing this lets Babel take control of everything JSX and TypeScript stick to types as it does not yet support Vue JSX. You can learn more.
将jsx
选项设置为“ preserve”意味着TypeScript不应处理JSX。 这样做使Babel可以控制所有JSX和TypeScript坚持使用类型,因为它尚不支持Vue JSX。 您可以了解更多 。
Then create a jsx.d.ts
file in your project and add the TypeScript JSX declarations for Vue.
然后在您的项目中创建一个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
}
}
}
Make sure that TypeScript can load the declaration file. Or, you can add autoloading for it in tsconfig.json
via:
确保TypeScript可以加载声明文件。 或者,您可以通过以下方式在tsconfig.json
中tsconfig.json
添加自动加载功能:
{
"compilerOptions": {
...
"typesRoot": ["./node_modules/@types", "./types"]
}
}
That's it for today. Enjoy having some or all of your Vue.js templates in JSX.
今天就这样。 享受在JSX中拥有部分或全部Vue.js模板。
And, please no complaints about JSX breaking SOC (separation of concerns), I can't take another one of those arguments. If you prefer using the createElement
function with objects by all means enjoy!!
而且,请不要抱怨JSX破坏了SOC(关注点分离),我不能接受其中一个论点。 如果您更喜欢将createElement
函数与对象一起使用,那就createElement
了!!
Let me know your thoughts and suggestions in the comments.
在评论中让我知道您的想法和建议。
Cheers!
干杯!
翻译自: https://scotch.io/tutorials/using-jsx-with-vue-and-why-you-should-care
vue vue-jsx标签