[翻译] vue3指南-04 Template Syntax template语法

1,663 阅读9分钟

Vue.js uses an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying application instance's data. All Vue.js templates are valid HTML that can be parsed by spec-compliant browsers and HTML parsers.

Vue.js使用的template语法是一种基于HTML式的——能够声明式地把视图层的Dom元素和底层应用实例data相绑定. 所有Vue的template都是有效的HTML——怎么说呢——template是可以通过符合规范的浏览器和HTML解析器解析的.

Under the hood, Vue compiles the templates into Virtual DOM render functions. Combined with the reactivity system, Vue is able to intelligently figure out the minimal number of components to re-render and apply the minimal amount of DOM manipulations when the app state changes.

在底层,Vue把templates编译成虚拟Dom渲染函数(Virtual Dom render functions). 结合reactivity系统, 在app状态(视图状态/数据状)有变化时, Vue就可以很聪明地挑出那些必须重新渲染的组件(最少数量),然后把这些操作放到最少的Dom身上.

If you are familiar with Virtual DOM concepts and prefer the raw power of JavaScript, you can also directly write render functions instead of templates, with optional JSX support.

如果你清楚虚拟Dom的概念同时有比较倾向于JavaScript的原生能力,你还可以直接写render function,并且可选择支持JSX方式.

Interpolations 插入

Text 文本

The most basic form of data binding is text interpolation using the "Mustache" syntax (double curly braces):

最基础的数据绑定形式即使用“胡子🧔”语法(双大括号)进行文本插入:

<span>Message: {{ msg }}</span>

The mustache tag will be replaced with the value of the msg property on the corresponding data object. It will also be updated whenever the data object's msg property changes.

胡子标签会被data对象内的msg属性(property)值替换掉. 同时当msg属性改变是这标签内容也会同步更新.

You can also perform one-time interpolations that do not update on data change by using the v-once directive, but keep in mind this will also affect any other bindings on the same node:

你也可以使用一次性的插入,即data变化时不再更新——用v-once指令. 但是注意⚠️,这指令会影响在这个结点上的所有绑定:

<span v-once>This will never change: {{ msg }}</span>

Raw HTML 纯HTML

The double mustaches interprets the data as plain text, not HTML. In order to output real HTML, you will need to use the v-html directive:

双花括号将data翻译成纯文本(plain text)而不是HTML. 如果想要输出真正的HTML,可以使用v-html指令:

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
const RenderHtmlApp = {
  data() {
    return {
      rawHtml: '<span style="color: red">This should be red.</span>'
    }
  }
}

Vue.createApp(RenderHtmlApp).mount('#example1')

The contents of the span will be replaced with the value of the rawHtml property, interpreted as plain HTML - data bindings are ignored. Note that you cannot use v-html to compose template partials, because Vue is not a string-based templating engine. Instead, components are preferred as the fundamental unit for UI reuse and composition.

span里面的内容会替换成rawHTML属性值,Vue将它翻译成HTML并且忽略数据绑定.**记住:你不能用v-html指令去构造组成template, 因为Vue不是一个基于字符串的templating engine(模版引擎). 相反地, 更提倡用组件(components)**来作为UI组成和复用的基本单位.

TIP 提示

Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS vulnerabilities. Only use HTML interpolation on trusted content and never on user-provided content 在你的网站上动态渲染任意HTML的行为很危险,因为这很容易造成XSS漏洞. 所以不要在用户提供内容上使用HTML插入,只在可信任内容上使用.

Attributes 属性

Mustaches cannot be used inside HTML attributes. Instead, use a v-bind directive

花括号也不能用在HTML元素标签内部属性. 用v-bind指令吧:

<div v-bind:id="dynamicId"></div>

In the case of boolean attributes, where their mere existence implies true, v-bind works a little differently. In this example:

属性是bool属性值时候(像disabled之类的)——有这个属性存在就代表值为true.这时候,v-bind工作方式有点儿不同:

<button v-bind:disabled="isButtonDisabled">Button</button>

If isButtonDisabled has the value of null or undefined, the disabled attribute will not even be included in the rendered <button> element.

如果,isButtonDisabled值为null/undefined,那这个disabled属性(attribute)就不会存在在<button>标签里.(很合理啊it's intuitively reasonable).

Using JavaScript Expressions 使用JS表达式

So far we've only been binding to simple property keys in our templates. But Vue.js actually supports the full power of JavaScript expressions inside all data bindings:

目前为止,我们只在templates上绑定了简单属性的键值(keys). 其实,在所有data绑定里,Vue是充分支持JS表达式能力的:

{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('')
}}

