0%

第十一天

第十一天

JavaScript开源框架

Jquery、ExtJS、Dojo、vue.js

JS MV*模式

MVC(模式-视图-控制器)、MVP(模型-视图-表示器)、MVVM(模型-视图-视图模型)

MVC

MVC全名是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写。MVC一般用于表现层(Web)开发。

表现层--对应JavaWeb中JSP层

mvc模式图
mvc模式图

MVP

MVP是一种过渡模式,全称是Model-View-Presenter,Model提供数据,View负责显示,Presenter负责逻辑的处理。

MVVM

MVVM是一种基于MVC和MVP的架构模式,全称是Model-View-ViewModel,其中可以将ViewModel看成一个专门的Controller,充当数据转换器,它将Model信息转变成View信息,还将命令从View传递到Model。因此,很多这种模式的实现都要利用声明式数据绑定来实现将View工作从其它层分离。

mvvm模式图
mvvm模式图

MVC与MVVM的区别

mvc+mvvm
mvc+mvvm
  • MVC是后端的分层开发的概念
  • MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层分为了三部分Model、View、VM(ViewModel)

单页Web应用程序(SPA)

只有一张Web页面的应用,通过改变该页的数据和样式修改页面,提高效率。

Vue.js

  • Vue.js是一个JavaScript的MVVM库,是一套构建用户界面的渐进式框架。它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计。
  • Vue.js是目前最火的一个框架,Recat是最流行的一个框架(React除了开发网站,还可以开发手机App,Vue语法上也可以用于App开发,需要借助于Weex)。
  • Vue.js是前端的主流框架之一,和Angular.js、React.js一起,并成为前端三大主流框架!
  • Vue.js是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。

Vue特点

  1. 轻量级的框架
  2. 双向数据绑定
  3. 指令
  4. 插件化

框架和库的区别

  • 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则重新架构整个项目。
  • 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。

display和visibility区别

display:none隐藏后不占空间 visibility:hidden隐藏后会占用空间

Vue基础

Vue基础

  1. 如何定义一个基本Vue代码结构
  2. 插值表达式和v-text
  3. v-cloak
  4. v-html
  5. v-bind Vue提供的属性绑定机制,缩写是 :属性
  6. v-on 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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue的基本代码</title>
<!-- 1. 导入vue.js -->
<script src="./js/vue.js"></script>
</head>

<body>
<!-- Vue 实例所控制的这个元素区域,就是V -->
<!-- 将来new的Vue实例,会控制这个元素中的所有内容 -->
<div id="app">
<p>{{msg}}</p>
</div>


<script>
// new出来的这个vm对象, 就是mvvm中的VM调度者
// 2. 创建一个Vue的实例
// 当我们导入包后, 在浏览器内存中, 就多了一个Vue构造函数
var vm = new Vue({
//element,表示当前我们new的这个vue实例,要控制页面上的哪个区域,值是一个选择器
el: "#app",
// data就是MVVM中的M,专门用来保存每个页面的数据
// data属性中,存放的是el中要用到的数据
data: {
// 通过vue提供的指令,很方便的就能把数据渲染到页面上,程序员不再手动操作DOM元素了【前端的vue之类的框架,不提倡我们去手动操作DOM元素】
msg: "welcome to vue!"
}
})
</script>
</body>

</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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-cloak、v-text、v-html、v-on的学习</title>
<script src="./js/vue.js"></script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>

<body>
<div id="app">
<!-- 使用v-cloak能够解决插值表达式闪烁的问题 -->
<p v-cloak>++++++{{msg}}--------</p> <!-- 有+和- -->
<!-- 默认v-text是没有闪烁问题的 -->
<!-- v-text会覆盖元素中原本的内容,但插值表达式只会替换自己的占位符,不会把整个元素的内容清空 -->
<h4 v-text="msg">=======</h4><!-- 无= -->

<div>{{msg2}}</div>
<div v-text="msg2"></div>
<div v-html="msg2"></div>

<!-- v-bind:是vue中提供的用于绑定属性的指令 -->
<!-- <input type="button" value="按钮" v-bind:title="mytitle+'123'"> -->
<!-- v-bind可以被简写为: :要绑定的属性 -->
<!-- v-bind中可以写合法的JS表达式,如'123' -->
<input type="button" value="按钮" :title="mytitle+'123'">

<!-- vue中提供了v-on:事件绑定机制 -->
<!-- <input type="button" value="按钮" v-on:click="alert('hello')">alert()报错 -->
<!-- <input type="button" value="按钮" v-on:click="show"> -->
<input type="button" value="按钮" @click="show">

</div>
<script>
new Vue({
el: "#app",
data: {
msg: "123",
msg2: "<h1>标题<h1>",
mytitle: "这是一个title"
},
//methods 属性中定义了当前vue实例中所有可用的方法
methods: {
show: function () {
alert("Hello");
}
}
})
</script>

</body>

