一、样式处理
1.1 Vue
中标签元素的样式主要区分为两种:
- 固定样式:传统的
css
语法,直接修饰标签元素 - 动态样式:可能会根据不同的条件发生变化,需要通过
Vue
变量数据实现控制
(1) class
样式绑定
class
样式的绑定方式有三种:字符串拼接、数组格式、对象格式(掌握)
<!DOCTYPE html>
<html lang="zh">
<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>Document</title>
<style>
#box, #box2, #box3{width: 500px; height: 200px;}
.bg-dark{background: #333; color: white;}
.bg-light{background: #eee; color: #333; box-shadow: #000 0 0 2px;}
.fontStyle{font-size: 22px; font-weight: 600;}
</style>
</head>
<body>
<div id="app">
<!-- 1、class 样式,字符串拼接方式;很少使用-->
<!-- <div id="box" :class="'bg-dark' + ' ' + 'fontStyle'"> -->
<div id="box" class="bg-dark fontStyle">
class样式设置
</div>
<!-- 2、class样式,数组格式-->
<div id="box2" :class="[bgLight, fs]">
class样式设置
</div>
<!-- 3、class样式,对象格式,可以通过变量控制某个样式是否生效 -->
<!-- 最常用的样式设置方式,使用的时候需要注意:-->
<!-- :class="{key: value}" key就是样式名称/并不是变量-->
<!-- 如果样式名称中不包含中划线,直接编写;如果包含中划线,需要在样式名称上添加引号 -->
<div id="box3" :class="{'bg-dark':isDark, fontStyle: isFs}">
class样式设置
</div>
</div>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
bgLight: 'bg-light',
bgDark: 'bg-dark',
fs: 'fontStyle',
isDark: true,
isFs: true
}
})
</script>
</html>
(style样式)
<!DOCTYPE html>
<html lang="zh">
<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>Document</title>
<style>
#box, #box2, #box3, #box4, #box5{width: 500px; height: 200px;}
.bg-dark{background: #333; color: white;}
.bg-light{background: #eee; color: #333; box-shadow: #000 0 0 2px;}
.fontStyle{font-size: 22px; font-weight: 600;}
</style>
</head>
<body>
<div id="app">
<!-- 对象格式:可以将样式直接编写到表达式中 -->
<div id="box4" :style="{backgroundColor:bgColor, color: fontColor}">
style样式设置
</div>
<!-- 对象格式:表达式中,直接填写一个对象变量 -->
<div id="box5" :style="styleObj">
style样式设置
</div>
</div>
</body>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
bgColor: 'orangered',
fontColor: 'white',
styleObj: {
backgroundColor: 'pink',
color: '#333',
fontSize: '28px'
}
}
})
</script>
</html>
二、侦听器
Vue
中提供了一种特定功能,可以监听一个受控制的变量(data
选项中声明的变量)内部的数据是否发生更新,一旦发生更新就**可以被监听(自动执行)**并执行一些后续的操作!
<!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>Document</title>
<script src="../public/js/vue.js"></script>
</head>
<body>
<div id="app">
<p>普通变量:{{message}}</p>
<p>对象数据:{{loginForm.username}}
{{loginForm.password}}
</p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message:'变量数据',
loginForm:{
username:"damu",
password:"123"
}
},
watch:{
message:function(newVal,oldVal){
console.log(newVal,oldVal,"监听器生效")
},
loginForm:{
headler(newVal,oldVal){
console.log(newVal.username,oldVal.username)
},
deep:true
}
}
})
</script>
</body>
</html>
三、计算属性
3.1: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>Document</title>
<script src="../public/js/vue.js"></script>
</head>
<body>
<div id="app">
<p>商品单价:{{price}}</p>
<p>购买数量:<input type="number" v-model="count"></p>
<p>小计金额:{{price * count}}元</p>
<p>计算属性:{{subtotal}}元</p>
<p>普通函数:{{getTotal()}}</p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
price: 600,
count: 1
},
computed: {
//内部函数包含自己的作用域,包含自己的this关键字
//如果修改为箭头函数,就回丢失this指向
subtotal: function () {
return this.price * this.count
}
},
methods: {
getTotal:function() {
return this.price * this.count
}
}
})
</script>
</body>
</html>
4、过滤器
Vue
框架针对页面上展示的数据,数据格式可以通过固定的函数进行规范;对展示数据进行格式规范的选项称为过滤器(filter
)
<!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>Document</title>
<script src="../public/js/vue.js"></script>
</head>
<body>
<div id="app">
<p>商品单价:{{ price }}</p>
<p>商品单价(全局过滤器):{{ price | priceFilter }}</p>
<p>商品单价(私有过滤器):{{ price | pfilter }}</p>
</div>
<script>
Vue.filter('priceFilter',function(val){
return parseFloat(val).toFixed(2) + "元"
})
const app = new Vue({
el:'#app',
data:{
price:600,
},
watch:{},
computed:{},
methods:{},
filters:{
pfilter:function(val) {
//局部私有过滤器,只能在当前实例范围使用
return "¥" + parseFloat(val).toFixed(3) + "元"
}
}
})
</script>
</body>
</html>
5、事件处理
Vue
中提供了v-on
的指令,用于给指定元素绑定操作事件,同时也提供了事件操作简介语法
<div v-on:click="handler"></div>
<div @click="handler"></div>
<div id='app'>
<h2>1、事件的绑定</h2>
<div class="box" v-on:click="handler">
v-on:事件名称,可以直接给元素绑定事件
</div>
<div class="box" @click="handler">
@事件名称,同样可以直接给元素绑定事件
</div>
</div>
const app = new Vue({
el: '#app',
data: {},
watch: {},
computed: {},
methods: {
handler() {
alert("用户点击了div")
}
}
})
6、事件对象
事件触发之后,可以通过事件对象,对事件处理进行功能拓展,获取事件发生对象的标签、获取鼠标位置等等
function handler(e) {
// 兼容写法
e = e || window.event
// 获取鼠标位置:可视区域位置、网页文档位置
var {clientX, clientY} = e // 相对于窗口的位置
var {pageX, pageY} = e // 相对于网页的位置
var {offsetX, offsetY} = e // 相对于点击元素的位置
}
代码操作:如何在不同的情况下,事件处理函数中获取并使用事件对象
<h2>2、事件对象</h2>
<div class="box" @click="handler2">
如果没有传递参数给处理函数,默认处理函数的第一个形式参数就是事件对象
</div>
<div class="box" @click="handler3($event, 'id12')">
如果事件处理函数需要参数;Vue默认提供了一个显式的事件对象$event,可以传递给对应的处理函数
</div>
</div>
const app = new Vue({
el: '#app',
data: {},
watch: {},
computed: {},
methods: {
handler() {...},
handler2(e) {
console.log(e, "事件对象")
},
handler3(e, id){
console.log(e, id, "传递参数的事件对象")
}
}
})
七、事件修饰符
通过原生JS事件的操作,包含很多需要预处理的问题,如事件冒泡、元素默认行为等等
// event 原生JS中如何阻止事件冒泡?
if(event.stopPropagation){
event.stopPropagation()
} else {
event.cancelBubble = true
}
// event 原生JS中如何阻止浏览器默认行为?
if(event.preventDefault){
event.preventDefault()
} else {
event.returnValue = false
}
7.1 Vue
中将原生JS中操作繁琐的方式,转换成了通过修饰符实现功能的操作方式:
系统按键修饰符
代码操作:
<h2>按键修饰符</h2> <!-- 用户同时按下ctrl + enter键,触发addMessage事件处理函数 --> <input type="text" v-model="msg" @keyup.ctrl.enter="addMessage">
addMessage() { console.log("用户按下了回车键,开始留言", this.msg) }
.stop
:阻止事件冒泡.prevent
:阻止默认行为.capture
:转换触发机制,从冒泡触发事件转变为捕获触发机制.self
:指定事件只能由当前标签自身触发.once
:一次性事件.passive
:2.3.0
Vue 还对应addEventListener
中的passive
选项]提供了.passive
修饰符。-
<!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>Document</title> <script src="../public/js/vue.js"></script> <style> .box { cursor: pointer; width: 500px; height: 100px; margin: 10px 0; background: pink; border-radius: 8px; } .outer, .inner { padding: 20px; box-shadow: #333 0 0 2px; } .outer { background: plum; } .inner { background: blueviolet; } </style> </head> <body> <div id="app"> <h2>事件的绑定</h2> <div class="box" v-on:click="handler"> v-on:事件名称,可以直接给元素绑定事件 </div> <div class="box" @click="handler"> @事件名称,同样可以直接给元素绑定事件 </div> <h2>事件对象</h2> <div class="box" @click="handler2"> 如果没有传递参数给处理函数,默认处理函数的第一个形式参数就是事件对象 </div> <!-- <div class="box" @click="handler3($event,'id12'"> 如果事件处理函数需要参数,vue默认处理函数的第一个形式参数就是事件对象 </div> --> <h2>事件修饰符</h2> <p>事件冒泡,js事件语法机制,当前元素的事件被触发之后,就回向上传递继续出发 父级元素事件称之为冒泡事件 </p> <div class="outer" @click = "handlerOuter"> <div class="inner" @click = "handleInner"> <button @click="handlerBtn">点击按钮</button> </div> </div> <p> 事件冒泡本质上是一个非常好的效果,但是有些特效场景中不需要,需要组织事件冒泡 </p> <div class="outer" @click = "handlerOuter"> <div class="inner" @click.stop = "handleInner"> <button @click="handlerBtn">点击按钮</button> </div> </div> <p> 浏览器中包含了大量的带有默认行为的元素,如表单;操作过程中可能需要组织 </p> <form action="https://www.baidu.com/s?"> 搜索:<input type="text" v-model="kw"> <button @click.prevent="handlerSearch">点击搜索</button> </form> <p> 时间的触发:补货阶段、触发阶段、冒泡阶段、触发机制默认是冒泡触发,vue提供了一种操作可以在捕获时直接触发 </p> <div class="outer" @click.capture ='handlerOuter'> <div class="inner" @click.capture = 'handlerInner'> <button @click = 'handlerBtn'>捕获触发</button> </div> </div> <p> 特定场景中,事件只能有当前标签自身触发 </p> <div class="outer" @click.capture ='handlerOuter'> <div class="inner" @click.capture = 'handlerInner'> <button @click = 'handlerBtn'>捕获触发</button> </div> </div> <p>针对特殊的一次性事件,提供了.once修饰符</p> <div class="outer" @click.once = 'handlerOuter'> <div class="inner" @click.once = 'handleInner'> <button @click = "handlerBtn">点击按钮</button> </div> </div> <h2> 按键修饰符 </h2> <input type="text" v-model="msg" @keyup.enter = 'addMessage'> </div> <script> const app = new Vue({ el: '#app', data: { kw: "", msg: "" }, wathc: {}, computed: {}, methods: { handler() { alert('用户点击了div') }, handler2(e) { console.log(e, '事件对象') }, handler3(e, id) { console.log(e, id, '传递参数的事件对象') }, handlerBtn() { alert('用户点击了按钮') }, handleInner() { alert('用户点击了div inner') }, handlerOuter() { alert('用户点击了div outer') }, handlerSearch() { if (this.kw.trim().length > 0) { alert('提交搜索'); window.location.href = "https://www.baidu.com/s?wd" + this.kw } else { alert('数据不完善,验证失败') } }, addMessage() { console.log('用户按下了回车键,开始留言', this.msg,console.log(msg)) } } }) </script> </body> </html>
八、按键修饰符
-
一般标签上的事件在操作 过程中,也可以结合键盘按键触发对应的 事件,如按下回车执行!
原生JS中主要通过事件对象的
keyCode
属性判断某个按键被按下;Vue
中提供了内建的按键修饰符以及扩展的可以让开发人员自定义的按键修饰符,让键盘按键完全参与到事件操作中内建按键修饰符
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.ctrl
.alt
.shift
.meta
.down
.left
.right
-
九、表单绑定
-
<!DOCTYPE html> <html lang='zh'> <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>Document</title> </head> <body> <div id='app'> <form> <div> <label>账号:</label> <input type="text" v-model="userForm.username"> <span>val:{{ userForm.username }}</span> </div> <div> <label>密码:</label> <input type="password" v-model="userForm.password"> <span>val:{{ userForm.password }}</span> </div> <div> <label>性别:</label> <input type="radio" name="gender" v-model="userForm.gender" value="男">男 <input type="radio" name="gender" v-model="userForm.gender" value="女">女 <span>val:{{ userForm.gender }}</span> </div> <div> <label>年龄:</label> <input type="number" v-model="userForm.age"> <span>val:{{ userForm.age }}</span> </div> <div> <label>爱好:</label> <input type="checkbox" v-model="userForm.fav" value="LOL">LOL <input type="checkbox" v-model="userForm.fav" value="英雄联盟">英雄联盟 <input type="checkbox" v-model="userForm.fav" value="艾尔登法环">艾尔登法环 <span>val:{{ userForm.fav }}</span> </div> <div> <label>生日:</label> <input type="date" v-model="userForm.birthday"> <span>val:{{ userForm.birthday }}</span> </div> <div> <label>地址:</label> <select v-model="userForm.address"> <option value="郑州">郑州</option> <option value="广州">广州</option> <option value="杭州">杭州</option> <option value="柳州">柳州</option> </select> <span>val:{{ userForm.address }}</span> </div> <div> <label>介绍:</label> <textarea v-model="userForm.intro" cols="30" rows="5"></textarea> <span>val:{{ userForm.intro }}</span> </div> <div> <label>头像:</label> <input type="file" v-model="userForm.header"> <span>val:{{ userForm.header }}</span> </div> <button @click="submit">提交</button> </form> </div> <script src='./vue.js'></script> <script> const app = new Vue({ el: '#app', data: { userForm: { username: '', // 账号- 文本输入框 password: '', // 密码- 密码输入框 gender: '' , // 性别- 单选按钮 age: 0, // 年龄- 数值输入框 fav: [], // 爱好- 复选框 birthday: '', // 生日- 日期选择框 address: '', // 地址- 下拉列表框 intro: '', // 介绍- 多行文本框/文本域 header: '' // 头像- 文件域 } }, watch: {}, computed: {}, methods: { submit() { console.log("提交表单", this.userForm) } } }) </script> </body> </html>