Vue基础
学习目标
第一章 Vue概述
1.1 Vue介绍

- Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
- Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
- 前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
官网:https://cn.vuejs.org/
VueJS是前端渐进式框架,让HTML和JavaScript无缝的整合,实现了视图和模型的双向数据绑定(MVVM)。
渐进式框架:可以先使用vue的基础功能,然后在此基础上逐渐使用你所需要的其他的功能

1.2 MVVM模式
MVVM是Model-View-ViewModel的简写。它本质上就是MVC的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)
MVVM是前端视图层的分层开发思想,主要是把每个页面,分成了M , V 和 VM 其中,VM是 MVVM 思想核心;
因为VM 是 M 和 V 之间的调度者

Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

MVVM模式是视图和模型的双向数据绑定,通过ViewModel实现,当View发生变化,Model变化;当Model变化,View也相应的变化。
第二章 Vue快速入门
2.1 快速入门
- 创建工程
- 导入vue.js
- 编写入门程序(Vue实例)
- 插值表达式
【需求】:使用vue,对 message 赋值,并把值显示到页面{{}}中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>快速入门</title> </head> <body> <div id="app"> <p>{{ message }}</p> </div>
<script src="./js/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: { message: '欢迎学习Vue' } }) </script> </body> </html>
|
2.2 插值表达式
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值,Mustache 标签将会被替代为对应数据对象上属性的值。无论何时,绑定的数据对象上属性发生了改变,插值处的内容都会更新。
Vue.js 都提供了完全的 JavaScript 表达式支持。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>插值表达式</title> </head>
<body> <div id="app"> {{ message }} <br> {{ message1 }} <br> {{ message1 + 10 + 100 }} <br> {{ message1 > 5 ? "大于5的数" : "小于5的数" }} </div> <script src="./js/vue.js"></script> <script> var vue = new Vue({ el: "#app", data:{ message: "hello vue", message1: 10 }, methods:{ } }) vue.message = "hello Kevin" </script> </body> </html>
|
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
1 2 3 4
| <!-- 这是语句,不是表达式 --> {{ var a = 1 }} <!-- 流控制也不会生效,请使用三元表达式 --> {{ if (ok) { return message } }}
|
2.3 小结
Vue的使用其实很简单,只需要导入1个js,定义1个Vue实例,写3个属性(el,data,methods),写1个插值表达式输出结果,即可实现效果。
- data:用来定义模型(Model)
{{}}:用来显示数据(View)
- ViewModel:用来将模型的数据显示到视图上
第三章 Vue常用指令
指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
3.1 v-on(缩写@)
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
3.1.1 v-on:click(缩写@click)
【需求】:点击按钮事件,改变message的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>v-on:click单击事件</title> </head> <body> <div id="app"> {{ message }} <button @click="fun('good')">改变</button> </div> <script src="js/vue.js"></script> <script> var vm = new Vue({ el: "#app", data:{ message: "hello world" }, methods:{ fun(msg) { this.message = msg; } } }); </script> </body> </html>
|
3.1.2 v-on:keydown
表示键盘按下事件。
xxxxxxxxxx :smile: :heart: :+1:text
KeyCode对照

