写给女朋友的vue教程(二)

​ 怀着很悲痛的心情写下了这篇教程,4月份,两次冲刺项目延期,本组所有人,4月份绩效C。产品大哥不断改需求,不断添加需求,导致冲刺结束的前一天,需求文档还在被频繁改动,在加上需求评审,重要需求一笔带过,导致严重低估工作时间。然后就有C绩效。

​ 抱着随时被优化的态度,默默打开了vue.js文档,开始了这片文章。

怎么写?

​ 这段时间不定时的翻过几遍vue文档,大致总结了一下基础内容,和组件相关的内容,发现就算看了十遍,如果没有实际用到项目里面去也是白搭,文档里面的东西都太基础了,也是只简单的运用,所以基础部分就一篇写完,后面在整理核心内容。

​ 此时我也找前端小姐姐要到了前端项目组的代码地址,下载研究一波,在来实地考察一下vue怎么玩。

​ 好了,不说废话了,先来看看基础内容

基础

先来三个链接

这个是vue.js的API,里面介绍了API使用的方法,需要什么,就查什么,还有中文的,简直不要太方便

[]: https://cn.vuejs.org/v2/api/

这个是教程,基础的教程

[]: https://cn.vuejs.org/v2/guide/

这个就是风格指南了,类似于阿里巴巴开发规范,没事看看也挺好的,规范代码是很重要的

[]: https://cn.vuejs.org/v2/style-guide/

​ 其实我已经不知道说什么了,内容全部来自于上面三个文档,在说多了就是废话了,但是女朋友智力有限,看不懂上面的官方的话,所以我还是得废话一下说点通俗易懂的东西

开始

每个Vue应用都是要new Vue开始的

1
2
3
var vm = new Vue({
// 选项
})

Vue也是遵循了MVVM模型,即双向数据绑定,AngularJS也是这样,这个缩写的组成是 Model-View-ViewModel

简单点说就是视图和实体的数据是连通的,当实体的数据发生改变,视图上面绑定了这个实体的地方的内容也会相应改变

Vue实例生命周期
1
2
3
4
5
6
7
8
9
10
11
12
13
new Vue({
data: {
a: 1,
user:'zhangsang',
visible:false
},
created: function () {
// `this` 指向 vm 实例
// 这个匿名函数就去做你在创建这个实例的时候要做的事
// 比如你在页面开始的时候要调用ajax加载一些菜单数据,或者一些默认内容
console.log('a is: ' + this.a)
}
})

在这个new Vue实例里面data就相当于当前页面需要用到的数据,这个data可以封装成一个对象,或对应的json格式的数据,来满足业务的需要

created就是生命周期钩子,你可以理解为,一朵花,从苗到盛开到凋谢,这个created就可以理解为种下去苗的那一瞬间你要去浇水,施肥等等你想做的事情

这个就是Vue实例的生命周期图

用下面的代码来看看Vue的生命周期,这个代码直接新建一个txt的文档,把以下内容复制进去,后缀改成html就可运行,然后看控制台输出的内容

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
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
</head>
<body>

<div id="app">
<p>{{ message }}</p>
</div>

<script type="text/javascript">

