Table of Contents
本系列前文传送门
- 「网页开发|前端开发|Vue」01 快速入门:快速写一个Vue的HelloWorld项目
- 「网页开发|前端开发|Vue」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转
- 「网页开发|前端开发|页面布局」03 学会够用的CSS,实现任意你想要的页面布局
前言
在了解Vue项目的文件结构、如何通过路由拥有多页面网站以及如何去实现单个页面的元素布局之后,我们就需要去实现具体单个页面的内容了。
因此我们就需要在使用html编写页面的基础上,掌握一些vue的特性来帮助编写页面内容以及页面数据的处理和变化。
一、Vue实例:项目入口
我们要使用Vue来搭建网站,就需要实例化一个Vue对象来代表一个Vue应用,如下:
1// The Vue build version to load with the `import` command 2// (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3import Vue from 'vue' 4new Vue({ 5 ...... 6})
我们来看一个具体的网站Vue实例:
1<div id="app"> 2 <p>{{message}}</p> 3</div> 4 5<script type="text/javascript"> 6 var vm = new Vue({ 7 el: '#app', 8 data: { 9 message: "Hello Vue World!" 10 }, 11 methods: { 12 printMessage: function() { 13 console.log(this.message) 14 } 15 } 16 }) 17</script>
这里Vue({})
中有三个参数:el
, data
, methods
:
el
代表要挂在的HTML元素的iddata
初始化了一些数据给页面,这里初始化了变量message
的值为Hello Vue World!
,而html代码中用{{ message }}
表示这里使用message
的值作为渲染内容method
则是用来定义供页面使用的方法,这里定义了printMessage()
方法,调用后会在控制台输出message
的值
一个Vue应用代表一个网站,一个网站一般会有多个页面,对应到Vue中成为多个组件。一般来说,每个页面都是应用的一个组件,页面中需要被重复用的的部分也会单独拆分成一个组件。
我们在「网页开发|前端开发|Vue」01 快速入门:快速写一个Vue的HelloWorld项目中已经探索了使用脚手架工具生成的标准化Vue项目文件的结构以及各个代码之间的流转,可以回看加深一下理解。
二、模板语言:Vue如何编写页面
我们一般会将 Vue 组件定义在一个单独的 .vue 文件中,叫做单文件组件。
Vue扩展了HTML,称之为模板。任何合乎规范的 HTML 都是合法的 Vue 模板,在一个XXXX.vue
文件中,会有<template></template>
标签,在其中是HTML
代码(这些HTML
将最终被渲染成浏览器页面),如下:
1<template> 2 <div class="hello"> 3 <h1>Hello World</h1> 4 </div> 5</template>
这使得如果熟悉html
语言,可以快速开发vue
网站应用的开发。
在同一个XXXX.vue
文件中,会有CSS
代码,默认这些样式代码只针对这个文件中的HTML
元素有效,如下:
1<style scoped>
2h1 {
3 font-weight: normal;
4}
5</style>
6
这里的scoped
属性是一个可选属性,加上之后会自动添加一个唯一的 attribute (比如 data-v-21e5b78
) 为这个文件中内 CSS 指定作用域,编译的时候 .list-container:hover 会被编译成类似 h1[data-v-21e5b78]
。
同样的,XXXX.vue
文件中也会有javascript
代码,以<script></script>
包括起来,如下:
1<script> 2export default { 3 name: 'HelloWorld', 4 data() { 5 return { 6 msg: 'Hello Vue World!' 7 } 8 } 9} 10</script>
总而言之,我们只需要记住Vue
所谓的模板
就是将一个页面的HTML
, CSS
以及javascript
代码单独放到一起的XXXX.vue
文件。当我们要编写一个页面的时候,我们只需要在对应的.vue
文件中编写代码即可。
我们在「网页开发|前端开发|Vue」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转 中已经介绍了如何将展示一个页面的网站,通过路由设计拓展成展示多个页面的网站,可以回看加深理解。
三、模板语法:类编程语言的设计
因为Vue的模板可以理解是扩展了的HTML,Vue提供了一些类似编程语言语法关键字的模板语法来帮助开发,也叫做指令。
Vue官网介绍,一个指令的本质是模板中出现的特殊标记,让处理模板的库知道需要对这里的 DOM 元素进行一些对应的处理。
指令的前缀是默认的 v-,常见指令如下:
v-if
: 条件判断,当if条件为true时元素才会存在(注意,是直接在页面源代码中不存在这个元素的代码)。当有多个条件分支的时候会搭配v-else-if
,v-else
来使用。
1<div id="app"> 2 <div v-if="type === 'A'"> 3 A 4 </div> 5 <div v-else-if="type === 'B'"> 6 B 7 </div> 8 <div v-else-if="type === 'C'"> 9 C 10 </div> 11 <div v-else> 12 type is not A or B or C 13 </div> 14</div>
v-show
: 与v-if
相似,用来控制是否展示某些元素。但v-if
结果为false
的时候页面源代码里不会有对应元素的代码,但是v-show
为false
的时候,页面源代码中也会有对应元素的代码,只是我们在浏览器渲染的页面中看不到而已。v-for
:- for循环,主要用来处理数组,通过遍历来展示多个元素
- 注意,比如希望得到一个
<ul>
中有多个<li>
的结果,v-for
应该写在<li>
中
v-bind
:- 当元素属性(比如
class
)的值需要用到data
里面定义的变量时,需要使用v-bind
来标记 - 比如
<div v-bind:class="{ isActive?'active':'default' }">
表示,如果当变量isActive
的值为true,则class='active'
,否则class='default'
v-bind:class="{ isActive?'active':'default' }"
也可以简写成:class="{ isActive?'active':'default' }"
- 当元素属性(比如
v-on
:- 与
v-bind
类似,v-bind
是在元素属性上绑定逻辑,v-on
则是在元素事件上绑定逻辑。 - 比如
<button v-on:click="counter += 1">增加 1</button>
是给button
的click
事件绑定了counter+=1
的逻辑,使得每次点击Button都会将counter
的值加一 v-on:click="counter += 1"
可以简写成@click="counter += 1"
- 与
v-model
: 用来在表单控件元素上(比如input
)绑定某个数据变量,然后就可以通过表单控件来修改变量的值。
1<div id="app"> 2 <p>input 元素:</p> 3 <input v-model="message" placeholder="编辑我……"> 4 <p>消息是: {{ message }}</p> 5</div> 6 7<script> 8new Vue({ 9 el: '#app', 10 data: { 11 message: 'input what you want', 12 } 13}) 14</script>
我们看到这里在通过new Vue({...})
创建了一个实例,然后实例化的同时初始化了变量message
的值为input what you want
,然后通过v-model
将变量message
绑定到<input>
上,这个时候如果我们修改输入框中的内容,这个新的内容就会成为变量message
新的值,相当于提供了通过用户输入修改变量值的途径,或者说提供了存储用户输入的途径。
四、计算属性与监听属性
直接在模板中的用变量的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护,于是就有了计算属性和监听属性:
- 计算属性:我们可以指定通过一个变量A,去计算变量B,当A发生变化的时候,B会跟着重新计算。
- 监听属性:指定监听一个变量A,当变量A变化时,都会执行编写好的逻辑。这里的逻辑可以是计算也可以是其他的。
- 计算属性是为了及时更新值(计算逻辑只是得到值的手段),而监听属性是为了执行预定逻辑。
计算属性具体用法如下:
1<template> 2<div id="app"> 3 <button @click="count += 1">增加 1</button> 4 <p>Count: {{ count }}</p> 5 <p>Double Count: {{doubleCount}}</p> 6</div> 7</template> 8<script> 9export default { 10 data() { 11 return { 12 count:1 13 } 14 }, 15 computed: { 16 // 每当 count 改变时,这个函数就会执行 17 doubleCount() { 18 return this.count * 2 19 } 20 } 21} 22</script>
这里当我们点击button
按钮使得变量count
加一之后,doubleCount
会重新计算。
注意,这里在computed
的doubleCount
函数体中要访问data()
中定义的count
,需要使用this
来定位,不然会无法找到变量从而抛出如下的ReferenceError
错误:
1vue.esm.js:3767 ReferenceError: count is not defined
2 at VueComponent.doubleCount (HelloWorld.vue:19:1)
3 at Watcher.get (vue.esm.js:4164:1)
4 at Watcher.evaluate (vue.esm.js:4265:1)
5 at VueComponent.computedGetter [as doubleCount] (vue.esm.js:4490:1)
6 at Object.get (vue.esm.js:706:1)
7 at Proxy.render (HelloWorld.vue:16:1)
8 at Vue._render (vue.esm.js:2540:1)
9 at VueComponent.updateComponent (vue.esm.js:2980:1)
10 at Watcher.get (vue.esm.js:4164:1)
11 at new Watcher (vue.esm.js:4154:1)
监听属性具体用法如下:
1<template> 2 <div id="app"> 3 <button @click="count += 1">点击</button> 4 <p>Count: {{ count }}</p> 5 </div> 6</template> 7<script> 8export default { 9 data() { 10 return { 11 count: 1 12 } 13 }, 14 watch: { 15 // 每当 count 改变时,这个函数就会执行 16 count(newValue, oldValue) { 17 alert(`count从 ${oldValue} 增加到了 ${newValue}`) 18 } 19 } 20} 21</script> 22
这里watch中定义的count
监听逻辑会有两个参数代表原值和新值,我们可以在逻辑中使用这两个值做一些判断或者计算。
五、生命周期与Hook函数
生命周期是一个类比人类生命的技术术语,用来表示元素或者说组件从被创建、初始化、渲染更新、再次渲染、卸载(移除)等一系列过程。
Vue 组件完整的生命周期包括,创建组件、初始化数据、编译模板、挂载 DOM、渲染、更新、再次渲染、卸载等一系列过程。
在这些过程的前后我们都要执行相应的方法,这些方法就叫做Hook(钩子)函数。而在Vue 组件的生命周期中有 8 个常用的钩子函数,我们可以在刚才的代码中加入各个生命周期Hook函数来测试效果,如下:
1<template> 2 <div id="app"> 3 <button @click="count += 1">点击</button> 4 <p>Count: {{ count }}</p> 5 </div> 6</template> 7<script> 8export default { 9 data() { 10 return { 11 count: 1 12 } 13 }, 14 watch: { 15 // 每当 count 改变时,这个函数就会执行 16 count(newValue, oldValue) { 17 alert(`count从 ${oldValue} 增加到了 ${newValue}`) 18 } 19 }, 20 beforeCreate() { 21 console.log(`the vue is beforeCreate.`) 22 }, 23 created() { 24 console.log(`the vue is created.`) 25 }, 26 beforeMount() { 27 console.log(`the vue is beforeMount.`) 28 }, 29 mounted() { 30 console.log(`the vue is mounted.`) 31 }, 32 beforeUpdate() { 33 console.log(`the vue is beforeUpdate.`) 34 }, 35 updated() { 36 console.log(`the vue is updated.`) 37 }, 38 beforeDestroy() { 39 console.log(`the vue is beforeDestroy.`) 40 }, 41 destroyed() { 42 console.log(`the vue is destroyed.`) 43 } 44} 45</script> 46
回到浏览器页面使用F12打开开发者工具,可以在console控制台中看到如下输出:
the vue is beforeCreate.
the vue is created.
the vue is beforeMount.
the vue is mounted.
点击按钮之后,可以看到console中额外有如下输出信息:
the vue is beforeUpdate.
the vue is updated.
所以我们可以看到,当浏览器执行代码进行页面渲染的时候,会依次执行创建组件的Hook函数(beforeCreate()
和created()
)和挂载的Hook函数(beforeMount()
和mounted()
)。
当我们进行点击或者其他交互行为时,页面元素或组件更新进行再次渲染,会触发更新的Hook函数(beforeUpdate()
和updated()
),而当卸载组件时才会触发卸载的Hook函数(beforeDestroy()
和destroyed()
)
以上就是在Vue开发过程中主要会使用到的内容,至于其他更加细致针对具体应用场景的用法,直接在遇到具体开发场景时,查阅Vue文档即可。
本系列下一篇文章传送门
写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