【需求】:对文本输入框做校验,使用键盘按下事件,如果按下0-9的数字,正常显示,其他按键则阻止事件执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>v-on:keydown</title> </head> <body> <div id="app"> <input type="text" v-on:keydown="fun($event)"> </div> <script src="js/vuej.js"></script> <script> new Vue({ el: "#app", data: { message: 10 }, methods: { fun(e) { var keyCode = e.keyCode; if(!(keyCode >= 48 && keyCode <= 57)) { e.preventDefault(); } } } }); </script> </body> </html>
|
3.1.3 v-on:mouseover
鼠标移入区域事件
【需求1】:给指定区域大小的div中添加样式,鼠标移到div中,弹出窗口。
【需求2】:阻止上一层事件的执行(阻止事件冒泡)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> <style> .father{ width: 500px; height: 500px; background: red; } .son{ width: 300px; height: 300px; background: blue; } </style> </head> <body> <div id="app"> <div class="father" @mouseover="father()"> <div class="son" @mouseover="son()"></div> </div> </div> <script src="vue.js"></script> <script> var vm = new Vue({ el: "#app", methods: { father(){ alert('father'); }, son(){ alert('son'); } } }) </script> </body> </html>
|
3.2 v-text与v-html
使用{{}}可以输出文本的值。
v-text:输出文本内容,不会解析html元素
v-html:输出文本内容,会解析html元素
【需求】:使用message属性赋值,查看页面输出内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>v-text与v-html</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <div v-text="message"></div> <div v-html="message"></div> </div> </body> <script> new Vue({ el: "#app", data: { message: "<h1>hello world</h1>" } }); </script> </html>
|
3.3 v-bind(缩写 :)
插值语法不能作用在 HTML 属性上,遇到这种情况应该使用 v-bind指令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> <style> .red{ color: red; } .big{ font-size: 30px; } </style> </head> <body> <div id="app"> <p>百度</p> <p class="red big">百度</p> <p v-bind:class="{red:isRed, big:isBig}">百度</p> <p :class="[ok ? 'red' : '', 'big']">百度</p> <p :class="[showred, 'big']">百度</p> <a :href="url">百度</a> </div> <script src="./js/vue.js"></script> <script> var vm = new Vue({ el: "#app", data:{ isRed: true, isBig: true, ok: true, showred: 'red', url: "http://www.baidu.com" }
}) </script> </body> </html>
|
v-bind缩写方式
1 2 3 4
| <a v-bind:href="url"></a>
<a :href="url"></a>
|
3.4 选项卡案例

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>选项卡</title> <style> .tab_con { width: 800px; height: 350px; margin: 50px auto 0; } .tab_btns{ height: 50px; } .tab_btns input { width: 100px; height: 50px; background: #ddd; font-size: 18px; font-weight: bold; border: 0px; outline: none; border-radius: 5px 5px 0 0; font-weight: bold; } .tab_btns input:hover { cursor: pointer; }
.tab_btns .active { background: #06f; color: #fff; } .tab_cons { height: 300px; background: #06f; border-radius: 0 5px 5px 5px; } .tab_cons div{ height: 300px; line-height: 300px; text-align: center; display: none; font-size: 26px; color: #fff; } .tab_cons .current { display: block; } </style> </head>
<body> <div id="app"> <div class="tab_con"> <div class="tab_btns"> <input type="button" value="按钮一" :class="[(num==0)?'active':'']" @click="num=0"> <input type="button" value="按钮二" :class="[(num==1)?'active':'']" @click="num=1"> <input type="button" value="按钮三" :class="[(num==2)?'active':'']" @click="num=2"> </div> <div class="tab_cons"> <div :class="[(num==0)?'current':'']">按钮一对应的内容</div> <div :class="[(num==1)?'current':'']">按钮二对应的内容</div> <div :class="[(num==2)?'current':'']">按钮三对应的内容</div> </div> </div> </div> <script type="text/javascript" src="./js/vue.js" ></script> <script type="text/javascript"> new Vue({ el: "#app", data:{ num: 0 } }) </script> </body> </html>
|
3.5 v-model
用于读取视图中的数据。
【需求】:使用vue赋值json数据,并显示到页面的输入框中(表单回显)。
点击提交按钮:
测试:改变输入框的值,同时验证模型的数据发生改变。
测试:改变json数据,验证同时输入框的内容也发生改变。
这就是MVVM模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>v-model</title> <style> .box { margin: 20px 0px; } </style> </head>
<body> <div id="app"> <div class="box"> <label>用户名:</label> {{ username }} <br> <input type="text" v-model="username" /> <input type="button" value="改变值" @click="fnChange" /> </div>
<div class="box"> <select v-model="sel"> <option value="0">大班</option> <option value="1">中班</option> <option value="2">小班</option> </select> {{ sel }} </div>
<input type="checkbox" v-model="danCheck" />同意用户协议 <h1>{{ singleCheck }}</h1>
<input type="checkbox" value="西瓜" v-model="multipleCheck" />西瓜 <input type="checkbox" value="苹果" v-model="multipleCheck" />苹果 <input type="checkbox" value="黄瓜" v-model="multipleCheck" />黄瓜 <h1>{{ multipleCheck }}</h1> <div class="box"> <input type="radio" value="男" v-model="sex" /> 男 <input type="radio" value="女" v-model="sex" /> 女 </div>
<textarea v-model="tarea"></textarea> <h1>{{ tarea }}</h1> </div>
<script type="text/javascript" src="./js/vue.js"></script> <script type="text/javascript"> var vue = new Vue({ el: '#app', data: { username: 'Kevin', sel: 1, singleCheck: false, multipleCheck: ['西瓜', '苹果', '黄瓜'], sex: '女', tarea: '' }, methods: { fnChange(){ this.username += 'haha' } } }) </script> </body> </html>
|
3.6 v-for
3.6.1 普通数组
用于遍历 array、集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>v-for遍历普通数组</title> </head>
<body> <div id="app">
<p v-for="(item, i) in list"> 索引值:{{i}} --- 每一项:{{item}} </p> </div> <script src="./js/vue.js"></script> <script> new Vue({ el: '#app', data: { list: [1, 2, 3, 4, 5, 6] }, methods: {} }); </script> </body> </html>
|
3.6.2 对象数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>v-for遍历对象数组</title> </head>
<body> <div id="app"> <p v-for="(user, i) in list"> Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}} </p> </div> <script src="./js/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: { list: [ { id: 1, name: 'Tom' }, { id: 2, name: 'Jerry' }, { id: 3, name: 'Jack' }, { id: 4, name: 'Lucy' } ] }, methods: {} }); </script> </body> </html>
|
3.6.3 循环对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <title>v-for遍历对象</title> </head>
<body> <div id="app"> <p v-for="(value, key, i) in user"> 值是: {{ value }} --- 键是: {{key}} -- 索引: {{i}} </p> </div> <script src="./js/vue.js"></script> <script> new Vue({ el: '#app', data: { user: { id: 1, name: 'Pony', address: '深圳' } }, methods: {} }); </script> </body> </html>
|
3.6.4 迭代数字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>v-for迭代数字</title> </head>
<body> <div id="app"> <p v-for="count in 10">这是第 {{ count }} 次循环</p> </div>
<script src="./js/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: {}, methods: {} }); </script> </body> </html>
|
3.6.4 key属性的使用
key的作用主要是为了高效的更新虛拟DOM,其原理是vue在patch(补丁)过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
另外,若不设置key还可能在列表更新时引发一些隐蔽的bug,如某行数据不该更新的却更新了。
vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
没有增删操作的场景下,key没有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>v-for中key的使用</title> </head>
<body> <div id="app"> <div> <label>Id:</label> <input type="text" v-model="id">
<label>Name:</label> <input type="text" v-model="name">
<input type="button" value="添加" @click="add"> </div>
<p v-for="item in list" :key="item.id"> <input type="checkbox">{{item.id}} --- {{item.name}} </p> </div>
<script> var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '李斯' }, { id: 2, name: '嬴政' }, { id: 3, name: '赵高' }, { id: 4, name: '韩非' }, { id: 5, name: '荀子' } ] }, methods: { add() { this.list.unshift({ id: this.id, name: this.name }) } } }); </script> </body> </html>
|
3.7 v-if与v-show
v-if是根据表达式的值来决定是否渲染元素
v-show是根据表达式的值来切换元素的display(css属性)
【需求】:使用vue赋值flag变量(boolean类型),用来判断元素中的内容是否显示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <p v-if="ok">这是使用了v-if的p标签</p> <p v-else>这是使用了v-else的p标签</p> <p v-show="ok">这是使用v-show的p标签</p> <div v-if="code=='A'">A</div> <div v-else-if="code=='B'">B</div> <div v-else-if="code=='C'">C</div> <div v-else>NOT A/B/C</div> </div> <script src="js/vue.js" ></script> <script type="text/javascript"> new Vue({ el: "#app", data:{ ok: true, code: 'D' } }) </script> </body> </html>
|
3.8 数组 splice() 方法
splice() 方法向数组中添加或者删除项目,然后返回被删除的项目。
该方法会改变原始数组。
语法:
1
| arrayObject.splice(index, howmany, item1, ..., itemX)
|
| 参数 |
描述 |
| index |
必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 |
| howmany |
必需。要删除的项目数量。如果设置为 0,则不会删除项目。 |
| item1, …, itemX |
可选。向数组添加的新项目。 |
返回值:
说明:
splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。
3.8.1 案例1
新增:在本例中,我们将创建一个新数组,并向其添加一个元素
1 2 3 4 5 6
| <script> var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"] document.write(arr + "<br>") arr.splice(2, 0, "William") document.write(arr) </script>
|
输出:
George, John, Thomas, James, Adrew, Martin
George, John, William, Thomas, James, Adrew, Martin
3.8.2 案例2
修改:在本例中我们将删除位于 index 2 的元素,并添加一个新元素来替代被删除的元素
1 2 3 4 5 6
| <script> var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"] document.write(arr + "<br>") arr.splice(2, 1, "William") document.write(arr) </script>
|
输出:
George, John, Thomas, James, Adrew, Martin
George, John, William, James, Adrew, Martin
3.8.3 案例3
删除:在本例中我们将删除从 index 2 开始的三个元素
1 2 3 4 5 6 7
| <script> var arr = ["George", "John", "Thomas", "James", "Adrew", "Martin"] document.write(arr + "<br>") var del = arr.splice(2, 3) document.write(arr + "<br>") document.write(del) </script>
|
输出:
George, John, Thomas, James, Adrew, Martin
George, John, Martin
Thomas, James, Adrew
3.9 TodoList案例

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| <!DOCTYPE html> <html lang="zh-CN">
<head> <meta charset="UTF-8"> <title>todolist</title> <style> .list_con { width: 600px; margin: 50px auto 0; } .inputtxt { width: 550px; height: 30px; border: 1px solid #ccc; padding: 0px; text-indent: 10px; } .inputbtn { width: 40px; height: 32px; padding: 0; border: 1px solid #06f; background-color: #06f; color: #fff; } .list { margin: 0; padding: 0; list-style: none; margin-top: 20px; } .list li { height: 40px; line-height: 40px; border-bottom: 1px solid #ccc; } .list li span { float: left; } .list li a { float: right; text-decoration: none; margin: 0 10px; } </style> </head>
<body> <div id="app" class="list_con"> <h2>To do list</h2> <input id="txt1" type="text" class="inputtxt" v-model="txt"> <input type="button" value="增加" class="inputbtn" @click="fnAdd">
<ul id="list" class="list"> <li v-for="(item,index) in content"> <span>{{item}}</span> <a href="javascript:;" class="up" @click="fnUp(index)"> ↑ </a> <a href="javascript:;" class="down" @click="fnDown(index)"> ↓ </a> <a href="javascript:;" class="del" @click="fnDel(index)">删除</a> </li> </ul> </div>
<script src="js/vue.js" ></script> <script> new Vue({ el: "#app", data:{ content: ['学习HTML', '学习CSS', '学习JavaScript'], txt: '' }, methods:{ fnAdd() { if (this.txt.trim() === '') { alert('输入内容不能为空') return } this.content.push(this.txt) this.txt = '' document.querySelector('#txt1').focus() }, fnDel(index) { if(confirm('确认删除吗?')){ this.content.splice(index, 1) } }, fnUp(index) { if (index == 0) { alert('亲,到顶了') return } this.content.splice(index - 1, 0, this.content[index]) this.content.splice(index + 1, 1) }, fnDown(index) { if (index == this.content.length - 1) { alert('亲,到底了') return } this.content.splice(index + 2, 0, this.content[index]) this.content.splice(index, 1) } } }) </script> </body> </html>
|
3.10 聊天对话框 课堂练习

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>聊天对话框</title> <style type="text/css"> .talk_con { width: 600px; height: 500px; border: 1px solid #666; margin: 50px auto 0; background: #f9f9f9; } .talk_show { width: 580px; height: 420px; border: 1px solid #666; background: #fff; margin: 10px auto 0; overflow: auto; } .talk_input { width: 580px; margin: 10px auto 0; } .whotalk { width: 80px; height: 30px; float: left; outline: none; } .talk_word { width: 420px; height: 26px; padding: 0px; float: left; margin-left: 10px; outline: none; text-indent: 10px; } .talk_sub { width: 56px; height: 30px; float: left; margin-left: 10px; } .atalk { margin: 10px; } .atalk span { display: inline-block; background: #0181cc; border-radius: 10px; color: #fff; padding: 5px 10px; } .btalk { margin: 10px; text-align: right; } .btalk span { display: inline-block; background: #ef8201; border-radius: 10px; color: #fff; padding: 5px 10px; } </style> </head>
<body> <div class="talk_con" id="app"> <div class="talk_show" id="words"> <div :class="[item.who=='A'?'atalk':'btalk']" v-for="item in content"> <span>{{item.who}}说:{{item.say}}</span> </div> </div> <div class="talk_input"> <select class="whotalk" id="who" v-model="sel"> <option value="0">A说:</option> <option value="1">B说:</option> </select> <input type="text" class="talk_word" id="talkwords" v-model="txt"> <input type="button" value="发送" class="talk_sub" id="talksub" @click="fnAdd"> </div> </div>
<script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var oTxt = document.getElementById("talkwords") oTxt.focus() new Vue({ el: "#app", data: { content: [{ who: 'A', say: '吃饭了吗?' }, { who: 'B', say: '还没呢,你呢?' }, ], txt: '', sel: '0' }, methods: { fnAdd: function() { if(this.txt==''){ alert('请您输入内容'); return; } this.content.push({ who: this.sel == '0' ? 'A' : 'B', say: this.txt }) this.txt = '' oTxt.focus() } } }) </script> </body> </html>
|
第四章 Vue生命周期
4.1 生命周期概述
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM(文档对象模型),以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
比如 created 钩子函数可以用来在一个Vue实例被创建之后执行代码。例如Ajax可以在created钩子函数下运行,使用Ajax对页面数据初始化。
1 2 3 4 5 6 7 8 9
| new Vue({ data: { a: 1 }, created: function () { console.log('a is: ' + this.a) } })
|
4.2 生命周期图示

Vue在生命周期中有这些钩子函数
- beforeCreate,created
- beforeMount,mounted
- beforeUpdate,updated
- beforeDestroy,destroyed
Vue在实例化的过程中,会调用这些生命周期的钩子,给我们提供了执行自定义逻辑的机会。那么,在这些vue钩子中,vue实例到底执行了哪些操作,我们先看下面执行的例子。
【需求】:演示vue对象的创建、赋值、显示、改值、销毁的全过程,即Vue的生命周期,同时使用钩子函数添加自己的业务逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>vuejs生命周期</title> </head>
<body> <div id="app"> <h1>{{ message }}</h1> </div> <script src="./js/vue.min.js"></script> <script> var vue = new Vue({ el: "#app", data: { message: 'hello world' }, beforeCreate: function() { showData('创建vue实例前', this); }, created: function() { showData('创建vue实例后', this); }, beforeMount: function() { showData('挂载到dom前', this); }, mounted: function() { showData('挂载到dom后', this); }, beforeUpdate: function() { showData('数据变化更新前', this); }, updated: function() { showData('数据变化更新后', this); }, beforeDestroy: function() { showData('vue实例销毁前', this); }, destroyed: function() { showData('vue实例销毁后', this); } });
function showData(process, obj) { console.log(process); console.log('data 数据:' + obj.message) console.log('vue挂载的虚拟dom对象:') console.log(obj.$el) console.log('真实dom结构:' + document.getElementById('app').innerHTML) console.log('------------------------------------------------------') } setTimeout(function(){ vue.message = "good..."; },3000)
setTimeout(function(){ vue.$destroy(); },6000)
</script> </body> </html>
|
总结:
vue对象初始化过程中,会执行到beforeCreate、created、beforeMount、mounted 这几个钩子的内容
beforeCreate:数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
created:数据已经绑定到了对象实例,但是还没有挂载对象(使用ajax可在此方法中查询数据,调用函数,页面的初始化)
beforeMount:模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点。
mounted:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进行各种操作。
当我们的data发生改变时,会调用beforeUpdate和updated方法
beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还没有发生改变。
updated :dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到dom上面,完成更新。
当调用vue.$destroy(),用来销毁vue。
beforeDestroy,destroed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听、还有model对象数据与view的绑定,即数据驱动。
第五章 Axios
5.1 Axios介绍
Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。
axios github:https://github.com/axios/axios
5.2 Axios请求方法
为方便起见,axios为所有支持的请求方法提供了别名
- axios.request(config)
- axios.get(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.patch(url[, data[, config]])
5.3 Axios基本使用
【需求】:创建data/user.json文件,使用axios调用json,将数据显示到页面上
第一步:创建data目录,创建user.json(后续我们从数据库查询,获取json数据)
1 2 3 4 5 6
| [ {"username":"张三","age":22}, {"username":"李四","age":21}, {"username":"王五","age":20}, {"username":"赵六","age":23} ]
|
第二步:使用axios读取user.json文件的内容,并在页面上输出内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <title>vuejs中axios数据调用</title> </head>
<body> <div id="app"> <p v-for="user in users"> {{user.username}} --- {{user.age}} </p> </div> <script src="./js/vue.min.js"></script> <script src="js/axios.min.js"></script> <script> var vm = new Vue({ el: "#app", data: { users: [] }, methods: { init(){ axios.get("./data/user.json").then(response => { console.log(response); this.users = response.data; }) } }, created() { this.init() } }); </script> </body> </html>
|
第六章:作业