Vue概述
Vue诞生
渐进式javascript框架
Vue是渐进式javascript框架
声明式渲染—>组件系统---->客户端路由—>集中式状态管理---->项目构建
Vue的优点
- 易用:熟悉HTML CSS JavaScript知识 即可快速上手Vue
- 灵活:库与框架之间来回切换
- 高效:20KB运行大小 超快虚拟DOM
Vue的基本使用
使用步骤
- 需要提供标签用于填充数据
- 引入vue.js文件
- 使用vue.js的语法功能
- vue提供的数据填充到标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue的基本使用</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div>{{message}}</div>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
message: 'Hello Word'
}
})
</script>
</html>
Vue之细节分析
实例参数
- el:元素的挂载位置
- data:模型对象(值是一个对象)
插值表达式
- 将数据填充到HTML标签
- 插值表达式支持基本的计算操作
Vue代码之运行的原理
- 概述编译过程(Vue语法—>原生语法)
Vue前端模板
前端渲染方式
原生JS拼接字符串
缺点:不同的开发人员的代码风格差别很大 随着业务的复杂 后期的维护逐渐变得困难
var d = data.weather;
var info = document.getElementById('info');
info.innerHTML = '';
for(var i=0;i<d.length;i++){
var date = d[i].date;
var day = d[i].info.day;
var night = d[i].info.night;
var tag = '';
tag += '<span>日期:'+date+'</sapn><ul>';
tag += '<li>白天天气:'+day[1]+'</li>'
tag += '<li>白天温度:'+day[2]+'</li>'
tag += '<li>白天风向:'+day[3]+'</li>'
tag += '<li>白天风速:'+day[4]+'</li>'
tag += '</ul>';
var div = document.createElement('div');
div.innerHTML = tag;
info.appendChild(div);
}
使用前端模板引擎
优点:不同的开发人员遵循同样的规范写代码 代码可读性提高 后期方便维护
缺点:没提供专门的事件机制
<script id="abc" type="text/html">
{{if isAdmin}}
<h1>{{title}}</h1>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
{{/if}}
</script>
Vue模板语法
- 插值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
指令
指令:本质便是自定义属性 以v-开头
v-clock
解决插值表达式存在的闪动问题
先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-clock</title>
<style>
[v-clock] {
display: none;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-clock>{{msg}}</div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: 'Hello Word'
}
})
</script>
</html>
Vue数据绑定指令
v-text:填充纯文本
- 相比于插值表达式更加简洁
v-html:填充HTML片段
- 存在安全问题
- 本网站的内部数据可使用 来自第三方的数据不可使用
v-pre:填充原始信息
- 显示原始信息,跳过编译过程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之数据绑定</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-text='Text'></div>
<div v-html='Html'></div>
<div v-pre>{{Pre}}</div>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
Text: 'Text',
Html: '<h1>innerHTML</h1>',
Pre: 'Pre'
}
})
</script>
</html>
数据响应式
理解响应式
- html5中的响应式(屏幕的变化导致样式的变化)
- 数据的响应式(数据的变化会导致内容的变化)
数据绑定
- 数据绑定:将数据填充到标签中
v-once
- 编译一次内容后 便不再具有响应式的功能 后续的信息不需要更改 可使用v-once来提高性能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-once</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-once> {{message}}</div>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "Hello Word"
}
})
</script>
</html>
v-model
双向数据绑定 页面的变化会导致数据的变化 数据的变化会导致页面的变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div>{{message}}</div>
<input type="text" v-model='message' />
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
message: 'Hello Word'
}
})
</script>
</html>
MVVM
- DOM Listeners:事件监听
- Data Bindings:属性绑定
Vue事件绑定
Vue处理事件
常规写法
<input type="button" v-on:click="num++"
简写
<input type="button" @click="num++"
Vue事件函数的处理方式
绑定函数名称
<input type="button" @click="handleClick"
调用函数
<input type="button" @click="handleClick()"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue事件绑定</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div>{{num}}</div>
<button v-on:click='num++'>+</button>
<button v-on:click='num--'>-</button>
<button @click='handle'>+</button>
<button @click='handleClick()'>-</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
num: 0
},
methods: {
handle: function() {
this.num++
},
handleClick: function() {
this.num--
}
}
})
</script>
</html>
Vue事件函数的传参
-
事件若绑定函数名称 默认事件对象作为第一个参数进行传递
-
事件若直直接调用函数 事件对象则作为最后一个参数进行传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue事件函数的调用</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<button v-on:click='handle'>+</button>
<button @click='handleClick(50,50,$event)'>-</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "Hello Word"
},
methods: {
handle: function(event) {
console.log(event.target.innerHTML);
},
handleClick: function(num1, num2, event) {
console.log(num1 + num2);
console.log(event.target.innerHTML);
}
}
})
</script>
</html>
Vue事件修饰符
<!-- 阻止事件冒泡 -->
<div class="son" @click.stop='handleClick'></div>
<!-- 阻止默认事件 -->
<a href="http://www.baidu.com" @click.prevent='handleBthClick'>百度</a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue事件修饰符</title>
<style>
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div>{{num}}</div>
<div @click='handle'>
<button @click.stop='handleClick'> 按钮</button>
</div>
<a href="http://www.baidu.com" @click.prevent='handleBthClick'>百度</a>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
num: 0,
},
methods: {
handle: function() {
this.num++
},
handleClick: function() {
},
handleBthClick: function() {
}
}
})
</script>
</html>
Vue按键修饰符
enter 回车键
<input v-on:keyup.enter='submit'>
esc 退出键
<input v-on:keyup.delete='handle'>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue按键修饰符</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<input type="text" v-model='uname' v-on:keyup.delete='clearBthClick'>
<input type="password" v-model='password' v-on:keyup.enter='submitClick'>
<button @click='submitClick'>提交</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
uname: '',
password: '',
},
methods: {
clearBthClick: function() {
this.uname = ''
},
submitClick: function() {
console.log(this.uname, this.password);
}
}
})
</script>
</html>
Vue自定义按键修饰符
全局 config.keyCodes 对象
Vue.config.keyCodes.f1 = 112
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue自定义按键修饰符</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<input type="text" v-model='info' v-on:keyup.clear='clearBthClick'>
</div>
</body>
<script>
// Vue自定义按键修饰符
Vue.config.keyCodes.clear = 65
let vm = new Vue({
el: "#app",
data: {
info: ''
},
methods: {
clearBthClick: function() {
this.info = ''
}
}
})
</script>
</html>
Vue之简单计算器的案例
步骤
① 通过v-model指令 实现数值A和数值B的绑定
② 给计算按钮绑定事件 实现计算逻辑
③ 将计算结果绑定到对应位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单计算器的案例</title>
<style>
#app {
width: 500px;
margin: 20px auto;
text-align: center;
}
button {
margin-left: 0;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<h2>简单计算器</h2>
<div>
<span>数值A:</span>
<input type="text" v-model='A'>
</div>
<div>
<span>数值B:</span>
<input type="text" v-model='B'>
</div>
<div>
<button v-on:click='handleResult'>结果</button>
<span v-text='result'></span>
</div>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
A: ' ',
B: ' ',
result: ''
},
methods: {
handleResult: function() {
this.result = parseInt(this.A) + parseInt(this.B)
}
}
})
</script>
</html>
Vue之属性绑定
常规写法
<a v-bind:href="url">百度</a>
简写
<a :href="url">百度</a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之属性绑定</title>
<style>
a {
text-decoration: none;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<a v-bind:href="url" v-text='text'></a>
<button @click='handleClick'>切换</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
text: "百度",
url: 'https://baike.baidu.com/'
},
methods: {
handleClick: function() {
this.url = 'https://cn.vuejs.org/',
this.text = 'Vue'
}
}
})
</script>
</html>
v-model的底层实现原理
<input type="text" v-model='msg'>
<input type="text" v-bind:value='msg' v-on:input='handleClick'>
<input type="text" v-bind:value='msg' v-on:input='msg=$event.target.value'>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model的底层实现原理</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div> {{message}}</div>
<input type="text0" v-model='message'>
<input type="text" v-bind:value='message' v-on:input='handleClick'>
<input type="text" v-bind:value='message' v-on:input='msg=$event.target.value'>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
message: 'Hello Word'
},
methods: {
handleClick: function(event) {
this.message = event.target.value
}
}
})
</script>
</html>
Vue样式绑定
Vue样式绑定之class对象形式
<div v-bind:class="{ active: isActive }"></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之class对象形式</title>
<style>
* {
margin: 0;
padding: 0;
}
.active {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
background-color: red;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-bind:class={active:isActive}></div>
<button @click='handle'>切换</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
isActive: true
},
methods: {
handle: function() {
this.isActive = !this.isActive
}
}
})
</script>
</html>
Vue样式绑定之class数组形式
<div v-bind:class="[activeClass, errorClass]"></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之class对象形式</title>
<style>
* {
margin: 0;
padding: 0;
}
.active {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
background-color: red;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-bind:class='[activeClass]'>Test</div>
<button @click='handle'>切换</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
activeClass: "active"
},
methods: {
handle: function() {
this.activeClass = ''
}
}
})
</script>
</html>
Vue样式绑定之相关语法细节
1、对象绑定和数组绑定可以结合使用
2、class绑定的值可以简化操作
3、默认的class会保留
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之相关细节</title>
<style>
* {
margin: 0;
padding: 0;
}
.active {
height: 200px;
text-align: center;
line-height: 200px;
border: 1px solid red;
}
.color {
width: 200px;
background-color: purple;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<!-- 对象绑定和数组绑定可以结合使用 -->
<div v-bind:class="[activeClass,{color:isColor}]">test</div>
<!-- class绑定的值可以简化操作 -->
<div v-bind:class="arrClass">test</div>
<div v-bind:class="ObjClass">test</div>
<!-- 默认的class会保留 -->
<div class='item' v-bind:class="ObjClass">test</div>
<button @click='handleClick'>切换</button>
</div>
</body>
<script>
// 样式绑定
let vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
isColor: true,
arrClass: ['active', 'color'],
ObjClass: {
active: true,
color: true,
}
},
methods: {
handleClick: function() {
this.activeClass = '',
this.isColor = !this.isColor
}
}
})
</script>
</html>
Vue样式绑定之style
对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>
数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue样式绑定之style</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<!-- style之对象写法 -->
<div v-bind:style='{width:widthStyle,height:heightStyle,border:borderStyle}'></div>
<!-- 简写 -->
<div v-bind:style='objStyle'></div>
<!-- style之数组与对象可以结合使用 -->
<div v-bind:style="[objStyle, colorStyle]"></div>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
widthStyle: "200px",
heightStyle: '200px',
borderStyle: '1px solid red',
objStyle: {
width: '200px',
height: '200px',
border: '1px solid red',
},
colorStyle: {
backgroundColor: 'purple'
}
}
})
</script>
</html>
Vue分支循环结构
Vue分支结构
- v-if
- v-else
- v-else-if
- v-show
v-if与v-show的区别
- v-if控制元素是否渲染到页面
- v-show控制元素是否显示(已经渲染到了页面)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue分支结构</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>=70'>一般</div>
<div v-else>比较差</div>
<div v-if='flag'>v-if</div>
<div v-show='flag'>v-show</div>
<button @click='handleClick'>按钮</button>
</div>
</body>
<script>
let vm = new Vue({
el: "#app",
data: {
score: 90,
flag: false,
},
methods: {
handleClick: function() {
this.flag = !this.flag
}
}
})
</script>
</html>
Vue循环结构
v-for遍历数组
<li v-for='item in list'>{{item}}</li>
<li v-for='(item,index) in list'>{{item}} + '---' +{{index}}</li>
key的作用
- key的作用:帮助Vue区分不同的元素,从而提高性能
<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之循环数组</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<ul>
<li v-for='(item,index) in fruit'>{{index}}----{{item}}</li>
<li v-for='(item,index) in myFruit' :key="item.id">
<span>{{item.id}}</span>
<span>------</span>
<span>{{item.cname}}</span>
<span>{{item.ename}}</span>
</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
fruit: ['苹果', '香蕉', '栗子'],
myFruit: [{
id: 1,
cname: '苹果',
ename: 'apple'
}, {
id: 2,
cname: '香蕉',
ename: 'banner'
}, {
id: 3,
cname: '栗子',
ename: 'chestnut'
}]
}
})
</script>
</html>
v-for之遍历对象
v-for遍历对象
<div v-for='(value, key, index) in object'></div>
v-if和v-for结合使用
<div v-if='value==12' v-for='(value, key, index) in object'></div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue之循环数组</title>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<ul>
<li v-for='(value,key,index) in obj' v-if='value==25'>{{value}}----{{key}}----{{index}}</li>
</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
obj: {
name: '尧子陌',
sex: '男',
age: '25'
}
}
})
</script>
</html>
Vue之tab栏切换
实现静态UI效果
- 用传统的方式实现标签结构和样式
基于数据重构UI效果
- 将静态的结构和样式重构为基于Vue模板语法的形式
- 处理事件绑定和js控制逻辑
声明式编程
- 模板的结构和最终显示的效果基本一致
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue之tab栏切换</title>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 166px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<script src="./vue.js"></script>
<body>
<div id="app">
<div class="tab">
<ul>
<li @click='change(index)' v-for='(item,index) in list' :key='item.id' :class='currentIndex==index?"active":""'>{{item.title}}</li>
</ul>
<div :class='currentIndex==index?"current":""' :key='item.id ' v-for='(item, index) in list '>
<img :src="item.path">
</div>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
/*
*/
var vm = new Vue({
el: '#app ',
data: {
currentIndex: 0, // 选项卡当前的索引
list: [{
id: 1,
title: 'apple ',
path: 'img/apple.png '
}, {
id: 2,
title: 'orange ',
path: 'img/orange.png '
}, {
id: 3,
title: 'lemon ',
path: 'img/lemon.png '
}]
},
methods: {
change: function(index) {
// 在这里实现选项卡切换操作:本质就是操作类名
this.currentIndex = index;
}
}
});
</script>
</body>
</html>