1、什么是vue.js
2、为什么要学习前端的流行框架
3、框架和库的区别
4、后端MVC和前端的MVVM的区别
5、vue.js的基本代码--hollo world代码
6、v-cloak、v-text、v-html指令的基本使用
7、v-bind指令
8、使用v-on指令定义Vue中的事件
9、跑马灯效果制作
10、事件修饰符
11、讲解v-model实现【表单元素】的数据双向绑定
12、案例:v-model实现计算器
13、vue中通过属性绑定为元素设置class类样式
14、vue中通过属性绑定为元素绑定style行内样式
15、v-for指令的四种使用方式
16、v-for中key的使用注意事项
17、v-if和v-show的使用和特点
1、什么是vue.js <--返回目录
vue.js是目前最火的一个前端框架,React是最流行的一个前端框架(React除了可以开发网站,还可以开发手机App)。vue.js语法也可以开发手机App,需要借助weex。
vue.js和Angular.js、React.js一起并称为前端三大主流框架。
vue.js是一套构建用户界面的框架。只关注视图层。它不仅易于上手,还便于与第三方库或既有项目整合。vue.js有配套的第三方类库,可以整合起来做大型项目的开发。
前端的主要工作?主要负责MVC(模型-视图-控制器)中V的这一层,主要工作就是和界面打交道,来制作前端页面效果。
2、为什么要学习前端的流行框架 <--返回目录
提高开发效率的发展历程:原生JS --> jquery之类的类库 --> 前端模板引擎 --> angular.js / vue.js
- 能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念
- 在vue.js中,一个核心的概念,就是让用户不再操作DOM元素
3、框架和库的区别 <--返回目录
框架:是一套完整的解决方案;对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目
库(插件):提供一个小功能,对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求。
- 比如,从jquery切换到zepto
- 模板引擎从EJS切换到art-template
4、后端MVC和前端的MVVM的区别 <--返回目录
MVC是后端的分层开发的概念
MVVM是前端视图层的概念,主要关注于视图层分离,也就是说,MVVM把前端的视图层分为了三部分。Model, View, VM ViewModel调度者
5、vue.js的基本代码--hollo world代码 <--返回目录
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <style type="text/css"> div { width: 200px; height: 200px; background-color: #ccc; } </style> </head> <body> <div id="app"> <p>{{ msg }}</p> </div> <script type="text/javascript"> // 创建一个vue实例 // 当我们导入vue包后,在浏览器内存中,就有一个vue构造函数 var vm = new Vue({ el: '#app', // 当前我们new的Vue实例要控制页面的哪个元素 data: { // 存放el中要用到的数据 msg: 'hello vue' // 通过vue提供的指令,很方便地把数据渲染到页面上,程序员不再手动操作DOM元素 } }); </script> </body> </html>
6、v-cloak、v-text、v-html指令的基本使用 <--返回目录
这三个指令都是用来绑定渲染文本数据的
1)v-cloak指令:能够解决插值表达式闪烁的问题
[v-cloak] { display: none; } <!-- 使用v-cloak指令:能够解决插值表达式闪烁的问题 --> <p v-cloak>+++{{ msg }}+++</p>
2)<h4 v-text="msg"></h4> 是没有闪烁问题
<h4 v-text="msg">原来的文本 <!-- 这里的文本会被msg替换 --> </h4>
3) v-html将数据以html代码执行
4)插值表达式和v-text区别?不同的使用场景
- v-text:标签里面的文本全部被替换
- 插值表达式:{{ 变量 }}被替换,{{ 变量 }}外面如果有文本,不会被替换
代码:
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 300px; /*height: 200px;*/ background-color: #ccc; } [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <!-- 使用v-cloak指令 能够解决插值表达式闪烁的问题 --> <p v-cloak>+++{{ msg }}+++</p> <!-- v-text没有闪烁问题 --> <h4 v-text="msg">原来的文本 <!-- 这里的文本会被msg替换 --> </h4> <div>{{ msg2 }}</div> <div v-text="msg2"></div> <div v-html="msg2"></div> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: 'hello vue', msg2: '<h1>我是一个h1标签</h1>' } }); </script> </body> </html>
7、v-bind指令 <--返回目录
v-bind:是vue中提供的用于绑定属性的指令
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 200px; height: 200px; background-color: #ccc; } </style> </head> <body> <div id="app"> <!-- v-bind:是vue中提供的用于绑定属性的指令, ""里面的代码被作为js表达式代码, v-bind:可以简写为":" --> <!--<input type="button" value="按钮" v-bind:title="mytitle + '123'"> --> <input type="button" :value="'我的' + mybtn" :title="mytitle + '123'"> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { mytitle: "标题", mybtn:"按钮" } }); </script> </body> </html>
8、使用v-on指令定义Vue中的事件 <--返回目录
用法:v-on:click="clickHandler" <==> @click="clickHandler"
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 200px; height: 200px; background-color: #ccc; } </style> </head> <body> <div id="app"> <!-- <input type="button" value="按钮" :title="mytitle + '123'" v-on:click="clickHandler"> --> <input type="button" value="按钮" :title="mytitle + '123'" v-on:click="clickHandler"> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { mytitle: "标题" }, methods: { //methods属性定义当前vue实例所有可用的方法 clickHandler: function() { alert(111); } } }); </script> </body> </html>
9、跑马灯效果制作 <--返回目录
实现原理:VM实例会自动监听自己data中数据的改变,数据一旦改变,会自动把最新数据,从data同步到页面。
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 200px; height: 200px; background-color: #ccc; } [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <input type="button" value="跑起来" @click="run"> <input type="button" value="停止" @click="stop"> <h4 v-cloak> {{ msg }} </h4> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: '猥琐发育,别浪~~~', time: null }, methods: { run: function() { var that = this; /*//先清除定时器 console.log("开启定时器前先清除定时器:" + this.time); clearInterval(this.time);*/ // 如果之前开启了定时器,就不再重复开启了 if (this.time) {//注意:记得在stop方法里面清除定时器后使得time=null console.log("之前开启了定时器,就不再重复开启了"); return; } //开启定时器 this.time = window.setInterval(function(){ var start = that.msg.substring(0, 1) var end = that.msg.substring(1) that.msg = end + start; },1000); }, stop: function() { console.log("清除定时器:" + this.time); clearInterval(this.time); this.time = null;//清除定时器后,将time=null this.msg = '猥琐发育,别浪~~~'; } } }); </script> </body> </html>
10、事件修饰符 <--返回目录
1).stop阻止冒泡
<div class="inner" @click="divHandler"> <!-- @click.stop="btnHandler"阻止事件冒泡 --> <input type="button" value="跑起来" @click.stop="btnHandler"> </div>
2).prevent 阻止默认事件
<!-- @click.prevent="aHandler" 阻止链接的默认行为 --> <a href="http://www.baidu.com" @click.prevent="aHandler">百度</a>
3).capture 添加事件侦听器时使用事件捕获模式
<!-- @click.capture="divHandler"捕获机制 --> <div class="inner" @click.capture="divHandler"> <input type="button" value="跑起来" @click="btnHandler"> </div>
4).self 只当事件在该元素本身(比如不是子元素)触发时才触发回调
<!-- 只有点击div自身才会触发事件,冒泡和捕获都不触发 --> <div class="inner" @click.self="divHandler"> <input type="button" value="跑起来" @click="btnHandler"> </div>
5).once 事件只触发一次
<!-- 使用once事件只触发一次,prevent和once顺序无所谓;第一次默认行为也阻止了, 第二次默认行为不阻止。 --> <a href="http://www.baidu.com" @click.prevent.once="aHandler">百度</a>
代码:
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; position: relative; } .inner { width: 200px; height: 200px; background-color: pink; /*子盒子居中显示*/ position: absolute; left: 50%; top: 50%; margin-left: -100px; margin-top: -100px; } </style> </head> <body> <div id="app"> <!-- @click.stop="btnHandler"阻止事件冒泡 --> <!-- <div class="inner" @click="divHandler"> <input type="button" value="跑起来" @click.stop="btnHandler"> </div> --> <!-- @click.prevent="aHandler" 阻止链接的默认行为 --> <!-- <a href="http://www.baidu.com" @click.prevent="aHandler">百度</a> --> <!-- @click.capture="divHandler"捕获机制 --> <!-- <div class="inner" @click.capture="divHandler"> <input type="button" value="跑起来" @click="btnHandler"> </div> --> <!-- 只有点击div自身才会触发事件,冒泡和捕获都不触发 --> <!-- <div class="inner" @click.self="divHandler"> <input type="button" value="跑起来" @click="btnHandler"> </div> --> <!-- 使用once事件只触发一次,prevent和once顺序无所谓;第一次默认行为也阻止了, 第二次默认行为不阻止。 --> <a href="http://www.baidu.com" @click.prevent.once="aHandler">百度</a> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { }, methods: { btnHandler: function () { console.log("触发了button的单击事件"); }, divHandler: function() { console.log("触发了div.inner的单击事件"); }, aHandler: function() { console.log("触发了链接的单击事件"); } } }); </script> </body> </html>
11、讲解v-model实现【表单元素】的数据双向绑定 <--返回目录
v-model:value="msg"可以实现【表单元素】数据的双向绑定
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; position: relative; } [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <h4 v-cloak>{{ msg }}</h4> <!-- v-bind:只能实现Model到View的数据绑定 --> <!-- <input type="text" v-bind:value="msg"> --> <!-- v-model:value="msg"可以实现数据的双向绑定 --> <input type="text" v-model:value="msg"> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: '百年孤独' }, methods: { } }); </script> </body> </html>
12、案例:v-model实现计算器 <--返回目录
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; position: relative; } input[type="text"] { width: 100px; } </style> </head> <body> <div id="app"> <input type="text" v-model:value="n1"> <input type="button" value="+"> <input type="text" v-model:value="n2"> <input type="button" value="=" @click="clickHandler"> <input type="text" v-model:value="result"> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { n1: "", n2: "", result: "" }, methods: { clickHandler: function() { this.result = parseInt(this.n1) + parseInt(this.n2); } } }); </script> </body> </html>
13、vue中通过属性绑定为元素设置class类样式 <--返回目录
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; } [v-cloak] { display: none; } .red { color: red; } .thin { font-weight: 200; } .italic { font-style: italic; } .active { letter-spacing: 0.5em; } </style> </head> <body> <div id="app"> <!-- 原来的方式 --> <!-- <h1 class="red thin" v-cloak>{{ msg }}</h1> --> <!-- 第一种方式:直接传递一个数组 --> <!-- <h1 :class="['red','thin']" v-cloak>{{ msg }}</h1> --> <!-- 第二种方式:在数组中使用三元表达式 --> <!-- <h1 :class="['red','thin','italic',flag?'active':'']" v-cloak>{{ msg }}</h1> --> <!-- 第三种方式: 数组嵌套对象,用对象替代三元表达式; flag为true时active激活,flag为false时active不激活--> <!-- <h1 :class="['red','thin','italic',{'active':flag}]" v-cloak>{{ msg }}</h1> --> <!-- 第四种方式: 在为class使用v-bind绑定对象时,对象的属性可以带引号,也可以不带引号 --> <!-- <h1 :class="{red:true, active:flag}" v-cloak>{{ msg }}</h1> --> <h1 :class="classObj" v-cloak>{{ msg }}</h1> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: 'h1里面的文本', flag: false, classObj: {red:true, italic:true, active:this.flag} }, methods: { } }); </script> </body> </html>
14、vue中通过属性绑定为元素绑定style行内样式 <--返回目录
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; } [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <!-- 原来的方式 --> <!-- <h1 style="color:red;font-weight:200" v-cloak>{{msg}}</h1> --> <h1 :style="{color:'blue','font-weight':200}" v-cloak>{{msg}}</h1> <h1 :style="styleObj1" v-cloak>{{msg}}</h1> <h1 :style="[styleObj1,styleObj2]" v-cloak>{{msg}}</h1> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: 'h1里面的文本', styleObj1: {color:'pink','font-weight':200}, styleObj2: {'font-style':'italic'} }, methods: {} }); </script> </body> </html>
15、v-for指令的四种使用方式 <--返回目录
遍历普通数组 [1,2,3]
遍历对象数组 [{id:1,name:'张三'},{id:2,name:'李四'}]
遍历对象 {id:3,name:'王五'}
迭代数字
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; } </style> </head> <body> <div id="app"> <!-- <p>{{ list[0] }}</p> --> <!-- 遍历普通数组 --> <!-- 注意:老师演示时(item, i) in list --> <!-- <p v-for="item in list">{{item}}</p> --> <p v-for="(i, item) in list">索引{{i}}:{{item}}</p> <!-- 遍历对象数组 --> <p v-for="(i, user) in list2">索引{{i}}:{{user.id}} --- {{user.name}}</p> <!-- 遍历对象,老师演示的版本key val与我代码里相反 --> <p v-for="(key, val) in user">val:{{val}}---key:{{key}}</p> <!-- 迭代数字,老师演示的版本里count从1开始 --> <p v-for="count in 3">第{{count}}次循环</p> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { list: ['火狐','谷歌','欧朋'], list2: [{id:1,name:'张三'},{id:2,name:'李四'}], user: {id:3,name:'王五'} }, methods: {} }); </script> </body> </html>
16、v-for中key的使用注意事项 <--返回目录
2.2.0+的版本里,当在组件中使用v-for时,key属性是必须的;key属性只能使用string/number。
案例:点击按钮添加,添加一个对象到list列表中
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <style type="text/css"> div#app { width: 400px; height: 400px; background-color: #ccc; } </style> </head> <body> <div id="app"> <label>id:<input type="text" v-model="id"></label> <label>name:<input type="text" v-model="name"></label> <input type="button" value="添加" @click="add"><br/> <p v-for="item in user"> <input type="checkbox" :key="item.id">{{item.id}}----{{item.name}} </p> </div> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { id: '', name: '', user: [{id:1,name:'西施'},{id:2,name:'貂蝉'},{id:3,name:'杨玉环'}] }, methods: { add: function() { // this.user.push({id:this.id,name:this.name}); this.user.unshift({id:this.id,name:this.name}); } } }); </script> </body> </html>
17、v-if和v-show的使用和特点 <--返回目录
1) v-if和v-show的值为true时,元素才显示;v-if和v-show的值为false时,元素不显示
2)v-if:每次都会重新删除或创建元素;所以,v-if有较高的切换性能消耗
- 如果元素涉及到频繁的切换,最好不用v-if
3)v-show:切换元素的display:none样式,不重新创建元素;有较高的初始渲染消耗
代码:
<!DOCTYPE html> <html> <head> <title>标题</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <!-- 导入vue的包 --> <script type="text/javascript" src="vue.js"></script> <style type="text/css"> div { width: 200px; height: 200px; background-color: #ccc; } </style> </head> <body> <div id="app"> <!-- <input type="button" value="切换" @click="flag=!flag"> --> <input type="button" value="切换" @click="toggle"> <p v-if="flag">{{ msg }}</p> <p v-show="flag">{{ msg }}</p> </div> <script type="text/javascript"> //创建一个vue实例 var vm = new Vue({ el: '#app', data: { msg: 'hello vue', flag: true }, methods: { // toggle: function() { // if(this.flag){ // this.flag = false; // }else { // this.flag = true; // } // } toggle: function() { this.flag = !this.flag; } } }); </script> </body> </html>