Vue简介
尤雨溪:Vue.js的创建者
- 2014年2月,Vue.js正式发布
- 2015年10月27日,正式发布1.0.0
- 2016年4月27日,发布2.0的预览版本
Vue:渐进式JavaScript框架
声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建
Vue的优点
- 易用:熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
- 灵活:在一个库和一套完整框架之间自如伸缩
- 高效:20kB运行大小,超快虚拟 DOM
Vue的基本使用
传统模式
Vue的基本使用
Vue的基本使用
1. 提供标签用于填充数据
2.引入Vue的库文件
3.可以使用Vue相关的语法功能
4.把Vue提供的数据填充到html标签中
Vue实例的参数
- el:元素的挂载位置
- data:模型数据(值是一个对象或函数)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue的基本使用</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<div>{{5>3?'正确':'不正确'}}</div>
<div>{{20+40}}</div>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg: 'hello word'
}
},
})
</script>
</html>
插值表达式的作用
- 把数据填充到html标签中
- 插值表达式支持基本的计算操作
Vue代码运行的原理
前端渲染
把数据填充到HTML标签中
前端渲染的方式
- 原生JS拼接字符串
- 使用前端模板引擎
- 使用Vue的模板语法
Vue的模板语法之大纲
- 插值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
插值表达式
插值表达式:{{}}
- 把数据填充到html标签中
- 插值表达式支持基本的计算操作
指令
自定义指令的本质
自定义属性。指令的格式:以v-开始
v-clock
v-clock是为了解决插值表达式的闪动问题,先隐藏,替换好值之后显示最终的结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-clock</title>
<style>
[v-v-clock] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<div v-clock>{{msg}}</div>
</div>
</body>
<script src='./vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg: 'hello word'
}
},
})
</script>
</html>
Vue数据绑定的三种方式
v-text
填充纯文本,相对于插值表达式更加简洁且没有闪动问题。
v-html
填充html片段,但存在xss(跨站脚本)攻击,不建议使用
v-pre
显示原始的信息,跳过编译过程。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-pre>{{msg}}</div>
<div v-text='text'></div>
<div v-html="html"></div>
</div>
</body>
<script src='./vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg: 'hello word',
text: 'hello Vue',
html: '<h1>hello Vue</h1>',
}
},
})
</script>
</html>
数据响应式
如何理解数据响应式
- html5中的响应式(屏幕尺寸的变化会导致样式的变化)
- 数据的响应式:数据的变化会导致页面内容的变化
数据绑定的含义
- 将数据填充到html标签中
v-once
v-once:只编译一次,显示内容之后便不再有响应式的功能
v-once的优点
如果显示的信息后续不需要更改,可以节省Vue的内存,从而可以节省性能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-once</title>
</head>
<body>
<div id="app">
<div v-once>{{msg}}</div>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg:"hello Vue"
}
},
})
</script>
</html>
v-model
v-model:Vue中的双向数据绑定指令。
双向数据绑定的含义
数据的变化会导致视图的变化,视图的变化会导致页面内容的变化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<input type="text" v-model='msg'>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg: 'hello'
}
},
})
</script>
</html>
MVVM
- M(model)
- V:(view)
- VM:(View-Model)
事件绑定
Vue处理事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div>{{num}}</div>
<button v-on:click="num++">按钮++</button>
<button @click='num--'>按钮--</button>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
num: '1'
}
},
})
</script>
</html>
Vue事件函数的调用方式
Vue事件函数之传递参数
- 如果事件直接绑定函数名称,默认第一个参数则为事件对象
- 如果事件绑定函数调用,默认最后一个参数为事件对象($event)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之事件函数调用</title>
</head>
<body>
<div id="app">
<div>{{num}}</div>
<button @click='handle1'>按钮1</button>
<button @click='handle2(20,$event)'>按钮2</button>
</div>
</body>
<script src='./vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
num: '0'
}
},
methods: {
handle1: function(event) {
this.num++
console.log(event.target.innerHTML);
},
handle2: function(num, event) {
this.num--
console.log(event.target.innerHTML);
}
},
})
</script>
</html>
Vue之事件修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之事件修饰符</title>
</head>
<div id="app">
<div>{{num}}</div>
<div v-on:click="handle1">
<button v-on:click="handle">按钮</button>
</div>
<a href="http:///www.baidu.com" v-on:click="handle2">百度</a>
</div>
<body>
<div></div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
num: '0'
}
},
methods: {
handle: function(event) {
//js处理事件冒泡
event.stopPropagation();
},
handle1: function() {
this.num++
},
handle2: function(event) {
//js处理默认行为
event.preventDefault();
}
},
})
</script>
</html>
Vue中的按键修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之按键修饰符</title>
</head>
<body>
<div id="app">
<form action="">
<p>账号:<input type="text" v-model='name' v-on:keyup.delete="handle"></p>
<p>密码:<input type="password" v-model='password' v-on:keyup.enter="handle1"></p>
<input type="button" value='提交' v-on:click='handle1'>
</form>
</div>
</body>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
name: "",
password: ''
}
},
methods: {
handle: function() {
this.name = ''
},
handle1: function() {
//点击enter键在控制台进行打印
console.log(this.name, this.password);
}
},
})
</script>
</html>
Vue之自定义按键修饰符
自定义按键修饰符的名字可以随便起,但对应的keycode码必须要正确。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之自定义修饰符</title>
</head>
<body>
<div id="app">
<input type="text" v-model="msg" v-on:keyup.html='handle'>
</div>
</body>
<script src="./vue.js"></script>
<script>
Vue.config.keyCodes.html = 72
let vm = new Vue({
el: "#app",
data() {
return {
msg: ""
}
},
methods: {
handle: function(event) {
console.log(event.keyCode);
}
},
})
</script>
</html>
简单计算器的功能
实现逻辑
- 通过v-model实现a与b的双向数据绑定。
- 点击按钮,实现处理逻辑
- 将计算结果渲染到页面中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue实现计算器的效果</title>
</head>
<body>
<div id="app">
<p>A<input type="text" v-model='a'></p>
<p>B<input type="text" v-model='b'></p>
<button v-on:click='handle'>+</button>
<button v-on:click='handle1'>-</button>
<button v-on:click='handle2'>×</button>
<button v-on:click='handle3'>/</button>
<button v-on:click='handle4'>C</button>
<div>{{result}}</div>
</div>
</body>
<script src='../vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
a: '',
b: '',
result: ''
}
},
methods: {
handle: function() {
this.result = parseFloat(this.a) + parseFloat(this.b)
},
handle1: function() {
this.result = parseFloat(this.a) - parseFloat(this.b)
},
handle2: function() {
this.result = parseFloat(this.a) * parseFloat(this.b)
},
handle3: function() {
this.result = parseFloat(this.a) / parseFloat(this.b)
},
handle4: function() {
this.a = '';
this.b = '';
this.result = ''
},
},
})
</script>
</html>
Vue之属性绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之属性绑定</title>
<style>
* {
margin: 0;
padding: 0;
}
a {
display: block;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
text-decoration: none;
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<a :href="url">链接</a>
<button v-on:click="handle">按钮</button>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
url: 'http:///www.baidu.com'
}
},
methods: {
handle: function() {
this.url = 'https://nodejs.org/en/'
}
}
})
</script>
</html>
v-model的底层原理
注意:v-model的底层原理利用事件绑定及属性绑定。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model的底层原理</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<!-- 双向绑定的第一种的方法 -->
<input type="text" v-model='msg'>
<!--双向绑定的第二种方法 -->
<input type="text" v-bind:value='msg' v-on:input='msg=$event.target.value'>
<!-- 双向绑定的第三种方法 -->
<input type="text" v-bind:value='msg' v-on:input='handle'>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
msg: ''
}
},
methods: {
handle: function(event) {
this.msg = event.target.value;
}
},
})
</script>
</html>
Vue之样式绑定
class样式处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之class</title>
<style>
#app div {
margin-top: 20px;
}
.active {
width: 200px;
height: 200px;
}
.color {
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:class='{active:isActive,color:isColor}'></div>
<div v-bind:class='objClass'></div>
<div v-bind:class=[activeClass,colorClass]></div>
<div v-bind:class='arrClass'></div>
<div></div>
<div></div>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
isActive: true,
isColor: true,
activeClass: 'active',
colorClass: 'color',
objClass: {
active: true,
color: true,
},
arrClass: ['active', 'color']
}
},
})
</script>
</html>
class样式绑定的三个细节
- 对象用法可以与数组用法结合使用
- class声明的类可以简写
- 原有的类会被保存
style样式绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之class</title>
<style>
div {
margin-top: 20px;
}
</style>
</head>
<body>
<div id="app">
<div v-bind:style='{border:borderStyle,width:widthStyle,height:heightStyle}'></div>
<div v-bind:style='objStyle'></div>
<div v-bind:style=[objStyle,backgroundStyle]></div>
<div></div>
<div></div>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
borderStyle: '1px solid red',
widthStyle: '200px',
heightStyle: '200px',
objStyle: {
border: '1px solid red',
width: '200px',
height: '200px',
},
backgroundStyle: {
backgroundColor: 'red'
}
}
},
})
</script>
</html>
Vue之分支结构
- v-if
- v-esle-if
- v-else
- v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-if与v-show</title>
</head>
<body>
<div id="app">
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=60&&score<90">良好</div>
<div v-else>不及格</div>
<div v-show="flag">v-show</div>
<button v-on:click='handle'>按钮</button>
</div>
</body>
<script src='../vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
score: '90',
flag: true,
};
},
methods: {
handle: function() {
this.flag = !this.flag
}
}
})
</script>
</html>
v-if与v-show的区别
- v-if:是否控制元素渲染到页面中
- v-show:控制元素是否显示(已经渲染到页面中)
Vue之循环结构
v-for遍历数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-bind:key='index' v-for='(item,index) in list'>{{item +'----'+index}}</li>
<li v-bind:key='myList.id' v-for='(item,index) in myList'>{{item.id +'----'+item.name}}</li>
</ul>
</div>
</body>
<script src="../vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
list: ['apple', 'banner', 'pear', 'lemon'],
myList: [{
id: 1,
name: 'apple',
}, {
id: 2,
name: 'banner',
}, {
id: 3,
name: 'pear',
}, {
id: 4,
name: 'lemon',
}]
}
},
})
</script>
</html>
key的作用
帮助vue区分不同的元素,提高Vue的性能
v-for遍历对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-for遍历对象</title>
</head>
<body>
<div id="app">
<ul>
<li v-if='name="尧子陌"' v-for='(value,key,index) in obj'>{{index+'---'+value+'----'+key}}</li>
</ul>
</div>
</body>
<script src='../vue.js'></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
obj: {
name: "尧子陌",
age: "24",
hobby: '代码'
}
}
},
})
</script>
</html>
Vue之tab栏案例
实现原理
1.实现静态的UI效果
用传统的方式实现标签的结果与样式
2.基于数据重构UI
将静态结构的样式转换为Vue模板语法
处理JS逻辑和事件绑定
3.声明式编程
模板的结果和最终显示的结果一致。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之tab栏效果</title>
<style>
* {
margin: 0;
padding: 0;
}
.tab {
width: 600px;
margin: 200px auto;
}
.tab ul {
overflow: hidden;
list-style: none;
}
.tab li {
float: left;
width: 200px;
height: 40px;
text-align: center;
line-height: 40px;
box-sizing: border-box;
border: 1px solid red;
border-collapse: collapse;
}
.tab div {
display: none;
}
.active {
background-color: blue;
}
div>img {
display: block;
width: 600px;
}
div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab">
<ul>
<li v-on:click='change(index)' v-bind:key='item.id' v-bind:class='currentIndex==index?"active":""' v-for=' (item,index) in list '>{{item.title}}</li>
</ul>
<div v-bind:key='item.id' v-bind:class='currentIndex==index?"current":""' v-for=' (item,index) in list '><img v-bind:src="item.path"></div>
</div>
</div>
</body>
<script src='./vue.js '></script>
<script>
let vm = new Vue({
el: "#app",
data() {
return {
currentIndex: 0, //当前对应的索引
list: [{
id: 1,
title: '裴庆虎 ',
path: "./img/裴庆虎.jpg"
}, {
id: 2,
title: '关羽 ',
path: "./img/关羽.jpg"
}, {
id: 3,
title: '雅典娜 ',
path: "./img/雅典娜.jpg"
}, ]
};
},
methods: {
change: function(index) {
//选项卡的本质:切换类名
this.currentIndex = index;
console.log(index);
}
}
})
</script>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。