</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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>跑马灯效果</title>
<script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<input type="button" value="浪起来" @click="lang">
<input type="button" value="低调" @click="stop">
<h4>{{msg}}</h4>
</div>
<script>
// 注意: 在VM实例中, 如果想要获取data上的数据, 或者想要调用methods中的方法, 必须通过this.数据属性名 或 this.方法名 来进行访问,这里的this就表示new出来的VM实例对象
var vm = new Vue({
el: "#app",
data: {
msg: "猥琐发育,别浪~~!",
intervalId: null // 在data上定义定时器ID
},
methods: {
// VM实例, 会监听自己身上的data中所有数据的改变,只要数据发生变化,就会自动把新的数据,从data上同步到页面中去
// es6新写法
lang() {
// 箭头函数内部的this和外部的this保持一致
if (this.intervalId != null) return;
this.intervalId = setInterval(() => {
var start = this.msg.substring(0, 1); //获取到头的第一个字符
var end = this.msg.substring(1); //获取后面的所有字符
this.msg = end + start; //重新拼得到新的字符串,并赋值给this.msg
}, 400)
},
stop() {
clearInterval(this.intervalId);
this.intervalId = null;
}
}
})
// 分析:
// 1. 给[浪起来] 按钮, 绑定一个点击事件 v - on @
// 2. 在按钮的事件处理函数中,写相关的业务逻辑代码:拿到msg字符串,然后调用字符串的substring来进行字符串的截取操作,把第一个字符截取出来,放到最后一个位置
// 3. 为了实现点击一下按钮, 自动截取的功能, 需要所2步骤中的代码, 放到一个定时器中
</script>
</body>

</html>

v-on 事件修饰符

  • .stop 阻止冒泡
  • .prevent 阻止默认事件
  • .capture 添加事件侦听器使用事件捕获模式
  • .self只当事件在该元素本身(比如不是子元素)触发时触发回调
  • .once 事件只触发一次
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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>事件修饰符</title>
<script src="./js/vue.js"></script>
<style>
.inner {
height: 150px;
background-color: darkcyan;
}

.outer {
background-color: red;
}
</style>
</head>

<body>
<div id="app">
<!-- <div class="inner" @click="divHandler">
使用.stop 阻止冒泡
<input type="button" value="戳它" @click.stop="btnHandler">
</div> -->
<!-- 使用.prevent 阻止默认行为
<a href="http://www.baidu.com" @click.prevent="linkClick">百度</a> -->

<!-- 使用.capture 捕获机制,与冒泡相反,从外到里执行
<div class="inner" @click.capture="divHandler">
<input type="button" value="戳它" @click="btnHandler">
</div> -->

<!-- 使用.self 实现只有点击当前元素时,都会触发事件处理函数,其它捕获、冒泡情况均不执行
<div class="inner" @click.self="divHandler">
<input type="button" value="戳它" @click="btnHandler">
</div> -->

<!-- 通过.once 只触发一次事件处理函数 -->
<!-- <a href="http://www.baidu.com" @click.prevent.once="linkClick">百度</a> -->

<!-- .stop 和 .self的区别 -->
<!-- <div class="outer" @click="divHandler">
<div class="inner" @click="divHandler">
<input type="button" value="戳它" @click.stop="btnHandler">
</div>
</div> -->
<!-- .self 只阻止自己冒泡行为的触发,并不会阻止其它冒泡行为 -->
<div class="outer" @click="divHandler">
<div class="inner" @click.self="divHandler">
<input type="button" value="戳它" @click.stop="btnHandler">
</div>
</div>


</div>
<script>
var vm = new Vue({
el: "#app",
data: {},
methods: {
divHandler() {
console.log("这是触发了inner div的点击事件")
},
btnHandler() {
console.log("这是触发了btn的点击事件")
},
linkClick() {
console.log("触发了链接的点击事件");
}
div2Handler() {
console.log("这是触发了outer div的点击事件");
}
}
});
</script>
</body>

</html>

Vue指令之v-model和双向数据绑定

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">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-model</title>
<script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<h4>{{msg}}</h4>
<!-- v-bind 只能实现数据的单向绑定,从M自动绑定到V,无法实现数据的双向绑定 -->
<!-- <input type="text" v-bind:value="msg"> -->

<!-- 使用v-model 指令,可以实现表单元素和Model中数据的双向绑定 -->
<!-- 注:v-model 只能运用在表单元素中(input(radio、text、address、email...)、select、checkbox、textarea) -->
<input type="text" v-model="msg">
</div>
<script>
var vm = new Vue({
el: " #app",
data: {
msg: "Hello word"
},
methods: {}
})
</script>
</body>

</html>

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue中的样式</title>
<script src="./js/vue.js"></script>
<style>
.red {
color: red;
}

.thin {
font-weight: 200;
}

.italic {
font-style: italic;
}

.active {
letter-spacing: 0.5em;
}
</style>
</head>

