本章概要

  • 应用程序实例
  • 插值
  • 指令

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将呈现的 DOM 绑定至底层组件实例的数据。所有的 Vue.js 模板都是有效的 HTML ,可以被符合规范的浏览器和 HTML 解析器解析。
在底层,Vue 将模板编译为虚拟 DOM 呈现函数,结合响应式系统,当应用程序状态发生变化时,Vue 可以智能地计算出需要重新渲染和应用最小数量 DOM 操作的组件。
如下,例4-1:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Hello Vue.js</title>
	</head>
	<body>
		<!--View-->
		<div id="app">
			<!--简单的文本插值-->
			<p>{{message}}</p>
			<!--使用 JavaScript 表达式-->
			<p>{{message.toUpperCase()}}</p>
			<!--HTML代码将以普通文本的方式输出-->
			<p>{{spanHtml}}</p>
			<!--输出HTML代码-->
			<p v-html="spanHtml"></p>
			<!--使用v-bind指令对HTML元素的属性进行绑定-->
			<a v-bind:href="url">新浪网</a>
		</div>
	
		<script src="https://unpkg.com/vue@next"></script>
		<script>
			const App = {
			  data(){
			    return {
			        message: "Hello Vue.js",
			  	    url: "http://www.sina.com.cn/",
			  	    spanHtml: `
			  	       <span style='color: red'>
			  	            HTML元素,以红色字体显示
			  	       </span>`
			    }
			  }
			};
			const app = Vue.createApp(App);
			const vm = app.mount('#app');
		</script>
	</body>
</html>

4.1 应用程序实例

在一个使用 Vue.js 框架的页面应用程序中,需要创建一个应用程序实例(例4-1的第36行),这个实例将提供应用程序上下文,应用程序实例装载的整个组件树将共享相同的上下文。
Vue 3.0 引入 createApp() 是为了解决 Vue 2.x 全局配置带来的一些问题。createApp() 是全局 API ,它接受一个根组件选项对象作为参数,改对象可以包含数据、方法、组件生命周期钩子等,然后返回应用程序实例自身。
在组件选项中的 data 选项是一个函数(例4-1第25-34行),Vue在创建组件实例时会调用该函数。data() 函数返回一个数据对象,Vue 会将这个对象包装到它的响应式系统中,即转换为一个代理对象,此代理使 Vue 能够在访问或修改属性时执行依赖项跟踪和更改通知,从而自动重新渲染 DOM 。数据对象的每个属性都被视为一个依赖项。
创建了应用程序实例后,可以调用实例的 mount() 方法(例4-1第37行),指定一个 DOM 元素,在该 DOM 元素上装载应用实例的根组件,这样这个 DOM 元素中的所有数据变化都会被 Vue 框架所监控,从而实现数据双向绑定。
第36和37行代码可以链式调用,简写为如下形式:

Vue.createApp(App).mount('#app');

注意:第37行,在调用应用程序实例的 mount() 方法时将返回的组件实例赋给了变量 vm ,在实际开发中并不要求一定要将根组件实例赋值给某个变量。

4.2 插值

数据绑定最常见的形式就是使用 Mustache 语法(双花括号)的文本插值,如例4-1中第11行代码。
Mustache 标签会被替换为来自相应组件实例的 message 属性的值。只要绑定的数据对象中的 message 属性发生了变化,插值处的内容就会被更新。
使用 Chrome 浏览器打开 例4-1的页面,按 F12 键,打开浏览器的开发者工具,如图:
在这里插入图片描述

切换到 Console 窗口,输入 vm.message = “welcome you” ,然后按 Enter 键,可以看到页面中的内容同步发生了更新,如下:
在这里插入图片描述

提示:Vue 在创建组件实例时,会把 data() 函数返回的数据对象保存到组件实例的 data 属性中,同事为了方便访问,数据对象的任何顶层属性也直接通过组件实例公开。
也就是说,要访问 message 数据属性,vm.$data.message 和 vm.message 是等价的。

如果绑定的数据中包含了 HTML 代码,那么使用 Mustache 语法把 HTML 代码以普通文本的方式进行输出,也就是说,Vue 内部对 HTML 代码进行了字符转义。
例4-1在数据对象中定义了 spanHtml属性(第29行),其值是一段 HTML 代码,第15行的 {{spanHtml}}在页面渲染时会被替换为下面的内容:

<span style='color: red'> HTML元素,以红色字体显示</span>