<div v-bind:id="'list-' + id"></div>

These expressions will be evaluated as JavaScript in the data scope of the current active instance. One restriction is that each binding can only contain one single expression, so the following will NOT work:

这些表达式,在data所在当前实例里面,会被当作JS来进行运算.有一个限制🚫:每个绑定只能包含一个表达式,所以,下面这个是 不生效的:

<!-- 这不是一个表达式,而是一个statement-->
{{ var a = 1 }}

<!-- flow control won't work either, use ternary expressions -->
<!-- 控制语句也不行,去用3元表达式 -->
{{ if (ok) { return message } }}

Directives 指令们

Directives are special attributes with the v- prefix. Directive attribute values are expected to be a single JavaScript expression (with the exception of v-for and v-on, which will be discussed later). A directive's job is to reactively apply side effects to the DOM when the value of its expression changes. Let's review the example we saw in the introduction:

指令,是一种以v-作为前缀的元素属性(attribute). 他们(指令)的值应该是一条JS表达式.(v-forv-on除外,这俩后面讨论.) 指令的作用 是当表达式的值发生变化时,他们响应式作出反映(这些反映是side effects——不是纯函数). 让我们回顾一下之前介绍里的例子:

<p v-if="seen">Now you see me</p>

Here, the v-if directive would remove/insert the <p> element based on the truthiness of the value of the expression seen.

这里,v-if指令会 根据seen表达式的值为true/false来选择移除/插入 <p>元素.

Arguments

Some directives can take an "argument", denoted by a colon after the directive name. For example, the v-bind directive is used to reactively update an HTML attribute:

有些指令接受一个"入参(argument)",指令后紧跟一个冒号然后输入参数. 比如, 下面的v-bind指令用来响应式地更新一个html元素属性(attribute):

<a v-bind:href="url"> ... </a>

Here href is the argument, which tells the v-bind directive to bind the element's href attribute to the value of the expression url.

这里href就是一个参数,他告诉v-bind指令去把元素的href属性和表达式url的值绑定起来.

Another example is the v-on directive, which listens to DOM events:

另一个例子是,v-on指令,用来监听DOM事件:

<a v-on:click="doSomething"> ... </a>

Here the argument is the event name to listen to. We will talk about event handling in more detail too.

这里的参数是要监听的事件名.我们后面会更详细的讲事件处理.

Dynamic Arguments

It is also possible to use a JavaScript expression in a directive argument by wrapping it with square brackets:

也可以在一个指令参数里直接使用JS表达式——用方括号扩起来:

<!--
Note that there are some constraints to the argument expression, as explained
in the "Dynamic Argument Expression Constraints" section below.
-->

<!--
注意一下,这里关于参数表达式有些限制🚫,想上面讲的那个限制.去找一下上面的那个符号🚫
-->
<a v-bind:[attributeName]="url"> ... </a>

Here attributeName will be dynamically evaluated as a JavaScript expression, and its evaluated value will be used as the final value for the argument. For example, if your application instance has a data property, attributeName, whose value is "href", then this binding will be equivalent to v-bind:href.

这里attributeName会被当作一条JS表达式来被动态运算.它的结果值被当作最终的参数使用.比如: 如果实例里面有一个data的属性(property)叫attributeName.值是"href",那么上面的绑定就相当于是v-bind:href. (

    const Test = {
        data(){
            return {
                ...
                attributeName:"href",
                ...
            }  
        }
    }

)

Similarly, you can use dynamic arguments to bind a handler to a dynamic event name:

类似的,也可以用这种动态参数的方式去给一个事件handler绑定一个动态的事件名:

<a v-on:[eventName]="doSomething"> ... </a>

In this example, when eventName's value is "focus", v-on:[eventName] will be equivalent to v-on:focus.

这里,当eventName值为"focus"的时候,v-on:[eventName] 就相当于 v-on:focus.

Modifiers

Modifiers are special postfixes denoted by a dot, which indicate that a directive should be bound in some special way. For example, the .prevent modifier tells the v-on directive to call event.preventDefault() on the triggered event:

