随着前端交互复杂度的不断提升,各种字符拼接、循环遍历、DOM节点的操作也变得复杂多样。当数据量大、交互频繁时,无论是从用户体验还是性能优化上,都会面临前端渲染的问题。
Vue使用了一种基于HTML的模板语法,使用户能够声明式地将应用或组件实例的数据绑定到呈现的DOM上。模板中除了HTML的结构,还包含两个Vue模板的特有语法:插值和指令。插值语法只有一个功能,就是向标签体中插入一个动态的值。指令语法用来操作其所在的标签,比如指定动态属性值、绑定事件监听、控制显示隐藏等。
在底层机制中,Vue会将模板编译成高度优化的JavaScript代码。结合响应式系统,当应用状态数据变更时,Vue能够自动更新需要变化的DOM节点,并做到最小化更新。
前面我们提过,插值语法用来向标签体中插入一个动态的值。插值语法的结构很固定,用双大括号包含一个JavaScript表达式,即{{JavaScript表达式}}。值得一提的是,插值语法只可以作为一个标签的标签体文本或者标签体文本的一部分,不能作为标签的一个属性值。双大括号中可以包含任意JavaScript表达式,可以是一个常量、一个变量,或一个变量对象的方法调用,甚至可以是一个三目表达式。
但需要注意的是,模板中的变量读取数据的来源都是配置指定的data对象。后续还会讲解其他的数据来源,在这里读者暂时只需要理解为data对象。
来看一个简单的Vue使用实例,同时读者可以思考下方代码的运行效果。
上面的代码使用插值语法分别包含了常量“123”、变量“msg”、变量对象的方法调用“msg.toUpperCase()”,以及三目表达式“score<60?'入学测试未通过,暂时不可以来尚硅谷学习':'入学测试通过,欢迎来尚硅谷学习'”。前面我们说过,模板中的所有变量读取的都是data对象中的数据,除常量“123”不需要读取数据以外,后三者都会读取data对象中对应的数据。因此,页面效果如图2-1所示。
图2-1 页面效果
指令(Directive)是带有“v-”前缀的Vue自定义标签属性,其属性值一般是一个JavaScript表达式。Vue中包含了一些不同功能的指令,比如v-bind用来给标签指定动态属性值,v-on用来给标签绑定事件监听,v-if和v-show用来控制标签是否显示。但需要注意的是,不管是什么功能的指令,它们操作的目标都是指令属性所在的标签。
下面以v-bind与v-on为例来演示指令语法的使用,同时读者可以思考下方代码的运行效果。
这里先将这两个指令的语法进行展示,以便于读者后续的理解。
● v-bind:属性名="JavaScript表达式"。
● v-on:事件名="方法名表达式"。
代码如下所示。
上面这段代码使用v-bind为a标签指定了动态属性值url,此时a标签的href属性值就是data对象中定义的url值,如图2-2所示;使用v-on为button标签绑定事件监听并指定回调confirm函数,当点击按钮时触发该函数执行对应操作。通过控制台查看该效果,如图2-3和图2-4所示。
图2-2 a标签的href属性值
图2-3 弹出对话框
图2-4 点击“确定”按钮后跳转至尚硅谷官方网站
其实Vue允许将“v-bind:属性名”简化为“:属性名”,“v-on:事件名”简化为“@事件名”的形式,并且在实际项目开发中,前端工程师基本上会使用简化的语法进行开发。
例如,可以将上面的相关代码简化为下面的代码。
在通过createApp创建应用对象时,需要为其指定一个配置对象,这个配置对象中有两个基本的配置项,分别是data和methods。下面我们就对这两个配置项进行具体讲解。
首先来讲解data配置项。它的值必须是函数,且返回一个包含 n 个可变属性的对象,我们一般称此对象为data对象。此对象中的属性,我们常称为data属性。在模板中可以读取任意data属性进行动态显示。
然后来讲解methods配置项。它是一个包含 n 个方法的对象。在方法中用户可以通过this.xxx来读取或更新data对象中对应的属性。当更新了对应的data属性后,页面会自动更新。
有一点需要特别说明,data函数和method方法中的this,本质上是一个代理(Proxy)对象。它代理了data对象中所有属性的读/写操作。也就是说,用户可以通过this来读取或更新data对象中的属性。在methods对象中定义的所有方法最终也会被添加到代理对象中,同理,也可以在方法中通过this来更新data属性,从而触发页面自动更新。至于模板中的表达式读取变量或函数,本质上也都是从代理对象上查找的。
下面通过一段代码对data函数和methods对象进行具体演示,这里建议读者也对下方代码的运行效果进行思考。
运行代码,初始页面效果如图2-5所示,2秒后界面上的count属性值从0更新显示为2,4秒后更新显示为3。
图2-5 初始页面效果
在上面的代码中,我们设置了2个定时器,分别在2秒和4秒后调用,2秒后将data对象中的count属性值进行更新(增加2),4秒后调用vm的方法更新count属性值(增加3)。这部分内容比较简单,不再对其做详细讲解。
值得一提的是,上面的代码在data函数中输出了this来验证前面提到的“data对象中的所有属性都在代理对象上”和“methods对象中的方法会成为代理对象的方法”,具体来看控制台输出的结果,如图2-6所示。
图2-6 data函数中输出的代理对象
这里只对控制台输出的部分结果进行截取,在其中我们可以清晰地看到,代理对象中确实有data对象中的属性count和methods对象中的方法updateCount(具体见图2-6中的矩形框)。这也充分验证了我们之前的说法。