前言:Vue.js 是一套构建用户界面的框架,**只关注视图层**,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
+ 前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
## 为什么要学习流行框架
+ 企业为了提高开发效率:在企业中,时间就是效率,效率就是金钱;
- 企业中,使用框架,能够提高开发的效率;
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<!--<input type="button" value="点我切换" @click="toggle"/>-->
<input type="button" value="点我切换" @click="flage=!flage"/>
<!--v-if每次都会重新删除或创建元素-->
<!--v-show每次不会进行DOM的删除操作和创建操作,只是切换display:none-->
<!--v-if有较高的切换性能消耗-->
<!--v-show有较高的初始渲染消耗-->
<h3 v-if="flage">v-if控制的元素</h3>
<h3 v-show="flage">v-show控制的元素</h3>
</div>
</body>
<script>
var vm = new Vue({
el: ".app",
data: {
flage: true
},
methods: {
// toggle()
// {
// this.flage = !this.flage;
// }
}
})
</script>
</html>
+ 提高开发效率的发展历程:原生JS -> Jquery之类的类库(主要解决兼容性) -> 前端模板引擎(解决频繁操作dom,只需要调魔板引擎,就会帮我们渲染到页面,到现在好像止步了,其实不然!当你修改几个数据,魔板引擎会重新渲染,但是当数据多了的时候,,只修改几条数据,模板引擎就要全部重新渲染,涉及到浏览器的重绘和重排,这时候就很消耗浏览器性能了) -> Angular.js / Vue.js(能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念(v-model)【通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心DOM是如何渲染的了】这也是第一天要学的)
+ 在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑;
+ 增强自己就业时候的竞争力
- 人无我有,人有我优
- 你平时不忙的时候,都在干嘛?
## 框架和库的区别
+ 框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目。
- node 中的 express;
+ 库(插件):提供某一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求。
- 1. 从Jquery 切换到 Zepto
- 2. 从 EJS 切换到 art-template
举个例子:你给了库5元,叫他买酱油,你得告诉他怎么走,买多少,应该找回多少钱,每一步都要告诉他!
但是框架就不一样,你给钱,告诉他,买酱油,他就给你买回来
## Node(后端)中的 MVC 与 前端中的 MVVM 之间的区别
+ MVC 是后端的分层开发概念;
+ MVVM是前端视图层的概念,主要关注于 视图层分离,也就是说:MVVM把前端的视图层,分为了 三部分 M,V和VM,期中VM是MVVM的核心,因为VM是V和M之间的调度者。前端页面提供MVVM的思想,主要是让我们更方便的开发,因为MVVM提供了数据的双向绑定,注意数据的双向绑定是有VM提供的
+ 为什么有了MVC还要有MVVM(逻辑,视图)
## Vue.js 基本代码 结构和 MVVM 之间的对应关系
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
<!--将来vue的实例会控制这个元素的所有内容-->
<!--vue所控制的这个区域就是V层-->
<div id="app">
<p>{{msg}}</p>
</div>
</body>
<script>
// 2:创建一个vue实例
//当我们导入包之后,就在浏览器内存中多了一个Vue的构造函数
//我们new出来的这个vm对象,就是mvvm中的vm调度者
var vm = new Vue({
el: '#app',//表示我们当前new出来的实例,要控制页面那个区域
// 这里的data就是mvvm中的m。专门用来保存每个页面的数据
data: { //data属性中就是el要用到的数据
msg: '欢迎学习vue' //通过vue指令,很方便就能把数据渲染到页面上 ,程序员不在动手操作DOM元素了
}
})
</script>
</html>
## `插值表达式`、`v-clock`
插值表达式就是标签中间的内容通过{{}}的形式展现出来,v-cloak主要解决表达式闪烁的问题(插值表达式先出来,但是换没有渲染(vue包换在加载),这时候称之为闪烁)
## Vue指令之`v-text`和`v-html`
## Vue指令之`v-bind`的三种用法
1. 直接使用指令`v-bind`
2. 使用简化指令`:`
3. 在绑定的时候,拼接绑定内容:`:title="btnTitle + ', 这是追加的内容'"`
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div class="app">
<!--v-clock能够解决差值表达式闪烁的问题-->
<!--默认v-text没有闪烁,但是会覆盖插值表达式-->
<!--v-html输出html格式,但是会覆盖插值表达式-->
<!--v-bind:是vue提供用于绑定属性的指令-->
<!--v-bind:可以简写为:要绑定的属性-->
<!--可以写合法的js表达式-->
<!-- //插值表达式-->
<p v-cloak>{{msg}}</p>
<!-- //属性的方法-->
<h4 v-text="msg"></h4>
<div v-html="msg2"></div>
<!--<input type="button" value="按钮" v-bind:title="mytitle+'456'"/>-->
<input type="button" value="按钮" :title="mytitle+'46'"/>
<!--vue提供了v-on:事件绑定机制-->
<input type="button" value="弹框" v-on:click="show"/>
</div>
<script src="lib/vue-2.4.0.js"></script>
<script>
var vm = new Vue({
el: ".app",
data: {
msg: "123",
msg2: "<h1>大家好</h1>",
mytitle: "大家好123",
},
methods: {
show: function () {
alert('大家伙0')
},
}
})
</script>
</body>
</html>
跑马灯案例:
1:用到了数据绑定,这个是单单项的数据绑定{{}},
2: 点击事件 v-on:click="" 简写@click=""
3:箭头函数(改变this指向)
4:定时器的节流阀
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<input type="button" value="跑" v-on:click="run">
<input type="button" value="停" @click="stop">
<br>
<p>{{msg}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
msg: "跑起来跑起来跑起来跑起来跑起来",
timeId: null
},
methods: {
run() {
// 如果定时器不是空,就返回,中断,这也就起到一个很好的节流阀作用,不能重复点击
if (this.timeId != null) return
// this写在定时器里面,this指向就是定时器,但是我们想要的结果是,this是data里面的msg,
//所以箭头函数很好的解决了这个问题将functi(){}变为=>{}
this.timeId = setInterval(() => {
// 切割msg开头第一个汉子(从第0个开始,切割一个)
var start = this.msg.substring(0, 1)
// 除了第一个之外的所有汉字
var end = this.msg.substring(1)
// 将开始和结束进行拼接,字是一大坨的动,所以是后面的字,一个一个蹦出来,最后拼接开始
//将值重新赋值给msg this.mag = ""
this.msg = end + start
}, 400)
},
stop() {
// 清除定时器
clearInterval(this.timeId);
// 将timeId设置为null,方便下次再用
this.timeId = null
}
}
})
</script>
</html>
## Vue指令之`v-on的缩写`和`事件修饰符`
### 事件修饰符:
+ .stop 阻止冒泡
+ .prevent 阻止默认事件
+ .capture 添加事件侦听器时使用事件捕获模式
+ .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
+ .once 事件只触发一次
事件修饰符可以混合嵌套使用,看具体要实现的功能
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="lib/vue-2.4.0.js"></script>
<style>
.inner {
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div class="app">
<!--事件冒泡:存在嵌套关系,并且具有相同 的事件-->
<!--使用.stop阻止冒泡(全部)-->
<div class="inner" @click="inner">
<input type="button" value="点饿哦" class="btn" @click.stop="btn"/>
</div>
<!-- .cupture实现事件捕获,由外向内,本来是点击按钮,先触发按钮的事件,但是加了capture修饰符,就是先输出capture的内容。
一开始认为这是没有意义的,但是默认存在嵌套关系,并且具有相同的事件,这个时候默认是事件冒泡,但是加了capture之后就成了捕获,也唤醒-->
<!-- <div class="inner" @click.capture="inner">-->
<!-- <input type="button" value="点饿哦" class="btn" @click="btn"/>-->
<!-- </div>-->
<!--.self实现只有点击当前元素(自己),才会触发-->
<!-- 个人认为这个事件修饰符,比较好,点谁就是谁-->
<!-- <div class="inner" @click.self="inner">-->
<!-- <input type="button" value="点饿哦" class="btn" @click="btn"/>-->
<!-- </div>-->
<!-- 阻止默认事件-->
<!-- <a href="https://www.baidu.com" @click.prevent="cli">点我</a>-->
<!--使用.once只触发一次事件-->
<!-- <a href="https://www.baidu.com" @click.prevent.once="cli">点我</a>-->
</div>
</body>
<script>
var vue = new Vue({
el: ".app",
data: {},
methods: {
inner() {
console.log("我是inner")
},
btn() {
console.log("大家伙,我是按钮")
},
cli() {
console.log("跳转")
}
}
})
</script>
</html>
## Vue指令之`v-model`和`双向数据绑定`
注意:数据的双向绑定是通过指令v-model来实现,而且实现数据的双向绑定必须是(v-model和表单中的数据进行双向绑定)
<!--input(radio,text,address,email) select,checkbox,texares,-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<h3>{{msg}}</h3>
<input type="text" v-model="msg" style="width: 100%">
</div>
</body>
<script>
var vm = new Vue({
el: ".app",
data: {
msg: "大家好"
},
methods: {}
})
</script>
</html>
利用数据的双向绑定来实现一个简易计算器
注意点:实现简单计算器主要是利用到数据的双向绑定,当数据改变的时候,数据层会实时监控数据的变化,这样才能实现输入什么,加方法,再输出什么
表单的数据双向绑定,data里面要对数据进行初始化,用数据的时候,通过this来用
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<input type="text" v-model="start">
<select name="计算器" id="" v-model="mid">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model="end">
<input type="button" value="等于" @click="add">=
<input type="text" v-model="res">
</div>
</body>
<script>
var vm = new Vue({
el: ".app",
data: {
start: '',
mid: '+',
end: '',
res: ''
},
methods: {
add() {
// switch (this.mid) {
// case '+' :
// this.res = parseInt(this.start) + parseInt(this.end)
// break;
// case '-' :
// this.res = parseInt(this.start) - parseInt(this.end)
// break;
// case '*' :
// this.res = parseInt(this.start) * parseInt(this.end)
// break;
// case '/' :
// this.res = parseInt(this.start) / parseInt(this.end)
// break;
// }
// 简单方式
var codeStr = 'parseInt(this.start) ' + this.mid + ' parseInt(this.end)'
this.res = eval(codeStr);
}
}
})
</script>
</html>
for循环普通数组
注意:既然是循环肯定是v-for指令
v-for="item in 数组名" {{item}}//数组里面的每一项
for循环数组对象 {{item.属性}}
for循环对象
(key,value,i) in 对象名 {{value}}---{{key}}
for迭代数字
v-for="count in 10" {{count}} 从1开始
for循环中key的使用
v-for在循环的时候,同时制定唯一的字符串/数字类型来做唯一标识
省的自己换要定义i索引值
案例 v-for ,v-model ,:key 的混合使用
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="../lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<!-- label标签,他为鼠标用户改进了鼠标可用性,只要是在label里面点击文本,就会触发控件-->
<label for="">
NAme:
<input type="text" v-model="name">
<!-- 双向数据绑定到name,id上面,当文本框的数据发生变化,下面的数据也会发生变化-->
</label>
<label for="">
id:
<input type="text" v-model="id">
</label>
<input type="button" value="add" @click="add">
<p v-for="item in list">
<!-- //数组对象,item.属性-->
<input type="checkbox" name="" id=""> {{item.id}}{{item.name}}
</p>
</div>
</body>
<script>
var vm = new Vue({
el: ".app",
data: {
name: '',
id: '',
list: [
{
name: '哈哈',
id: 1
},
{
name: '哈哈',
id: 2
}
]
},
methods: {
// 用unshift来添加到数组对象的头部,({}),外面是方法的(),里面用对象接收
add() {
this.list.unshift({name: this.name, id: this.id})
}
}
})
</script>
</html>
v-show和 v-if的使用
注意:
都是控制元素的显示影藏
但是v-if每次消失影藏都会重新创建,
v-show只是dislay:none
切换显示影藏只是显示flage的值不同,那么就可以每次取反,也可以达到效果
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="lib/vue-2.4.0.js"></script>
</head>
<body>
<div class="app">
<!--<input type="button" value="点我切换" @click="toggle"/>-->
<input type="button" value="点我切换" @click="flage=!flage"/>
<!--v-if每次都会重新删除或创建元素-->
<!--v-show每次不会进行DOM的删除操作和创建操作,只是切换display:none-->
<!--v-if有较高的切换性能消耗-->
<!--v-show有较高的初始渲染消耗-->
<h3 v-if="flage">v-if控制的元素</h3>
<h3 v-show="flage">v-show控制的元素</h3>
</div>
</body>
<script>
var vm = new Vue({
el: ".app",
data: {
flage: true
},
methods: {
// toggle()
// {
// this.flage = !this.flage;
// }
}
})
</script>
</html>
总结:
1:MVC 和MVVM的区别
2:差值表达式: v-bloak ,v-text ,v-html , v-if,v-for ,v-show, v-model ,v-bind(:) ,v-on(@) v-
3:事件修饰符: .stop .prevent,.capture,.once,.self
5:el :要控制的区域 data:是个对象,指定了控制区域用到的数据,mothods:自定义方法
6:在VM中,如果要访问data上面的数据,methods里面的方法,要加this
7:v-for要回使用:key属性(只接受String/number)
8:v-model只能应用于表单元素
9:在vue中绑定样式的两种方法,v-model:class ,v-bind:style