修饰符是一类特殊的后缀——用点(.)表示.他表示这个指令是以一种特殊的方式绑定的. 比如,.prevent修饰符告诉v-on指令,当事件触发的时候,调用event.preventDefault()方法:

<form v-on:submit.prevent="onSubmit">...</form>

You'll see other examples of modifiers later, for v-on and for v-model, when we explore those features.

当我们去玩类似v-onv-model这些特性的时候,会见到其他修饰符和相关例子.

Shorthands 速写

The v- prefix serves as a visual cue for identifying Vue-specific attributes in your templates. This is useful when you are using Vue.js to apply dynamic behavior to some existing markup, but can feel verbose for some frequently used directives. At the same time, the need for the v- prefix becomes less important when you are building a SPA, where Vue manages every template. Therefore, Vue provides special shorthands for two of the most often used directives, v-bind and v-on:

v-前缀作为vue的template里面特别的可见提示.当对已经存在的应用动态行为是很有用的,但是对一些经常操作的指令,这样就很烦. 同时,当构建一个单页应用的时候,这v-前缀就没那么重要了. 因此Vue提供了一个速记法对两个常用指令,v-bindv-on:

v-bind Shorthand

<!-- full syntax -->
<a v-bind:href="url"> ... </a>

<!-- shorthand -->
<a :href="url"> ... </a>

<!-- shorthand with dynamic argument -->
<a :[key]="url"> ... </a>

v-on Shorthand

<!-- full syntax -->
<a v-on:click="doSomething"> ... </a>

<!-- shorthand -->
<a @click="doSomething"> ... </a>

<!-- shorthand with dynamic argument (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

They may look a bit different from normal HTML, but : and @ are valid characters for attribute names and all Vue-supported browsers can parse it correctly. In addition, they do not appear in the final rendered markup. The shorthand syntax is totally optional, but you will likely appreciate it when you learn more about its usage later.

看起来可能和正常HTML有点区别,但:@都是属性(attribute)名的有效字符,所有Vue支持的浏览器都可以正常解析的. 另外他们不会出现最终渲染的标签内. 这种速记法完全是选用的,再学一点儿,你会感激有这东西.

From the next page on, we'll use the shorthand in our examples, as that's the most common usage for Vue developers.

从下一篇开始,我们就会在🌰例子里开始用这些速记法了.

Caveats 警告⚠️

Dynamic Argument Value Constraints 一些动态参数值限制🚫

Dynamic arguments are expected to evaluate to a string, with the exception of null. The special value null can be used to explicitly remove the binding. Any other non-string value will trigger a warning.

动态参数希望计算结果是一个string(字符串)——null除外. 特殊值null可以当作显示地移除绑定. 其他任何非字符串值都会触发warning告警.

Dynamic Argument Expression Constraints 一些动态参数表达式限制🚫

Dynamic argument expressions have some syntax constraints because certain characters, such as spaces and quotes, are invalid inside HTML attribute names. For example, the following is invalid:

动态参数表达式有些语法限制,原因是一些特殊字符——像空格引号这些在HTML属性(attribute)名都是非法的.比如像下面这样都是无效的:

<!-- This will trigger a compiler warning. -->
<a v-bind:['foo' + bar]="value"> ... </a>

We recommend replacing any complex expressions with a computed property, one of the most fundamental pieces of Vue, which we'll cover shortly.

建议把所有复杂表达式都替换成computed 属性.这个是Vue最基础内容,马上会讲到.

When using in-DOM templates (templates directly written in an HTML file), you should also avoid naming keys with uppercase characters, as browsers will coerce attribute names into lowercase:

当使用Dom内(in-DOM) templates(直接写在HTML文件内的templates). 应该避免使用使用大写字母命名属性(attribute)key值.因为浏览器会强制转小写.

<!--
This will be converted to v-bind:[someattr] in in-DOM templates.
Unless you have a "someattr" property in your instance, your code won't work.
-->
<!--
会被转成v-bind:[someattr]在dom内templates,除非那你实例里面有一个属性(property)名'someattr',不然这个代码是无效的.
-->
<a v-bind:[someAttr]="value"> ... </a>

JavaScript Expressions JS表达式们

Template expressions are sandboxed and only have access to a whitelist of globals such as Math and Date. You should not attempt to access user defined globals in template expressions.

Template表达式沙盒式的.只有全局白名单的访问权限,如DateMath.不要尝试在template表达式里面去访问用户定义的全局变量

疑问点🤔️