Vue 事件处理 事件修饰符 表单处理 表单修饰符 双向绑定 生命周期 钩子函数
1-事件处理
1.1-事件绑定
-
通过
v-on:事件名称="事件处理函数"
绑定事件<button v-on:事件名称="事件处理函数">按钮</button>
1.2-事件传参
-
通过事件处理函数后的
()
传递参数即可<button v-on:事件名称="事件处理函数(参数)">按钮</button>
1.3-事件对象
-
无需给事件处理函数传递额外参数
系统会自动注入事件对象, 直接在事件处理函数定义的位置通过形参接受即可
const vm=new Vue({ el:'#app', data:{ }, methods:{ // 键盘事件处理函数, e是系统自动注入的事件对象 checkUser(e){ console.log(e.target.value); } } });
-
需要给事件处理函数传递额外参数
$event
是一个系统变量, 代表事件对象<input type="text" placeholder="请输入用户名" @keyup="checkUser($event,'hello')"/> <script> const vm=new Vue({ el:'#app', data:{ // 错误提示信息 tips:'' }, methods:{ // 键盘事件处理函数, e是系统自动注入的事件对象 checkUser(e,msg){ // 系统已经存在的用户名 const users=['admin','jack','tom','rose']; const username=e.target.value.trim(); if(username===''){ return this.tips='请输入用户名'; } if(users.indexOf(username)===-1){ // 更新tips: 用户名可以 return this.tips='恭喜你, 用户名可用'; } this.tips='用户名不可用'; } } }); </script>
1.4-事件修饰符
-
作用: 限制事件触发的条件
-
语法
@事件名称.事件修饰符="事件处理函数"
1.4.1-stop
- 作用: 阻止事件冒泡
<div id="app">
<div class="wrap" @click="wrapClick">
<!-- 使用事件修饰符stop, 阻止事件冒泡 -->
<div class="box" @click.stop="boxClick"></div>
</div>
</div>
1.4.2-prevent
- 作用: 阻止默认行为
<a href="http://baidu.com" @click.prevent="handle">a标签</a>
1.4.3-once
- 作用: 限定事件只执行一次
<!--使用事件修饰符once, 限制事件只执行一次-->
<button @click.once="handle">按钮</button>
1.4.4-self
- 作用: 限定事件只能被自己触发(不能被冒泡行为触发)
<!-- self是限定事件只能由元素自己触发, 不能被冒泡行为触发 -->
<div class="wrap" @click.self="wrapClick">
<div class="box" @click="boxClick"></div>
</div>
1.4.5-capture
-
作用: 修改事件触发的顺序(事件触发顺序变成由外向内)
<div class="wrap" @click.capture="wrapClick"> <div class="box" @click="boxClick"></div> </div>
1.5-按键修饰符
-
作用: 修饰键盘事件, 限制键盘事件的触发时机
-
语法
@事件名称.按键修饰符="事件处理函数"
-
系统内置的按键修饰符
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
2-表单处理
2.1-v-model指令
- 作用: 实现双向数据绑定(数据层<=>视图层)
- 注意: v-model指令只能在表单元素上使用
<div id="app">
<!-- v-model: 可以将用户的输入自动同步到数据层 -->
<h1>{{keywords}}</h1>
<hr>
<input type="text" placeholder="请输入搜索关键词" v-model="keywords">
<button @click="search">搜索</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
keywords:''
},
methods: {
search(){
console.log(this.keywords);
}
}
});
</script>
2.2-常见表单元素双向数据绑定
<div id="app">
<!-- v-model: 可以将用户的输入自动同步到数据层 -->
<div>
<input type="text" v-model="user.name" placeholder="姓名">
</div>
<div>
<input type="radio" value="男" v-model="user.sex">男
<input type="radio" value="女" v-model="user.sex">女
</div>
<div>
<input type="checkbox" value="学习" v-model="user.hobby">学习
<input type="checkbox" value="读书" v-model="user.hobby">读书
<input type="checkbox" value="弹钢琴" v-model="user.hobby">弹钢琴
</div>
<div>
<!-- multiple:实现多选 -->
<select v-model="user.language" multiple>
<option value="vue">vue</option>
<option value="react">react</option>
<option value="angular">angular</option>
</select>
</div>
<div>
<textarea v-model="user.introduce" cols="30" rows="2" placeholder="个人简介"></textarea>
</div>
<div>
<button @click="submit">立即提交</button>
</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
user:{
name:'',
hobby:[],
sex:'',
language:[],
introduce:''
}
},
methods: {
submit(){
// 获取用户输入
console.log(this.user);
}
}
});
</script>
2.2-表单修饰符
2.2.1-书写位置
一般是个v-model指令结合起来使用
2.2.2-语法规范
v-model.表单修饰符="数据对象"
-
trim
- 作用: 自动去除用户输入内容的首位空格
-
number
- 作用: 将用户输入内容自动转换成数值类型, 对于无法转换成数值的内容, 不会处理
-
lazy
- 作用: 延迟数据同步, 当失去焦点的时候, 再将数据同步到数据层(v-model默认会实时同步数据)
3-vm.$set
- vm.$set(操作的数组或者对象,数组下标或者对象属性名,值): vm代表vue实例对象
通过数组下标操作(新增/更新)数组元素, 不会触发视图的刷新;
通过赋值的方式给对象动态添加属性, 不会触发视图的更新;
使用$set方法添加的数组元素或对象属性可以触发视图的更新;
3.1-作用
- 通过下标添加或者修改数组元素(传统赋值方式无法触发视图更新)
- 给对象动态添加元素(传统赋值方式无法触发视图更新)
3.2-别名
- Vue.set(操作的数组或者对象,数组下标或者对象属性名,值);
4-vue核心原理
4.1-双向数据绑定(数据劫持)
-
通过
Object.defineProperty(所属的对象,属性名,{get(){},set(){}})
定义的数据的读取和赋值, 都可以被监听到<body> <h1>Object.defineProperty()实现数据劫持</h1> <hr> <h1 id="h1"></h1> </body> <script> // Object.defineProperty(所属的对象,属性名,{get(){},set(){}})定义数据的另外一种方式 // 定义了一个全局变量msg Object.defineProperty(window,'msg',{ get(){ //get访问器: 当读取数据msg的时候, 会被触发 console.log('get'); // 需要在此处指定变量的值 return 'msg的初始值'; }, // value是一个系统自动注入的参数, 代表的是msg最新的赋值 set(value){ // set访问器: 当对数据msg进行二次赋值的时候, 会被触发 // 应用场景: 通过视图更新(vue底层会在此处触发模板的重新编译) console.log('set',value); // 通知视图更新 document.querySelector('#h1').innerHTML=value; } }); // console.log(msg); // 读取数据, 会自动触发get方法的执行 // msg='hello'; // 重新赋值, 会自动触发set方法的执行 // 页第一加载的时候,输出的内容 const h1=document.querySelector('#h1'); h1.innerHTML=msg; </script>
4.2-模板编译(正则替换)
- 模板编译底层主要是通过正则替换来实现的
class Vue{
// 系统方法, 自动执行, 进行数据初始化
// props={el:'#app',data:{},methods:{}}
constructor(props){
// 将data中的数据,挂载到this上
for(let key in props.data){
this[key]=props.data[key];
}
// 将methods中的方法,挂载到this上
for(let key in props.methods){
this[key]=props.methods[key];
}
// 将模板对应的选择器挂载到this上, 方便在其他方法中获取
this.$el=props.el;
// 调用一次渲染方法
this.render();
}
// 渲染方法(模板编译)
render(){
// 获取对应的dom对象
const app=document.querySelector(this.$el);
// 编写正则表达式
const reg=/\{\{(\w+)\}\}/g;
const html=app.innerHTML.replace(reg,(a,b)=>{
// a:是整个正则表达式匹配到的结果
// b:是()子表达式匹配到的结果
return this[b]
});
// 刷新视图
app.innerHTML=html;
}
}
5-生命周期钩子函数
- 本质: 一种特殊的函数, 会在vue实例创建, 运行,销毁阶段的不同时期自动触发
- 注意: 钩子函数是vue 在完成特定操作之后, 通知我们的一种方式
- 写书位置: 和data,methods平级
5.1-创建阶段
特点
- 只执行一次
钩子函数
- beforeCreate: 创建前(还没有完成数据和方法的创建, 数据和方法还不能使用)
- created: 创建后(完成数据和方法的创建,可以调用数据和方法)
- boforeMount: 挂载前(还没有完成视图的渲染)
- mounted: 挂载后(已经完成了视图的渲染)
5.2-运行阶段
特点
- 执行次数不确定
- 只有在视图中引用过的data数据更新的时候, 才会被触发
钩子函数
- beforeUpdate: 更新前(还没有完成视图更新)
- updated: 更新后(已经完成了视图更新)
5.3-销毁阶段
特点
- 执行一次
钩子函数
- beforeDestroy: 销毁前
- destroyed: 销毁后