- 1 Vue学习量化示意图
- 2 邂逅Vue
- 3 Vue基础语法
- 4 ES6补充
1 Vue学习量化示意图

2 邂逅Vue
2.1 认识Vuejs
- Vue是一个渐进式的框架
- 渐进式:意味可以将vue作为开发的一部分嵌入其中,带来更丰富的用户体验
- 使用更多的业务和逻辑实现,vue的核心库以及生态系统完全可以实现
- Core(vue核心库)+Vue-router(vue路由)+Vuex(用来做vue的状态管理)
- Vue特点和web开发中常见的高级功能
- 解耦视图和数据
- 可复用的组件
- 前端路由技术
- 状态管理(vuex)
- 虚拟DOM
- Vuejs需要的基础:具备HTML,CSS和js基础
2.2 Vuejs的安装方式
Vue.js安装方式有很多种
直接CDN引入(从最近的CDN服务器下载安装vue)
- 选择引入开发环境版本还是生产环境版本
1
2
3
4<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>下载和引用(初期学习我们直接引入到html页面中使用)
1 | 开发环境 https://vuejs.org/js/vue.js |
- npm安装
- 配合webpack(打包工具)和CLI(命令行工具)进行使用
2.3 Vuejs使用
2.3.1 基础实现
vue前端代码实现步骤
- 在html页面中引入下载好的vue.js文件
- 在html页面中的script标签下方创建vue对象并绑定dom元素(选择器),挂载创建好的实例对象和dom元素,
- 创建的实例对象可以操作dom元素
- 在修改过程成中需要更改vue对象中的数据而不需要更改网页数据,真正实现数据和结构分离
- 响应式过程:vue操作html页面显示
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23.html文件
<div id="box">
<p>{{name}}</p>
<p>{{age}}</p>
</div>
<!-- 引入下载好的vue.js文件 -->
<script src="../js/vue.js"></script>
<script>
// 创建vue对象,参数传入的是一个对象
/*
- el: '#box'->将vue对象挂载在哪个dom元素(这里通过选择器的方式),绑定以后就可以直接操作元素,实现响应式
- 响应式处理:vue中变量的更改网页部分无序在更改,显示的内容会自定进行更改
*/
let app = new Vue({
el: '#box',
//这里通过data参数传入数据
data: {
name: 'vuejs',
age: 12,
}
})
// 可以通过vue的实例对象app调用和使用属性和方法
</script>
响应式过程:通过过实例对象app修改vue实例对象中的内容网页html页面会自动响应修改后的显示内容
编程范式
声明式编程:vue框架中,这里已经封装好,直接调用
命令式编程:原生js中,按照步骤一步一步来进行操作
1
2
3
4
5
6原生js的做法(编程范式: 命令式编程)
1.创建div元素,设置id属性
2.定义一个变量叫message
3.将message变量放在前面的div元素中显示
4.修改message的数据: 今天天气不错!
5.将修改后的数据再次替换到div元素
vue中使用的ES6中的语法:
- let:变量声明
- const 常量声明
vue对象解析
参数:对象
data:对象(可能来自网络等)
app:对象实例
el:绑定的dom元素
methods:对象(存放的是自定义的方法函数)
在html元素中展示:
1
2
3
4
5
6
7const app = new Vue({
el: 'dom元素'
data:{传入的数据(键值对的方式)},
methods:{
//自定义的方法
}
})
浏览器执行代码的流程
- 执行到vue创建之前显示出对应的HTML
- 执行创建Vue实例,并且对原HTML进行解析和修改。
2.3.2 案例
列表展示
知识点
- v-for指令:循环实现列表展示功能,格式:
v-for='表达式'
- Vue对象中定义的方法和属性在html标签中可以直接获取,eg:data中定义的属性名,methods中定义的方法名
- v-for指令:循环实现列表展示功能,格式:
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.html文件
<div class="app">
<p>{{message}}</p>
<ul>
<li v-for='item in movies'>{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '.app',
data: {
message: '你好',
movies: ['hello', 'world', 'sing', 'pool', 'dance']
}
})
</script>结果展示
计数器
知识点
v-on指令:事件绑定
- 格式:
v-on:事件名称='执行的代码/函数名称'
1
v-on:click='count++'
- vue对象中的方法写在methods属性中:当有事件绑定执行多行代码,需要写在methods属性中
- 格式:
@click
指令:是v-on:click
的简写/语法糖this指向问题:
- vue对象中声明的属性名和方法在html标签中可以直接获取属性名
- vue内部使用vue对象中声明的属性民和方法需要使用this指向当前声明的vue对象实例才能使用,this->vue对象实例
- vue内部直接调用属性名和方法默认的this->window全局对象
事件绑定实现的方式有两种:
直接通过
v-on:click='执行代码'
的方式写在html标签中(注意:这里只能执行一句代码,多行代码采用方式2)将执行的代码封装在函数中,将封装的函数放在methods属性中,调用时传入方法名称即可
v-on:click='方法名称'
(注意:在事件监听的时候不用传递参数时()可以省略,其与情况下不能省略)
代码实现
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<div class="app">
<h2>当前计数:{{counter}}</h2>
<!-- 添加按钮 -->
<!-- 1.事件绑定方式1:直接执行 -->
<!-- <button v-on:click='counter++'>+</button>
<button v-on:click='counter--'>-</button> -->
<!-- 2.事件绑定方式2:添加方法 -->
<button v-on:click='add'>+</button>
<button v-on:click='sub'>-</button>
</div>
<script src="../js/vue.js"></script>
<script>
//代理proxy
var obj = {
counter: 0,
name: 'hello'
}
// 创建vue对象
let app = new Vue({
el: '.app',
data: obj,
// 定义方法写在methods对象中
methods: {
add: function () {
// 注意在对象内部调用对象的属性和方法通过this指向调用对象,默认属性名和方法是在全局中查找
this.counter++
},
sub: function () {
if (this.counter > 1)
this.counter--;
}
}
})
</script>
- 结果展示
2.4 Vuejs的MVVM
2.4.1 MVVM解析
MVVM:Model View VueModel的缩写
详细解析
View层:
视图层
在我们前端开发中,通常就是DOM层。
主要的作用是给用户展示各种信息。
Model层:
- 数据层
- 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。(data,methods)
- 在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。
VueModel层:(new Vue())
- 视图模型层
视图模型层是View和Model沟通的桥梁。
- 一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
示意图
2.4.2 计数器中 MVVM
2.5 Vue中options解析
let app = new Vue(options)
- options是传入的对象
options属性
el:
- 类型:String|Element(dom对象)
- 限制:只有在用new创建实例时才生效
- 作用:提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例(dom对象)
data:
- 类型:
Object | Function
- 限制:组件的定义只接受
function
。 - 详细:Vue 实例的数据对象。对象必须是纯粹的对象 (含有零个或多个的 key/value 对)
- 类型:
methods:
类型:
{ [key: string]: Function }
详细:
methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的
this
自动绑定为 Vue 实例。不应该使用箭头函数来定义 method 函数 (例如
plus: () => this.a++
)。理由是箭头函数绑定了父级作用域的上下文,所以this
将不会按照期望指向 Vue 实例,this.a
将是 undefined。
2.6 Vue的生命周期
- vue生命周期详细流程
- 官方声明周期图
- 绿色部分是vue内部进行的操作
- 红色部分是执行的钩子(hook)事件(回调函数):执行到这一步会触发回调函数执行相应操作,可以在实例对象中通过钩子函数来获取vue生命周期执行阶段,并调用实例对象中已经写好的钩子函数
- 黄色部分在循环挂载模板和挂载dom对象并进行页面的渲染
1 | let app = new Vue({ |
3 Vue基础语法
插值指令主要作用是将值插入到我们模板的内容当中(动态绑定内容)
3.1.1 Mustache模板引擎
Mustache语法解决的问题:即双大括号->将data中的文本数据插入到html中
[介绍:]:https://blog.csdn.net/kevin_Luan/article/details/46485561
- Logic-less templates.
- github:http://mustache.github.com/
- 文档:http://mustache.github.com/mustache.5.html
- mustache 类似 freemark和valicity 模板引擎,不过mustache 更轻量级,支持语言: Ruby, JavaScript, Python,Erlang, node.js, PHP, Perl, Perl6, Objective-C, Java, C#/.NET, Android, C++, Go, Lua,ooc, ActionScript, ColdFusion, Scala, Clojure,Fantom, CoffeeScript, D, Haskell, XQuery,ASP, Io, Dart, Haxe, Delphi, Racket, Rust,OCaml, Swift, and for Bash
Mustache语法
1
2
3
4
5
6
7
8
9
10- {{ name }} 打印变量,默认是escape过的,如果不要escape,用3个分隔符 {{{ name }}},或者用 {{ &name }},这个和分隔符无关
- {{#person}}…{{/person}} 区块(没有其他模板中的if else语句),4种方式
- person是真假值,决定是否输出
- person 是list of array,会循环展开 for x in person:section.render('xxx)
- person 是匿名函数/object, 区块包裹的html 会作为参数传递进去
- person 是dict,直接打印 dict[key]
- {{^person}}…{{/person},反向区块
- {{!name }} 注释
- {{> box }} 载入子模块Mustache的变量可以进行运算操作
1
2
3
4
5<!-- 变量输出 -->
<h2>{{message}}</h2>
<h2>{{firstName+' '+lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{counter*3}}</h2>

- 注意:Mustache语法使用在标签内容部分的,不能使用在属性值中
3.1.2 vue插值常用指令
v-once:
格式:
v-once
后面不在跟表达式,只会执行一次,后面修改了属性值也不会再响应该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变
代码
1 | <h2>{{message}}</h2> |
- 执行结果
v-html:
格式:
v-html='表达式'
该指令后面往往会跟上一个string类型
会将string的html解析出来并且进行渲染
作用:解析服务器端返回的html标签
代码:
1
2
3
4
5
6<h2 v-html='link'>123</h2>//这里使用vue中的v-html指令会覆盖掉html标签中原本的内容
vue参数:
data: {
message: 'hello world',
link: '<a href="http:www.baidu.com">百度一下</a>'
},执行结果
v-text:
v-text作用和Mustache比较相似:都是用于将数据显示在界面中
v-text通常情况下,接受一个string类型
缺陷:会覆盖掉html标签中原本的内容,一般不使用,建议使用Mustache语法
v-pre:
nv-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
作用:是否解析Mustache语法语法
后面不跟表达式
代码执行:
v-cloak:
cloak:斗篷的意思,遮盖
用于代码执行中断出现不友好的界面,在代码终端之前隐藏,执行结束在显示代码
vue代码执行之前添加v-cloak属性,代码执行会后会自动去掉v-cloak属性,进行html代码的展示
代码:在vue代码未执行之前隐藏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<style>
//v-clock存在的情况下执行这段代码,不存则不执行,代码正常显示
[v-cloak] {
display: none;
}
</style>
<div id="app">
<!-- vue -->
<h2 v-cloak>{{message}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
// 设置延时
setTimeout(function () {
let app = new Vue({
el: '#app',
data: { message: 'hello world' },
})
}, 1000)
</script>执行结果:代码暂停1秒钟之后显示内容
3.2 绑定属性
绑定指令:动态绑定属性
3.2.1 v-bind基本使用
- v-bind作用:
- nv-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍)
- 应用场景:
- 图片的链接src、网站的链接href、动态绑定一些类、样式等等
- 格式:
<img v-bind:src=''></img>
- 语法糖:
<img :src=''></img>
- 代码实现:通过Vue实例中的data绑定元素的src和href
1 | <!-- 动态的绑定属性 --> |
结果
3.2.2 v-bind绑定class
常规绑定和v-bind绑定的实现对比(二者都是直接在class后面添加字符串类名的名称)
- 原生的是直接写死的,不能动态改变
- v-bind绑定的,可以动态的添加属性值:字符串
‘类名’
的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14<style>
.active {
color: red
}
</style>
<div id="app">
<!-- 原生写法 -->
<h2 class="active">{{message}}</h2>
<!-- 绑定写法 -->
<h2 v-bind:class="activeflag">{{message}}</h2>
<!-- -->
</div>
activeflag:来自data中
activeflag: 'active',其他绑定的方式有两种:
- 对象语法
- 数组语法
对象语法
对象语法的含义是:class后面跟的是一个对象。对象中是键值对,通过键值对中的值为true/false来判断是否显示该类名,注意:这里的属性名称是类名(加不加括号都可以直接使用)
格式:
v-bind:class="{类名1: true, 类名2: boolean}">
具体用法:
- 用法一:直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
用法二:也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
- 用法三:和普通的类同时存在,并不冲突
注:如果isActive和isLine都为true,那么会有title/active/line三个类
<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
用法四:如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性
<h2 class="title" :class="classes">Hello World</h2>
代码实现
- 注意:
<h2 class='title' :class="getClass()"></h2>
中类内部是方法的调用,返回的是一个对象,这里不能直接写方法的名称,会报错
- 注意:
1 | <style> |
- 结果展示
数组语法
- 数组语法的含义是:class后面跟的是一个数组。
- 格式:
<h2 v-bind:class="[值1,值2,值3]"></h2>
- 值为变量:此时值来自data对象中
- 值为字符串:此时数值来自style的css样式中
- 具体用法
1 | 用法一:直接通过{}绑定一个类 |
- 数组中加引号表示的类名,和以前添加类名的方式一样,不加引号表示的是变量,获取的是data中对应的属性名的值
- 代码执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<div id="app">
<!-- 数组语法 -->
<!-- 格式:<h2 v-bind:class="[值1,值2,值3]">{{message}}</h2> -->
<!-- 注意这里和直接添加类名称是一样的,如下两种方式等价 -->
<h2 :class="['active','line']">{{message}}</h2>
<h2 class="active line">{{message}}</h2>
<!-- 注意上的数组中传入的是字符串类名(从style中直接获取的);
后面传入的是变量,值来自data -->
<h2 :class="['active','line']">{{message}}</h2>
<h2 :class="[active,line]">{{message}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'hello world',
activeflag: 'active',
active: 'title',
line: 'line'
},
}) - 结果
案例:v-for,v-bind,v-click实现
实现点击哪个list就变背景色
思路:
- v-for指令显示list
- 设置中间变量currentCounter来记录当前点击的index值
- 通过v-bind中对象的语法实现颜色变化(index=currentIndex)返回的本身就是boolean值可以确定当前点击颜色的变化(巧妙之处:添加中间变量)
- 通过v-click修改当前的index值
代码
1 | <style> |
- 执行结果
3.2.2 v-bind绑定style
注意:在vue中不加引号默认为变量,所以在写固定的属性值是需要加引号(数字等),属性名可以不用加vue当做字符串来解析
v-bind:style来绑定一些CSS内联样式
在写CSS属性名的时候,比如font-size,有两种写法
- 使用驼峰式 (camelCase) fontSize (建议使用驼峰式)
- 短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’(测试报错)
绑定的方式有两种
- 对象语法
- 数组语法
对象语法
1
2
3
4
5
6:style="{color: currentColor, fontSize: fontSize + 'px'}"
style后面跟的是一个对象类型
对象的key是CSS属性名称
对象的value是具体赋的值,值可以来自于data中的属性
- 不加引号:表示data中的属性值
- 加引号表示固定值代码
- 注意:写在方法中的值一定要添加this
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<div id="app">
<!-- 属性名:驼峰式命名 -->
<!-- 属性值:固定值加引号(数值也必须加),变量不加引号 -->
<h2 :style="{color:'red', backgroundColor: '#ff0'}">{{message}}</h2>
<h2 :style="{color:color, backgroundColor: '#ff0'}">{{message}}</h2>
<h2 :style="{fontSize:fontSize, backgroundColor: '#ff0'}">{{message}}</h2>
<!-- 注意这里的50px一定要引号 -->
<h2 :style="{fontSize:'50px', backgroundColor: '#ff0'}">{{message}}</h2>
<!-- 名称太长通过添加方法的方式 (一定要调用方法加括号)-->
<h2 :style="getClass()">{{message}}</h2>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
message: 'hello world',
color: 'red',
fontSize: '10px',
fontSize1: 30
},
methods: {
getClass: function () {
return { fontSize: this.fontSize1, backgroundColor: '#ff0' }
}
}
})
</script>数组语法
- 注意:写在方法中的值一定要添加this
数组中的值加引号表示固定值,不加表示变量
1 | <div v-bind:style="[baseStyles, overridingStyles]"></div> |
- 数组中添加的是多个对象属性,对象属性中定义的是style中的属性名和属性值
1 | <div id="app"> |
3.3 计算属性
3.3.1 计算属性的基本操作
计算属性是写在实例的computed选项中的
计算属性中定义的属性使用时直接填写属性名称即可
作用:需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
1
2
3
4
5
6
7
8
9<div id="app">//显示全名的三种实现方式
<!--1. 常规做法:Mustache语法拼接的方式 -->
<h2>{{firstName+' '+lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<!--2. 封装成函数的方式,直接调用 -->
<h2>{{方法调用}}</h2>
<!--3. 采用计算属性的方式获取,直接采用属性名的方式就可以,简介易于理解 -->
<h2>{{fullName}}</h2>
</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: 'Lemon',
lastName: 'Tom',
},
// 计算属性放在computed中
computed: {
// 采用属性名的方式进行命名,调用的时候直接调用属性名即可,而不用调用methods中的方法
fullName: function () {
return this.firstName + ' ' + this.lastName;
}
},
methods: {
getFullName: function () {
return this.firstName + ' ' + this.lastName;
}
}
})
</script>小结:
- 实现全名显示操作的三种方式:
- 常规做法:Mustache语法拼接的方式
- 封装成函数的方式,直接调用
- 采用计算属性的方式获取,直接采用属性名的方式就可以,简介易于理解
- 实现全名显示操作的三种方式:
3.3.2 计算属性的复杂操作
获取list中的书本总价格
- 这里使用到ES6中新的循环方式for in/of
1
2
3
4
5
6
7
8
9
10// ES6中新的操作
for (let i in this.books) {
// i为返回的索引
console.log(i);
console.log(this.books[i].price);
}
for (let book of this.books) {
// 返回的直接就是book对象
console.log(book);
}代码:
1 | <div id="app"> |
3.3.3 计算属性的setter和getter
getter和setter
每个计算属性都包含一个getter和一个setter
在上面的例子中,我们只是使用getter来读取。
在某些情况下,你也可以提供一个setter方法(不常用)
计算属性就是在computed的选项中定义的属性名称,
计算属性中的实现原理:
- get和set方法完整的写法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14computed选项中:
//计算属性fullName,后面跟着是一个对象,对象中存在get和set方法,所以在调用的时候采用的属性名的方式
fullName: {
set: function (newValue) {//set方法
console.log('----', newValue);
//设置set方法之后输出对应的值
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function () {//get方法
return this.firstName + ' ' + this.lastName
}
}- 一般情况下不设置set方法,计算属性都是只读的方式,代码如下:
1
2
3
4
5fullName: {
get: function () {
return this.firstName + ' ' + this.lastName
}
}- 在这种情况下可以直接省略计算属性后面的大括号和get:,直接写成如下形式
1
2
3fullName: function () {
return this.firstName + ' ' + this.lastName
}- 默认情况下都是调用的get方法,综上分析,computed中存放的都是计算属性而不是方法,调用直接调用属性名即可
比较computed中计算属性和methods中方法
二者都可以实现相同的功能,但是最终选择计算属性实现的原因是不同点
不同:
事件监听:用于用户交互,监听用户发生的时间,比如点击、拖拽、键盘事件等等
3.4.1 v-on基础使用
- 作用:绑定事件监听器
- 缩写:@
- 预期:Function | Inline Statement | Object
- 参数:event
- 代码实现:
1 | <div id="app"> |
3.4.2 v-on的参数问题
函数使用中,只有在点击监听事件的前提下,并且没有参数,才可以省略函数调用中的(),其他情况,方法的调用不能省略括号(包括mustche语法中,一般的类绑定中等)
参数分为三种情况
我们拿到event的目的可能是进行一些事件处理。
Vue提供了修饰符来帮助我们方便的处理一些事件
- .stop - 调用 event.stopPropagation()。
- .prevent - 调用 event.preventDefault()。
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
- .native - 监听组件根元素的原生事件。
- .once - 只触发一次回调。
代码:
1 | <div id="app"> |

3.5 条件判断
3.5.1 v-if、v-else-if、v-else
这三个指令与JavaScript的条件语句if、else、else if类似。
Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
v-if的原理:
v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
也就是根本没有不会有对应的标签出现在DOM中。
v-if/v-else指令演示代码:
1 | <h2 v-if="isShow"> |
- v-else-if指令
- 可以通过methods中定义方法的形式代替
1 | <div id="app"> |
3.5.2 v-show
- v-show的用法和v-if非常相似,也用于决定一个元素是否显示
1 | <div id="app"> |
v-if/v-show的区别
相同:二者都用于决定元素是否显示
不同
- v-show:通过css样式中的display属性,效率更高,标签使用多次的情况
- v-if:通过创建和删除标签来完成,标签使用一次的情况
3.5.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<div id="app">
<span v-if="isUser">
<label for="email">邮箱号码</label>
<input type="text" placeholder="请输入邮箱" id="email" key="email">
</span>
<span v-else>
<label for="phone">手机号码</label>
<input type="text" placeholder="请输入手机号" id="phone" key="phone">
</span>
<button @click='change'>切换登录</button>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
isUser: true
},
methods: {
change() {
this.isUser = !this.isUser
}
}
})
</script>存在的问题
- 在input标签中没有填加key属性时,如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容。
原因:虚拟DOM(Virtual DOM)(Vue底层页面渲染)
- 因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
解决方案:
- 如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
- 并且我们需要保证key的不同,此时检测到key的不同虚拟DOM中就不会进行复用
Vue底层页面的渲染
3.6 循环遍历
3.6.1 v-for
遍历数组
- 格式:
v-for="(item,index) in array"
1 | <!-- 获取数组的值 --> |
遍历对象
- 格式:
v-for="(value,key) in obj"
1 | <!-- 遍历对象的值 --> |
3.6.2 组件的key属性
官方推荐我们在使用v-for的时候添加key属性
- key属性的书写格式:
v-bind:key
->简写:key
这里进行动态的绑定
- key属性的书写格式:
使用key属性的原因:
- 和Vue的虚拟DOM的Diff算法有关系
当我们在列表中插入元素的时候(这里对数组中指定位置插入元素,直接操作的是数组中的splice方法)
不使用key的操作如下:
Diff算法默认的执行操作:C更新成F,D更新成C,E更新成D,最后再插入E,执行效率低
使用key的情况下:
使用key来给每个节点做一个唯一标识(这里的key最好和内容一一对应,这是唯一的)
Diff算法就可以正确的识别此节点,虚拟DOM直接在插入的位置插入,效率跟高
数组渲染之后在在中间插入元素的过程,在终端通过splice()数组方法啊操作数组,页面会实时进行更新,这是因为数据是响应式的
key的作用主要是为了高效的更新虚拟DOM
不要使用对象或数组之类的非基本类型值作为
v-for
的key
。请用字符串或数值类型的值。代码
1 | <ul> |
3.6.3 检测数组更新
- Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
- 并不是所有的数组中的方法都可以做到响应式(数组修改页面实时更新),哪些数组中的方法是可以做到响应式的
- Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。
- push():最后添加元素
- pop():最后删除元素
- shift():最前面添加元素
- unshift():最前面删除元素
- splice():删除指定位置的元素,删除个数为0时
- sort()
- reverse()
- 代码:
1 | //一 通过数组下标的方式是不能做到响应式的 |
3.7 阶段案例
图书馆案例
知识点总结:
价格保留两位小数:数字.fixed(num)
vue中过滤器的使用:通过|连接多个过滤器
- 过滤器可以用在两个地方:双花括号插值和
v-bind
表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
1
2
3
4
5<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>- 过滤器可以用在两个地方:双花括号插值和
绑定v-bind:disabled来使按钮失去点击(当购物车中数量小于1时)
代码:
3.8 v-model
作用主要用于表单的双向绑定
Vue中使用v-model指令来实现表单元素和数据的双向绑定,所以v-model会和不同类型的input标签进行绑定从而实现响应的功能
解析双向绑定
当我们在输入框输入内容时
因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
所以,通过v-model实现了双向的绑定。v-model
指令在表单<input>
,<textarea>
,<select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。v-model
会忽略所有表单元素的value
、checked
、selected
attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的data
选项中声明初始值。v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
- text 和 textarea 元素使用
3.8.1 v-model基本使用
- 格式:
v-model="data中的属性名称"
(data中的数组都是响应式的) - 双向数据:message数据和表单input绑定,改变其中一个另外一个也会改变
1 | <div id="app"> |
3.8.2 v-model实现原理
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
v-bind绑定一个value属性 数据->表单
v-on指令给当前元素绑定input事件 表单->数据
- 这里听过$event.target.value获取input事件对象event中输入的值($event可以在html标签中获取绑定事件中的event对象)
1
2
3<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!-- 1.v-model实现 -->
<input type="text" v-model='message'>
<!-- 2.v-bind和v-on:input事件绑定实现
- v-bind:绑定value,数据->表单
- v-on:input表单->数据
-->
<input type="text" :value='message' v-on:input='message=$event.target.value'>
<!-- 3.通过函数的方式实现(默认会在方法中传入event对象) -->
<input type="text" :value='message' @input='getValue'>
methods: {
getValue(event) {
console.log(event)
return event.target.value
}
}input事件中的event对象
3.8.3 v-model与input中不同type结合使用
v-model:radio
- v-model集合input中的radio类型使用
- radio是互斥选项,在表单提交过程中必须添加name属性且属性值必须相同,
- 在使用v-model且后面绑定相同的值也可以实现互斥选择,可不用name属性
1 | <!-- radio为互斥选项必须添加name属性且name属性的值相同 --> |
v-model:checkbox
v-model集合input中的checkbox类型使用
复选框分为两种情况:单个勾选框和多个勾选框
单个勾选框:v-model即为布尔值。此时input的value并不影响v-model的值。
多个复选框:
当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
当选中某一个时,就会将input的value添加到数组中。
复选框单选实现:通过借助data中的boolean变量实现
复选框多选实现:借助data中的数组实现,在v-model中使用相同的数组名,选择会自动添加到数组中
1 | <!-- 复选框单选实现 --> |
v-model:select
select也分单选和多选两种情况。
单选:只能选中一个值。v-model绑定的是一个值(字符串)。
当我们选中option中的一个时,会将它对应的value赋值到mySelect中
多选:可以选中多个值。这里需要给select添加multiple属性才能进行多选
v-model绑定的是一个数组。
当选中多个值时,就会将选中的option对应的value添加到数组中
1 | <!-- 单选实现 --> |
3.8.4值绑定
- 通过v-model进行绑定的时候,input标签中的value的值通过动态绑定v-bind实现,而不是写成固定值
- input标签和label标签最好一起使用,这样用户在点击文字的时候就可以选中
- 注意:要在标签中使用循环中的变量(响应式变量)必须通过动态绑定v-bind:才能使用(:id,:value)
1 | <!-- 值绑定:value中的值需要通过v-bind进行动态绑定v-bind,一般在使用input添加label标签 |
3.8.5修饰符
lazy修饰符:
默认情况下,v-model默认是在input事件中同步输入框的数据的。
也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
lazy修饰符可以让数据在失去焦点或者回车时才会更新:
number修饰符:
默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
number修饰符可以让在输入框中输入的内容自动转成数字类型:
trim修饰符:
如果输入的内容首尾有很多空格,通常我们希望将其去除
trim修饰符可以过滤内容左右两边的空格
代码:
1 | <!-- lazy失去焦点或者回车的时候进行响应 --> |
4.1 let/var
块级作用域
ES5中的变量var
- JS中使用var来声明变量,变量的作用域主要和函数的定义(变量在什么范围内可以使用)有关
- 针对其他的块定义来说是没有作用域的(for/if)
ES5中没有块级作用域造成的问题解决方案
- ES5之前因为if和for都没有块级作用域的概念, 所以在很多时候, 我们都必须借助于function的作用域来解决应用外面变量的问题.
- ES5中采用闭包的方式解决(函数是有作用域)
- ES6中引入变量let和const具有块级作用域,使for/if有了块级作用域
- ES5之前因为if和for都没有块级作用域的概念, 所以在很多时候, 我们都必须借助于function的作用域来解决应用外面变量的问题.
代码执行
1 | 1.没有块级作用域引起的问题:for的块级中,共用一个外部变量,没有块级作用域,外部就可以直接在修改内部的变量 |
4.2 const使用
使用const修饰的标识符为常量, 不可以再次赋值
应用场景:当我们修饰的标识符不会被再次赋值时, 就可以使用const来保证数据的安全性.
在ES6开发中优先使用const只有需要改变某一个标识符的时候才使用let.
注意事项:
一旦给const修饰的标识符被赋值之后, 不能修改
在使用const定义标识符,必须进行赋值
常量的含义是指向的对象不能修改, 但是可以改变对象内部的属性.
代码:
1 | const obj = { |
- 执行结果
4.3 ES6中对象字面量的增强写法
- 属性增强
1 | // 1.属性的增强写法(在属性名和属性值变量相同的情况下可以简写) |
- 函数增强写法
1 | 2.函数增强的写法(将:function省略) |
4.4 JS中高阶函数的使用
编程范式:
- 命令式编程/声明式编程
- 面向对象编程/函数式编程
JS中的高级函数编程
- 所谓的高级函数编程:(函数中嵌套函数):就是典型的函数式编程
- JS中高级函数的使用(可以进行链式编程),传递的参数都是回调函数
- map:对数组中的每个元素调用函数中的方法并返回一个新的数组,不会改变原数组,
- 返回值是一个表达式
- 格式:
数组.map(function(value){return 表达式})
- filter:过滤数组中的元素并返回满足条件的新的数组,不会改变原数组中的值
- 返回值是一个boolean值:true->填加到返回的新数组,false:函数内部会自动过滤这次的值
- 格式:
数组.filter(function(value){return boolean值})
- reduce:相当于累加器,返回最终的返回结果
- 格式:
数组.reduce(function(preValue,currentValue,currentIndex){return 数值}),initValue)
- preValue,currentValue,currentIndex->返回值,当前值,当前索引
- initValue:初始化值
- 返回值是一个数值,会被保存在preValue中
- 格式:
- map:对数组中的每个元素调用函数中的方法并返回一个新的数组,不会改变原数组,
- 代码实现
1 | /* |
reduce执行结果展示

注意:
Angular框架:2.0版本->typescript语言(微软开发)typescript是面向对象的编程,有多态等的概念
- react框架(谷歌开发)->js
目前也有人使用flow进行开发
后续学习中都会使用ES6进行代码的编写:
虽然浏览器不支持ES6但是可以通过在发布的时候使用工具转化为ES5
- for in/of循环的使用
本文链接: https://sparkparis.github.io/2020/05/04/Vue%E7%AC%94%E8%AE%B01/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!