认识Vue

  1. 渐进式框架
  2. Core+Vue-router+Vuex 全家桶
  3. 特点:
  • 解耦视图和数据
  • 可复用的组件
  • 前端路由技术
  • 状态管理
  • 虚拟DOM

初识Vue

1
2
3
4
5
6
let app = new Vue({
el: '#app', // 挂载要管理的元素
data: { // 定义数据
message: '你好,世界'
}
})

简单计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<h2>当前计数:{{counter}}</h2>
<button @click="counter++">+</button>
<button @click="counter--">-</button>
</div>
<script src="./js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
counter: 0
}
})
</script>
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">
<h2>当前计数:{{counter}}</h2>
<!-- <button @click="counter++">+</button>
<button @click="counter--">-</button> -->
<button v-on:click="addNum">+</button>
<button v-on:click="subNum">-</button>
</div>
<script src="./js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
// mushache语法
data: {
counter: 0
},
methods: {
addNum: function() {
this.counter++;
},
subNum: function() {
this.counter--;
}
}
})
</script>

事件指令

v-once

  1. 只会在第一次的时候展示,只渲染一次
  2. 没有表达式

v-html和v-text

  1. 相当于innerHTML
  2. 相当于innerText 都会将标签中的内容覆盖

v-pre

  • 原文输出 不进行解析

v-bind

  1. 动态绑定class 使用v-bind:class或者:class
  2. class 里面可以写数组,对象,方法methods

计算属性的setter和getter

  1. 计算属性一般是没有set方法,只读属性
  2. 使用计算属性中的set方法必须设置参数

v-on

  1. 可以使用@ 代替v-on:
  2. 参数 不需要额外的参数小括号可以省略
  3. $event对象获取浏览器参数

修饰词

  1. 修饰符.stop阻止事件冒泡
  2. 阻止表单的默认提交事件.prevent
  3. 监听键盘的事件@keyup 监听键盘回车事件.enter
  4. .once只能执行一次
  5. .navice 监听组件的事件

v-if

  • 多个元素 通过条件判断展示或者隐藏某个元素. 或者多个元素
  • 进行两个视图之间的切换

条件渲染的问题

  1. 在渲染DOM时,会复用原来的DOM元素
  2. 使用key标识 会创建新的DOM元素

v-show

  • 元素隐藏 保留元素
  • 切换频率高时使用v-show

key的作用

  • 为了更高效的更新渲染虚拟DOM
  • diff算法

响应式问题

  • 可以做到响应式:push在数组中追加元素; pop()删除数组中的最后一个元素, shift()删除数组中的第一个元素 unshift() 在数组中最前面追加元素; splice()删除元素/插入元素/替换元素(关键在第二个参数); sort()排序; reverse()进行反转; Vue.set(修改的对象, 索引值, 要修改的元素)
  • 通过索引值修改数组中的元素 无法进行页面渲染
  • filters filters不会修改数据, 只是改变用户看到的输出(效果)

购物车案例

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
135
136
137
138
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图书购物车</title>
</head>
<style>
body {
padding: 0;
margin: 0;
box-sizing: border-box;
}

.table_warp {
padding: 20px;
}

table {
border: 1px solid #ccc;
border-right: 0;
border-bottom: 0;
border-spacing: 0;
}

thead {
background-color: rgb(246, 246, 246);
}

td,
th {
padding: 10px;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
}

button {
margin: 0 5px;
}
</style>

<body>
<div class="table_warp" id="app">
<h2>图书购物车</h2>
<div v-if="bookList.length">
<table>
<thead>
<th>
<td v-for="(item,index) in th_title">{{item}}</td>
</th>
</thead>
<tbody>
<tr v-for="(item,index) in bookList">
<td>{{index+1}}</td>
<td>{{item.name}}</td>
<td>{{item.datePublish}}</td>
<td>{{item.price*item.puNum| getPrice}}</td>
<td><button @click="item.puNum>1?item.puNum--:false">-</button>{{item.puNum}}<button @click="item.puNum++">+</button></td>
<td><button @click="removeBook(index)">移除</button></td>
</tr>
</tbody>
</table>
<div>总价格:{{totalPrice | getPrice}}</div>
</div>
<h3 v-else>购物车为空</h3>
</div>

</body>
<script src="./js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
th_title: ['书籍名称', '出版日期', '价格', '购买数量', '操作'],
bookList: [{
id: 0,
name: '《算法导论》',
datePublish: '2006-9',
price: 85.00,
puNum: 2
},
{
id: 1,
name: 'UNIX编程艺术',
datePublish: '2008-9',
price: 35.00,
puNum: 1
},
{
id: 2,
name: '《编程珠玑》',
datePublish: '2006-9',
price: 85.00,
puNum: 1
},
{
id: 3,
name: '《算法导论》',
datePublish: '2010-9',
price: 100.00,
puNum: 1
},
{
id: 4,
name: '《算法导论》',
datePublish: '2026-9',
price: 76.00,
puNum: 1
}
]
},
computed: {
// 计算总价格
totalPrice() {
return this.bookList.reduce((v, i) => v + i.price * i.puNum, 0)
}
},
methods: {
// 移除书籍
removeBook(index) {
this.bookList.splice(index, 1)
}
// getPrice(price) {
// return '¥' + price.toFixed(2)
// }
},
// 过滤器的使用
filters: {
getPrice(price) {
return '¥' + price.toFixed(2)
}
}
})
</script>

</html>

案例图

v-model

  • input双向绑定
  • radio使用时双向绑定 如果绑定的时相同的数据, name可以省略
  • selected 多个选择加入属性multiple
1
2
3
<!-- <input type="text" v-model='message'>{{message}}  使用v-model实现双向绑定 -->
<input type="text" :value="message" @input="message = $event.target.value">{{message}}
<!--使用input事件-->

修饰符

  • .lazy 失去焦点或者用户点击回车时指向
  • 默认情况传入的数据类型为string 使用修饰词.number 将数据类型转换成number
  • .trim 将空格去除

组件化开发

  • 拆分成一个一个的, 可复用的组件
    步骤
  • 创建组件构造器, 调用Vue.extend()方法
  • 注册组件 Vue.component()方法, 全局组件
  • 使用组件

components属性

  • 构建局部属性, 在Vue实例中

父组件和子组件

  • 组件和组件之间存在层级关系

父子组件的通信

  1. props属性 向子组件传递数据
  2. 自定义事件$emit 子传父

props传值类型

  • 可以使用对象方法传递, 或者数组
  • 在使用对象方法时, 可以给传递的参数设定数据类型String, Array, Object, Null, Undefined, Number, Symbol
  • 也可以给传递的参数设定默认值default, 设定改参数是否必须接受传值required, 也可以自定义验证函数validator
  • 如果设定的数据类型为对象或者数组时 设置默认值时必须从一个工厂函数获取default:function(){}es5, default(){}es6

子传父

  • 使用emit发送事件, 自定义事件

注册语法糖

  • Vue.component(组件标签名, {template}) 注册全局组件的语法糖
  • 局部注册组件在components{(组件标签名, {template})}

分离template方法

  1. 通过script类型text/x-template 通过id来获取模板
  2. 或者直接通过template标签

组件内data动态化实现

  • data类型不是对象类型, 而是函数类型, 在函数的返回值中定义数据data
  • data函数是为了使组件之间相互独立, 返回的数据 地址不相同