<body>
<div id="app">
<!-- 第一种使用方式,直接传递一个数组,注意:这里的class需要使用v-bind做数据绑定
<h1 :class="['thin','italic']">这是一个h1</h1> -->
<!-- 在数组中使用三元表达式 -->
<!-- <h1 :class="['thin','italic',flag?'active':'']">这是一个h1</h1> -->
<!-- 在数组中使用对象代替三元表达式,提高代码可读性 -->
<!-- <h1 :class="['thin','italic',{'active':flag}]">这是一个h1</h1> -->
<!-- 在为class使用v-bind绑定对象时,对象的属性是类名,由于对象的属性可带引号,也可不带引号;属性的值是一个标识符 -->
<!-- <h1 :class="{red:true,thin:true,italic:false,active:false}">这是一个h1</h1> -->
<h1 :class="classObj">这是一个h1</h1>

</div>
<script>
var vm = new Vue({
el: " #app",
data: {
flag: true,
classObj: {
red: true,
thin: true,
italic: false,
active: false
}
}
})
</script>
</body>

</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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue中的样式-style</title>
<script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<!-- 对象就是无序键值对的集合 -->
<!-- <h1 :style="{color:'red','font-weight':200}">这是一个h1</h1> -->
<!-- <h1 :style="styleObj1">这是一个h1</h1> -->

<h1 :style="[styleObj1,styleObj2]">这是一个h1</h1>

</div>
<script>
var vm = new Vue({
el: "#app",
data: {
styleObj1: {
color: 'red',
'font-weight': 200
},
styleObj2: {
'font-style': 'italic'
}
}
})
</script>
</body>

</html>

v-for

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-for循环</title>
<script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<!-- 循环普通数组 -->
<!-- <p>{{list[0]}}</p>
<p>{{list[1]}}</p> -->
<!-- <p v-for="item in list">{{item}}</p> -->
<!-- <p v-for="(item,i) in list">索引值:{{i}}---值:{{item}}</p> -->

<!-- 循环对象数组 -->
<!-- <p v-for="(user,i) in list1">
ID:{{user.id}}---Name:{{user.name}}---索引:{{i}}
</p> -->

<!-- 循环对象 -->
<!-- 注意:在遍历对象身上的键值对时,除了有val key,在第三个位置还有一个索引 -->
<!-- <p v-for="(val,key,i) in user">
值:{{val}}---键:{{key}}---索引:{{i}}
</p> -->

<!-- 迭代数字 -->
<!-- in 后面可以放普通数组、对象数组、对象、数字 -->
<!-- count从1开始 -->
<!-- <p v-for="count in 10">这是第{{count}}次循环</p> -->

<!-- v-for循环中key属性的使用 -->
<div>
<label for="">ID: <input type="text" v-model="id"></label>
<label for="">Name: <input type="text" v-model="name"></label>
<input type="button" value="添加" @click="add">
</div>
<!-- 注意:v-for 循环时,key属性只能使用number或string -->
<!-- 注意:key在使用时,必须使用v-bind 属性绑定的形式指定key的值 -->
<!-- 不用key的话用unshift时会出现bug -->
<!-- 在组件中,使用v-for循环时,或在一些特殊情况中,如果v-for有问题,必须在使用v-for的同时,指定唯一的字符串/数字类型的 :key值 -->
<p v-for="item in list1" :key="item.id">
<input type="checkbox" name="" id="">{{item.id}}---{{item.name}}
</p>
</div>
<script>
var vue = new Vue({
el: "#app",
data: {
id: "",
name: "",
list: [1, 2, 3, 4, 5, 6],
list1: [{
id: 1,
name: 'zs'
},
{
id: 2,
name: 'ls'
},
{
id: 3,
name: 'ww'
}
],
user: {
id: 1,
name: "zs",
gender: "男"
}
},
methods: {
add() {
this.list1.unshift({
id: this.id,
name: this.name
})
}
}
})
</script>
</body>

</html>

v-if和v-show

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-if和v-show的使用</title>
<script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<!-- <input type="button" value="toggle" @click="toggle"> -->
<input type="button" value="toggle" @click="flag=!flag">
<!-- v-if的特点:每次都会重新删除或创建元素 -->
<!-- v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none样式 -->
<!-- v-if 有较高的切换性能消耗 -->
<!-- v-show 有较高的初始渲染消耗 -->
<!-- 如果元素涉及到频繁的切换,最后不要使用v-if,而是推荐使用v-show -->
<!-- 如果元素可能永远也不会被显示出来被用户看到,则推荐使用v-if -->
<h3 v-if="flag">这是用v-if控制的元素</h3>
<h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
flag: true
},
methods: {
// toggle() {
// this.flag = !this.flag;
// }
}
})
</script>
</body>

</html>

总结

  1. MVC和MVVM的区别
  2. 学习了Vue中最基本的代码结构
  3. 插值表达式 v-cloak v-text v-html v-bind(缩写是:) v-on(缩写是@) v-model v-for v-if v-show
  4. 事件修饰符: .stop .prevent .cature .self .once
  5. el 指定要控制的区域 data是个对象,指定了控制的区域内要用到的数据 methods 虽然带个s后缀,但是是个对象,这里可以自定义方法
  6. 在VM实例中,如果要访问data上的数据,或者要访问methods中的方法,必须带this
  7. 在v-for 要会使用key属性(只接收string/number)
  8. v-model 只能应用于表单元素
  9. 在vue中绑定样式两种方式:v-bind:class v-bind:style