var app = new Vue({
el: '#app',
data: {
message : "test1"
},
beforeCreate: function () {
console.group('beforeCreate 创建前状态===============》');
console.log("%c%s", "color:red" , "el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //undefined
console.log("%c%s", "color:red","message: " + this.message)
},
created: function () {
console.group('created 创建完毕状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //undefined
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeMount: function () {
console.group('beforeMount 挂载前状态===============》');
console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
mounted: function () {
console.group('mounted 挂载结束状态===============》');
console.log("%c%s", "color:red","el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data); //已被初始化
console.log("%c%s", "color:red","message: " + this.message); //已被初始化
},
beforeUpdate: function () {
console.group('beforeUpdate 更新前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
updated: function () {
console.group('updated 更新完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
beforeDestroy: function () {
console.group('beforeDestroy 销毁前状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message);
},
destroyed: function () {
console.group('destroyed 销毁完成状态===============》');
console.log("%c%s", "color:red","el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red","data : " + this.$data);
console.log("%c%s", "color:red","message: " + this.message)
}
})
</script>
</body>
</html>

可以看到在beforeCreate这个生命周期下,el和data都没有初始化,表示此时控件和data都没有加载

created表示完成了data的初始化,但是el控件还没加载上去

beforeMount表示控件和data都已经准备好了

mounted表示控件和data之间的关系已经全部加载上去了

一般在项目里面用mounted比较多,因为整个html模版已经渲染好,此时要做一些操作,就会更方便

在来看update当我在控制台里面修改message的值时,会调用beforeUpdate和update这两个生命周期钩子

destroy就是销毁了,销毁这个实例的生命周期,当执行了app.$destroy();的时候,我在去改变app.message的值,此时就不会打印update这里面的内容,表示此时这个页面内没有new Vue这个实例了

常用的语法

数据绑定

Mustache语法(双大括号)

在上文实例化Vue的时候,data里面的对象,此时就可以用到这里,当data里面的msg发生改变时,这个span标签里面的值也会改变

这里要注意:只有将实体属性放在实例化的data对象上,Vue才会对这个属性进行getter/setter转化,才能变成响应式的

1
2
3
4
5
6
7
8
9
10
var vm = new Vue({
data:{
a:1
}
})

// `vm.a` 是响应式的

vm.b = 2
// `vm.b` 是非响应式的
1
<span>Message: {{ msg }}</span>

使用JavaScript表达式,就相当于在双大括号里面去执行一些简单的运算表达式

1
2
3
4
5
6
7
{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>
指令

带有v-前缀的是特殊指令

直接来全部,就和后端语言里面的类似

v-if

if逻辑控制,双引号里面返回true或false,来控制p标签的插入或移除

1
<p v-if="seen">现在你看到我了</p>
v-else-if

else if逻辑判断,当if不生效会判断else if里面是否生效

1
2
3
4
5
6
7
8
9
10
11
12
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
v-else

和上面一样,当前者都不满足,则进入else代码块

上述逻辑运算可以用在一些条件控制上面,比如此时订单已经审核通过要求不显示驳回按钮,则可以判断订单状态是否通过

1
2
3
4
5
6
7
8
9
<div v-if="orderStarts===1">
驳回
</div>
<div v-if="orderStarts===2">
通过
</div>
<div v-if="orderStarts===0">
通过 驳回
</div>
v-show

这个指令其实和v-if类似,只不过v-show在加载的时候,元素始终会被渲染留在DOM中,只不过返回ture或false去控制他的display显示和隐藏

而v-if就不会,v-if是惰性的,当在渲染的时候,条件不符合,他直接就不加载这个元素了,而v-show是在渲染的时候就会被加载到dom上面,然后去控制他的display属性

1
<h1 v-show="ok">Hello!</h1>
列表渲染
v-for

v-for指令需要使用 item in items形式的特殊语法,items是源数据数组并且 item 是数组元素迭代的别名。

1
2
3
4
5
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
1
2
3
4
5
6
7
8
9
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

这个放在当有一个列表的情况,后台返回一个数组,比如返回几个平台供你选择,但是这个平台是动态的,后台返回给你,你用v-for渲染上去

当然v-for必须要支持双参数的,应为key-value,item则为value的值,index为key的值

1
2
3
4
5
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
1
2
3
4
5
6
7
8
9
10
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

v-on可以缩写成@

1
2
3
4
<div id="example-1">
<button @click="counter += 1">Add 1</button>
<p>The button above has been clicked {{ counter }} times.</p>
</div>
1
2
3
4
5
6
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
})

如果需要自定义方法去处理点击事件或者自定义一些方法需要在实例里面的methods去定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
// 在 `methods` 对象中定义方法
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
})

你就可以在@click=’greet’这样使用方法了,当然也可以直接example2.greet()去直接调用

表单控件

表单上面创建双向数据绑定使用v-model

v-model在不同的元素上面使用的时间和取的值都是不同的

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

这个表单控件的双向数据绑定,其实每个控件的模式都大同小可,他会自动帮你绑定上你定义的属性

总结

​ 上文都是一些基础的使用,没有很难的地方,在就是要踩坑了,用着用着就会忘记我上面写的东西,形成自己的印象,建议还是多翻官网文档比什么都好。

​ 接下来我会按照公司的vue前端项目来讲讲单文件组件,以及大型项目的构建

-------------本文结束感谢您的阅读-------------
0%