Vue 简介
Vue 是一套用于构建用户界面的渐进式框架。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
官方文档: Vue.js
开发工具:VSCode (Live Server 插件)
Vue下载:安装 — Vue.js
Vue谷歌调试工具vue_devtools:https://chrome.zzzmh.cn/info?token=nhdogjmejiglipccpnnnanhbledajbpd
①JavaScript框架;②简化DOM操作; ③响应式数据驱动
特点:数据驱动意图;双向数据绑定
![](https://img-blog.csdnimg.cn/c3d7c06e997141d389ddd87d2f99e3aa.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQkPoj5zpuJ8=,size_20,color_FFFFFF,t_70,g_se,x_16)
原理:MVVM
MVVM是vue实现数据驱动意图和双向绑定的核心原理;
Model: 表示当前页面渲染时依赖的数据源
View:表示当前页面所渲染的DOM结构
ViewModel:表示Vue实例,是MVVM核心
Vue 实例对象
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
Vue.js 使用了基于 HTML模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
var vue = new Vue({
data: data
})
Vue 指令
内容渲染指令
渲染DOM 元素的文本内容,内部支持 javascript表达式
<body>
<div id = "app">
<!--{{}} 插值表达式 -->
<div>{{message}}</div> <!--Hello Vue!-->
<h2>{{message}}10086</h2> <!--Hello Vue!10086-->
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
message:"Hello Vue!",
},
});
</script>
</body>
<body>
<div id = "app">
<!--v-text 缺点:会覆盖文本默认值-->
<h2 v-text="vtext+'10086'">此文本不生效</h2> <!--v-text测试10086-->
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
vtext:"V-text测试",
},
});
</script>
</body>
<body>
<div id = "app">
<!--v-html-->
<p v-html="vhtml"></p> <!--哔哩哔哩的超连接-->
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
vhtml:"<a href='https://www.bilibili.com'>哔哩哔哩</a>",
},
});
</script>
</body>
属性绑定指令
元素绑定属性,内部支持 javascript表达式
-
v-bind 为元素绑定属性,完整写法 v-bind:属性名,简写 :属性名
<body>
<div id = "app">
<!--v-bind-->
<p v-bind:title="vbindTile">悬停vBind</p> <!--提示:"悬停vBind"-->
<p :css="CSS">样式vBind</p> <!--简写 有样式的:"样式vBind"-->
</div>
<style>
.blackText{color: black;font-size: 18px;}
.redText{color:red; font-size: 18px;}
</style>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
vbindTile:"悬停vBind测试",
CSS:"blackText",
},
});
</script>
</body>
事件绑定指令
为元素绑定事件
-
v-on 事件绑定方法写成函数调用形式(原生事件名不需要写on)完整写法 v-on:事件 ; 简写 @+事件
事件的后面跟上“.”修饰符,可以事件限制,绑定方法定义在methods属性中,方法内部通过this 关键字可以访问修改data数据。支持参数传递。事件对象与传参并存时 可使用固定 $event 获取事件对象;可以用事件/按键修饰符。详查阅(API — Vue.js)
修饰符 |
说明 |
.stop |
调用 event.stopPropagation() |
.prevent |
调用 event.preventDefault() |
capture |
添加事件侦听器时使用 capture 模式 |
.self |
只当事件是从侦听器绑定的元素本身触发时才触发回调 |
.{keyCode | keyAlias} |
只当事件是从特定键触发时才触发回调 |
.native |
监听组件根元素的原生事件 |
.once |
只触发一次回调 |
.left |
(2.2.0) 只当点击鼠标左键时触发 |
.right |
(2.2.0) 只当点击鼠标右键时触发 |
.middle |
(2.2.0) 只当点击鼠标中键时触发 |
.passive |
(2.3.0) 以 { passive: true } 模式添加侦听器 |
<body>
<div id = "app">
<!--v-on-->
<button v-on:click="doClick">点击</button> <!--全写 单击事件-->
<button @dblclick="dodbclicked">双击</button> <!--简写 单击事件-->
<a href='https://www.bilibili.com' @click.prevent="stopEvent">哔哩哔哩</a> <!--添加阻止事件符,中断跳转默认行为-->
<br>
<div>{{count}}</div>
<button @click="addNum(1,$event)">Add</button>
<button @click="subNum(1,$event)">Sub</button>
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
message:"Hello Vue!",
num:0
},
methods:{
doClick:function(){alert("Click!");},
dodbclicked:function(){
this.message+="!"
alert("DBClick! "+this.message);
},
stopEvent:function(){alert("阻止了跳转默认行为!")},
addNum:function(n,e){
this.count += n
if(this.count%2 == 0)
e.target.style.backgroundColor = 'red';
else
e.target.style.backgroundColor = '';
},
subNum:function(n,e){
this.count -= n
if(this.count%2 == 0)
e.target.style.backgroundColor = 'red';
else
e.target.style.backgroundColor = '';
},
}
});
</script>
</body>
双向绑定指令
-
v-model 便捷设置和获取表单元素的值(双向绑定数据)
绑定数据只会和表单元素值相关联, 如: <input> <select> <textarea> 元素
![](https://img-blog.csdnimg.cn/00a3c6a7a91c449eae99e86e8fe492f1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQkPoj5zpuJ8=,size_20,color_FFFFFF,t_70,g_se,x_16)
<body>
<div id = "app">
<!--v-model-->
<!--自动清除首尾空格-->
<input type="text" v-model.trim="message" @keyup.enter="inputEnter(message)">
<!--数字相加,而非字符串拼接-->
<div>
<input type="text" v-model.number="n1"> +
<input type="text" v-model.number="n2"> =
<span>{{ n1 + n2 }}</span>
</div>
<!--非实时更新,完成后失去焦点后同步数据-->
<input type="text" v-model.lazy="message">
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
message:"Hello Vue!",
n1:0,
n2:0,
},
methods:{
inputEnter:function(text){alert(text);},
}
});
</script>
</body>
条件渲染指令
-
v-if 根据表达式的真假切换元素显示状态,原理是元素Dom操纵,实现显示隐藏,值为true存在,值为false移除(Dom)
-
v-show 根据真假切换元素的显示状态,原理是元素的display修改,实现显示隐藏, 指令后面的内容,最终会解析为布尔值,值为true显示,值为false隐藏 (Display)
频繁操作元素v-show 性能更好,初始不显示或显示频率不大v-if更好
<body>
<div id = "app">
<!--v-show v-if-->
<p v-show="isShow">vShow测试</p> <!--标签被隐藏-->
<button @click="dovShowTest">显示/隐藏测试</button>
<p v-if="type==0">vIf测试</p> <!--标签被清除-->
<p v-else-if="type==1">vElseIf测试</p> <!--else if 条件判断-->
<p v-else="type==2">vElse测试</p> <!--else -->
<input type="text" v-model.number="type">
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
isShow:true,
type:0,
},
methods:{
dovShowTest:function(){this.isShow = !this.isShow;},
}
});
</script>
</body>
列表渲染指令
数组经常和v-for结合使用,语法(item,index)in 数据,可以结合其他指令使用【item每一项,index索引】数组长度更新会同步到页面上,响应式 (官方建议绑定Key属性,字符串或数字类型,切不能重复)
<body>
<div id = "app">
<!--v-for-->
<p v-for="(item,index) in books">{{item.name}}</p>
<ul><li v-for="(item,index) in numbers">{{item.id}}.{{item.name}}</li></ul>
<table>
<thead>
<th>索引</th><th>ID</th><th>NAME</th>
</thead>
<tbody><!--for 循环最好绑定Key属性-->
<tr v-for="(item,index) in numbers" :key="item.id" :title = "item.name">
<td>{{ index }}</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
<br>
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
books:[{name:"西游记"},{name:"水浒传"},{name:"红楼梦"},{name:"三国演义"}],
numbers:[{id:1,name:'张三'},{id:2,name:'李四'},{id:3,name:'王五'},{id:4,name:'周六'}],
},
});
</script>
</body>
计算属性
实现代码的复用,数据原变化,计算属性会自动重新求值
<body>
<div id = "app">
<!--计算属性-->
<p>{{ rgb }}</p>
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
r:23,
g:52,
b:149
},
//计算属性节点
computed:{
rgb(){
return 'rgb(${this.r},${this.g},${this.b})';
}
},
});
</script>
</body>
侦听器
watch侦听器,用于监视数据变化
方法格式侦听器: 无法在刚进入页面时自动触发。侦听对象属性变化,不会触发。(最简单)
对象格式侦听器:让侦听器自动触发(immeditate)。侦听对象属性变化(deep)
<body>
<div id = "app">
<input type="text" v-model.trim="message">
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
message:"Hello Vue!",
info:{name:''},
},
//侦听器节点
watch:{
//方法格式 侦听 message 值的变化
message(newVal,oldVal){
console.log('message值变化',newVal,oldVal);
},
//对象格式 侦听
message:{
handler(newVal,oldVa){
console.log('message值变化',newVal,oldVal);
},
//控制是否自动触发,默认未false
immeditate:true,
//深度侦听,默认false
deep:true
},
info:{
handler(newVal){
console.log('info对象变化');
},
//深度侦听,默认false
deep:true
},
//若侦听时对象属性变化,需要''
'info.name'(newVal){
console.log('message值变化',newVal,oldVal);
}
},
});
</script>
</body>
过滤器
过滤器(Filters) 常用与文本格式化,过滤器可以和 v-bind 属性绑定。添加在javaScript表达式的尾部,由“管道符”进行调用,允许串联调用过滤器。filters节点下定义的是私有过滤器(Vue 3.x 不支持)。
全局过滤器:多个vue实例共享过滤器,必须在Vue实例前定义。若名称相同,就近原则调用对私有滤器
<body>
<div id = "app">
<!--过滤器-->
<!--在插值表达式中,通过“管道符” 调用capi过滤器,对message 值进行格式化-->
<p>{{message | capi}}</p>
<!--在 v-bind 中,通过“管道符”,调用fromatid过滤器,对属性值进行格式化-->
<div :id="rawid | fromatid" ></div>
<p>{{message | capiGlobal}}</p>
</div>
<script>
const vue = new Vue({
//指定当前Vue实例控制区域,值为 选择器
el:'#app',
//渲染在页面上的数据
data:{
message:"Hello Vue!",
rawid:0
},
//过滤器节点
filters:{
capi:function(val){return "TEST_FILTERS"},
fromatid:function(val){return 10086}
}
});
//定义全局过滤器
Vue.filters('capiGlobal',function(str){
return "global filter";
});
</script>
</body>
Axios 网络请求库
使用 get 或 post 方法即可发送请求。(常用)
then 方法中的回调函数会再请求成功或失败是触发 ,回调函数形参可获取返回信息。
官网:GitHub - axios/axios: Promise based HTTP client for the browser and node.js
![](https://img-blog.csdnimg.cn/8364da8a05524fc283d4726801e522f2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQkPoj5zpuJ8=,size_20,color_FFFFFF,t_70,g_se,x_16)
注:Axios回调函数中this已经改变,无法访问到data数据;将this保存,回调函数中直接使用保存的this即可。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Axios</title>
<script src="../lib/vue.js"></script>
<!--axios 导包-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<button id="btnGet">Get</button>
<button id="btnPost">Post</button>
<br>
<label id="labText"></label>
<script>
document.querySelector("#btnGet").addEventListener('click',async function(){
var url = 'http://127.0.0.1:8080/API/get';
var param = {param:{}};
//如果 调用某个方法的返回值时 'Promise' 实例,前面可以添加 await
//await 只能用于被 'async' 修饰的方法中
//await表达式会暂停当前 async function的执行,等待Promise处理完成。 如果await的promise失败了,就会抛出异常,需要通过try–catch来捕获处理。
var {data} = await axios.get(url,param);
console.log(data);
document.querySelector("#labText").innerHTML = data; //Get 请求成功![object Object]
});
document.querySelector("#btnPost").addEventListener('click',async function(){
var url = 'http://127.0.0.1:8080/API/post';
var param = {param:{}};
var {data} = await axios.post(url,param);
console.log(data);
document.querySelector("#labText").innerHTML = data; //POST 请求成功![object Object]
});
</script>
</body>
</html>