如果要输出真正的 HTML 代码,以便浏览器能够正常解析,需要使用 v-html 指令。如例4-1第17行代码所示。
Mustache 语法不能作用于 HTML 元素的属性上,要解决 HTML 元素属性值的绑定问题,需要使用 v-bind 指令。
例4-1 在数据对象中定义了 url 属性(第28行),第19行的代码如下:

<a v-bind:href="url">新浪网</a>

使用 v-bind 指令将 url 属性和元素的href 属性进行了绑定。在浏览器 Console 窗口改变 url 的值,查看元素的 href 属性是否同步发生改变。如下:
在这里插入图片描述

除了绑定简单的属性外,对于所有的数据绑定,Vue.js 还提供了完全的 JavaScript 表达式支持。
例4-1的第13行代码:

<p>{{message.toUpperCase()}}</p>

这是使用 JavaScript 表达式的例子。还可向如下代码一样,在插值语法中使用 JavaScript 表达式。

{{ a + b }}
{{ isLogin ? username : 'not login' }}
{{ message.split('').reverse().join() }}
<div v-bind:id="'list-' + id"></div>

这些表达式会在当前活动实例的数据范围作为 JavaScript 进行计算。需要注意的是,每个绑定都只能包含单个表达式,所以下面的示例都不会生效。

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- if语句也不会生效,可以使用三元表达式来代替 -->
{{ if (ok) { return message } }}

4.3 指令

指令是带有 v- 前缀的特殊属性,其值限定为单个表达式。指令的作用是,当表达式的值发生改变时,将这个变化(即响应式系统中的副作用,effect)反映到 DOM 上。
例如下面代码中的 v-if 指令将根据表达式 show 的值的真假来决定是插入还是删除

元素。

<p v-if="show">你能看到我不</p>

此外,一些指令还可以带有参数,在指令名称之后以冒号表示,如 v-bind 和 v-on 指令。

<a v-bind:href="url">新浪网</a>
<button v-on:click="sayGreet">Greet</button>

v-bind 指令用于响应式地更新 HTML 属性;v-on 指令用于监听 DOM 事件。

提示:因为 v-bind 和 v-on 指令经常被使用,因此,Vue.js 为这两个指令提供了简写语法。如下:

<!-- 完整语法 -->
<a v-bind:href="url" >dong dong dong</a>
<!-- 简写语法 -->
<a :href="url" >dong dong dong</a>
<!-- 完整语法 -->
<button v-on:click="sayGreet">Greet</button>
<!-- 简写语法 -->
<button @click="sayGreet">Greet</button>

从 Vue.js 2.6.0 版本开始,指令的参数可以是动态参数,语法为指令 :[JavaScript表达式]。如下:

<a v-bind:[attribute]="url">新浪网</a>

这里的 attribute 会被作为一个 JavaScript 表达式进行动态求值,求得的值作为最终的参数使用。假设组件实例中有一个数据对象属性为 attribute ,其值为 href,那么这个绑定将等价于 v-bind:href 。如果 attribute 的值计算为 null,那么这个绑定将被删除。最后的渲染结果如下:

<a>新浪网</a>

**在 DOM 中使用模版时(直接在一个 HTML 文件里编写模板),还需要避免使用大写字符命名动态参数,这是因为浏览器会把元素的属性名全部强制转换为小写字符。**如下:
例4-2

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Hello Vue.js</title>
    </head>
    <body>
        <!--View-->
        <div id="app">
            <a v-bind:[attributeName]="url">新浪网</a>
        </div>
    
        <script src="https://unpkg.com/vue@next"></script>
        <script>
            var vm = Vue.createApp({
                  data(){
                    return{
                      attributeName: "href",
                      url: "http://www.sina.com.cn/"  
                    }
                }
            }).mount('#app');
        </script>
    </body>
</html>

浏览器在加载该页面时,会将 v-bind:[attributeName] 转换为 v-bind:[attributename] ,之后 Vue 框架的核心代码在解析动态参数 attributename 时,发现在组件实例的数据对象中找不到 attributename 属性(数据对象中定义的是 attributeName),于是会提示一个警告信息:Property “attributename”was accessed during render but is not defined on instance。
使用动态参数时,还需要注意的是,不要使用复杂的表达式,因为 HTML 元素的属性命名是有规范的。例如,名称中不能有空格或引号。下面的代码将不能正常运行:

<a v-bind:['foo' + bar]="value">...</a>
Logo

前往低代码交流专区

更多推荐