一、Vue概述
1.1 介绍
- Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。它不仅易于上手,还便于与第三方库或既有项目整合。
1.2 MVVM模式
- MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开
- MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)
- Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。
1.3 Vue的快速入门
- 在script脚本区域,创建vue对象
- 声明
el: "#[区域id]"
,表示这块区域由vue接管。 - 声明
data: {}
,数据域 - 在body块,使用插值表达式,将
data
域中声明的变量插到{{变量名}}
中
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>快速入门</title>
<!--引入vue.js-->
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
{{message}} <!-- //vue的插值表达式,把data中定义的数据显示到此处 -->
</div>
</body>
<script>
//view model
//创建Vue对象
new Vue({
el: "#app",//由vue接管id为app区域
data: {
message: "hello, vue", //注意:此处不要加分号
}
});
</script>
</html>
1.3.1 插值表达式
- 数据绑定的最常见形式用双大括号语法的文本插值,无论何时,vue对象中
data
数据发生改变,插值出的内容都会更新。 - 支持的表达式,如下:
<!-- 支持 三目运算符, 但不支持赋值语句-->
{{ok? "A":"B"}}
<!--数学运算-->
{{number + 1}}
- <font color="red">赋值语句与流程控制语句都不会生效!</font>
<!-- 插值表达式不支持变量的声明 -->
{{var a = 1 }}
<!-- 插值表达式不支持条件判断流程控制 -->
{{ if(ok) return message}}
二、Vue常用指令
2.1 v-on
- 用
v-on
指令鉴定DOM事件,并会触发javascript代码
2.1.1 v-on:click
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:click</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
{{message}}
<button v-on:click="fun1('vue v-on')" >vue的onclick事件</button>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
message: "hello vue"
},
methods: {
fun1: function(message) {//fun1为button中的方法名,message为传的参
this.message = message;
//点击button后会触发方法,将data中的message改为传入的参数
}
}
});
</script>
</html>
2.1.2 v-on:keydown
- 我对
event
对象的理解:键盘按下,鼠标按下等,都称为一个“事件”,只有事件发生了,才会触发功能函数。 event
对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。事件通常与函数结合使用,函数不会在事件发生前被执行!注意点:
- <font color="red">使用不带圆括号的形式,event 对象将被自动当做实参传入</font>
- <font color="red">使用带圆括号的形式,我们需要使用 $event 变量显式传入 event 对象</font>,如果不传入可能最终找到的是全局的
window .event
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:keydown</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<!--键盘按下事件-->
<!--使用不带圆括号的形式,event 对象将被自动当做实参传入;-->
<!--使用带圆括号的形式,我们需要使用 $event 变量显式传入 event 对象。-->
vue: <input type="text" v-on:keydown="fun($event)">
<!--<input type="text" v-on:keydown="fun">-->
<hr>
传统Js: <input type="text" onkeydown="showKeyCode()">
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
methods: {
// $event 它是vue中的事件对象,和传统js的event对象是一样的
fun: function (event) {
var keyCode = event.keyCode;
if (keyCode < 48 || keyCode > 57) {
//不让键盘起作用
event.preventDefault();
}
}
}
});
//传统js的键盘按下事件
function showKeyCode() {
//event对象和 document对象 window对象 是一样的, 可以不定义直接使用
//alert("success");
var keyCode = event.keyCode;
if(keyCode < 48 || keyCode > 57) {
event.preventDefault();
}
// alert(keyCode);
}
</script>
</html>
2.1.3 v-on:mouseover
event.stopPropagation()
阻止冒泡。
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:mouseover</title>
<style>
#div, #div2 {
background-color: red;
}
</style>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<!--@mouseover等价于 v-on:mouseover
@事件名称 就是 v-on:事件名称 的简写方式
-->
<div v-on:mouseover="fun1" id="div">
<textarea v-on:mouseover="fun2($event)">这是一个文件域</textarea>
</div>
<div onmouseover="fun3" id="div2">
<textarea onmouseover="fun4()">这是一个文件域</textarea>
</div>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
methods: {
fun1: function () {
alert("鼠标悬停在div上");
},
fun2: function (event) {
alert("鼠标悬停在文件域上");
event.stopPropagation();//阻止冒泡
}
}
});
//传统js
function fun3() {
alert("鼠标移动到了传统div2上了");
}
function fun4() {
alert("鼠标移动到了传统文件域上了");
event.stopPropagation();
}
</script>
</html>
2.1.4 事件修饰符
vue为
v-on
提供了事件修饰符来处理DOM事件细节,如event.preventDefault()
(通知浏览器不要执行与事件关联的默认动作)、event.stopPropagation()
(不再派发事件)。.stop
.prevent
.capture
.self
.once
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:事件修饰符</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<!--阻止事件执行行为 -->
<form action="https://www.baidu.com/" method="post" v-on:submit.prevent>
<input type="submit" value="提交">
</form>
<form action="https://www.baidu.com/" method="post" onsubmit="return checkForm()">
<input type="submit" value="提交">
</form>
</div>
</body>
<script>
//view model
new Vue({
el: "#app"
});
//传统Js方式
function checkForm() {
alert(1);
//表单验证必须有一个明确的boolean类型返回值
//在应用验证方法时必须加上 return 方法名称
//return false表示表单验证不通过,action的url不会访问
return false;
}
</script>
</html>
2.1.5 按键修饰符
vue允许
v-on
在监听事件时添加按键修饰符.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-on:按键修饰符</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-on:keydown.enter="fun1()">
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
fun1: function () {
alert("按下的是回车")
}
}
});
</script>
</html>
- 补充
v-on
的完整写法和简易写法
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
2.2 v-text / v-html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-text与v-html</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<div v-html="message"></div>
<div v-text="message"></div>
<div id="div1"></div>
<div id="div2"></div>
</div>
</body>
<script>
//view model
//vue接管这块区域
new Vue({
el: "#app",
data: {
message: "<h1>hello</h1>"
}
});
//传统js的 innerHTML(能解析标签) 和 innerText(纯文本,不能解析标签)
window.onload = function () {
document.getElementById("div1").innerHTML="<h1>hello</h1>";
document.getElementById("div2").innerText="<h1>hello</h1>";
}
</script>
</html>
2.3 v-bind
- <font color="red">插值语法不能使用在html标签属性上</font>,应使用
v-bind
指令
<!DOCTYPE html>
<html xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-text与v-html在v-bind上的使用</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<font size="5" v-bind:color="ys1" >hello</font>
<font size="5" :color="ys2" >hello</font>
</div>
</body>
<script>
//view model
//插值表达式不能用于html标签的属性取值
//若想给html标签的属性设置变量的值,需要使用v-bind
//v-bind简化写法, 直接使用:
new Vue({
el: "#app",
data: {
ys1: "red",
ys2: "green"
}
});
</script>
</html>
- 补充
v-bind
的完整写法和简易写法
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
2.4 v-model
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-model</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<form action="" method="post">
用户名:<input type="text" name="username" v-model="user.username">
密码:<input type="text" name="password" v-model="user.password">
</form>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
user: {
username: "test",
password: "1234"
}
}
});
</script>
</html>
2.5 v-for
2.5.1 操作数组
<li v-for="item in arr">{{item}}</li>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-for遍历数组</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
arr: [1,2,3,4,5]
}
});
</script>
</html>
2.5.2 操作对象
<li v-for="(key, value) in product"> {{key}} === {{value}}</li>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-for遍历对象</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="(key, value) in product"> {{key}} === {{value}}</li>
</ul>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
product: {
id: "1",
name: "电脑",
price: 2000
}
}
});
</script>
</html>
2.5.3 操作对象数组
<tr v-for="(item, index) in products">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>v-for遍历对象</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<table border="1">
<tr>
<td>序号号</td>
<td>编号</td>
<td>名称</td>
<td>价格</td>
</tr>
<tr v-for="(item, index) in products">
<td>{{index}}</td>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
</tr>
</table>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
products: [
{id: 1, name: "电脑", price: 5000},
{id: 2, name: "手机", price: 3000},
{id: 3, name: "电视", price: 4000},
]
}
});
</script>
</html>
2.6 v-if / v-show
v-if
:根据表达式的值决定是否渲染元素(决定有还是没有)v-show
:根据表达式的值切换display
属性(已有,决定show还是none)
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>v-if与v-show</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<span v-if="flag">hello</span>
<span v-show="flag">halo</span><br>
<button v-on:click="toggle">切换</button>
</div>
</body>
<script>
//view model
new Vue({
el: "#app",
data: {
flag: false
},
methods: {
toggle: function () {
this.flag = ! this.flag;
}
}
});
</script>
</html>
三、Vue生命周期
- 每个Vue对象在被创建之前都要经过一系列的初始化过程。
具体生命状态
beforeCreate
- 数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
created
- 数据已经绑定到了对象实例,但是还没有挂载对象
beforeMount
- 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的
el
属性,el
属性是一个HTMLElement
对象,也就是这个阶段,vue实例通过原生的createElement
等方法来创建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
- 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的
mounted
- 将el的内容挂载到了
el
,相当于我们在jquery执行了(el).html(el)
,生成页面上真正的dom,上面我们就会发现dom的元素和我们el
的元素是一致的。在此之后,我们能够用方法来获取到el
元素下的dom对象,并进行各种操作
- 将el的内容挂载到了
beforeUpdate
- 数据更新到dom之前,我们可以看到
$el
对象已经修改,但是我们页面上dom的数据还没有发生改变
- 数据更新到dom之前,我们可以看到
updated
- dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到dom上面,完成更新
beforeDestroy
destroyed
- 实例的销毁,vue实例还是存在的,只是解绑了事件的监听还有watcher对象数据与view的绑定,即数据驱动
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>vuejs生命周期</title> <script src="js/vuejs-2.5.16.js"></script> </head> <body> <div id="app"> {{message}} </div> </body> <script> var vm = new Vue({ el: "#app", data: { message: 'hello world' }, beforeCreate: function() { console.log(this); showData('创建vue实例前', this); }, created: function() { showData('创建vue实例后', this); }, beforeMount: function() { showData('挂载到dom前', this); }, mounted: function() { showData('挂载到dom后', this); }, beforeUpdate: function() { showData('数据变化更新前', this); }, updated: function() { showData('数据变化更新后', this); }, beforeDestroy: function() { vm.test = "3333"; showData('vue实例销毁前', this); }, destroyed: function() { showData('vue实例销毁后', this); } }); function realDom() { console.log('真实dom结构:' + document.getElementById('app').innerHTML); } function showData(process, obj) { console.log(process); console.log('data 数据:' + obj.message) console.log('挂载的对象:') console.log(obj.$el) realDom(); console.log('------------------') console.log('------------------') } //vm.message = "good..."; vm.$destroy(); </script> </html>
四、Vue的ajax请求
4.1 axios
- 引入axios,可以通过
script
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
4.1.1 get请求
const axios = require('axios');
// Make a request for a user with a given ID
// 通过给定的id来发送请求
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.finally(function () {
// always executed
});
// Optionally the request above could also be done as
// 也可以通过json格式 {params: {key: value}}
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// always executed
});
// Want to use async/await? Add the `async` keyword to your outer function/method.
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}
4.1.2 post请求
//以json格式传入参数
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});