vue中事件绑定在vue中事件绑定时,es6中原生写法event
在vue中需要增加$符号,使用$event
在vue事件中,阻止默认点击或提交的默认事件使用.prevent
,在vue中的阻止冒泡是使用.stop
来操作,vue中的点击事件需放置到methods
方法对象中vue绑定事件中常用代码及案例代码如下:
vue中代码 | es6中代码 | 说明 |
---|---|---|
v-on:click/简写@ | 点击,回车等事件时,一般都是原生是以on开头,onclick | 在vue中使用指令v-on简写@ |
$evnet | event | 在vue中与原生es6不同,增加了一个修身符号$ |
.prevent | .preventDefault() | 阻止默认点击事件,在vue中更简单,使用.prevent |
.stop | .defaultPrevented() | 在vue中阻止冒泡直接使用.stop |
新增方法对象methods:用于点击事件自定义事件值的函数放置在内中 |
代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<!-- es6事件绑定写法 -->
<p>
<a href="http://www.php.cn" onclick="geturl()">es6事件绑定写法</a>
<span class="url"></span>
</p>
<script>
function geturl(ele) {
///阻止默认点击事件
event.preventDefault();
// 获取当前点击事件的标签主体
const link = event.currentTarget;
const link2 = event.target;
console.log(link);
console.log(link2);
// 标签主体的下一个兄弟的,文本= link的url
link2.nextElementSibling.textContent = link2.href;
}
</script>
<!-- vue3的写法 事件绑定 -->
<div class="app">
<p>
<!-- v-on是一个点击事件指令 简写符号为@ -->
<!-- es6中原生的evnet 但是在vue中是$evnet -->
<a href="http://php.cn" v-on:click="showurl($event)">vue3中实现双向绑定事件</a>
<span class="url">{{url}}</span>
</p>
<!-- ///////事件修饰符///////////// -->
<!-- 通过修饰符来禁止默认事件 使用 .prevent -->
<p>
<!-- 这里其实很好理解,this就是实例app中,url呢就是app中的url -->
<a href="http://php.cn" @click.prevent="this.url = $event.target ">VUE3中 事件修饰符的阻止默认事件实现</a>
<span class="url">{{url}}</span>
<!-- ////////////vue中的事件冒泡行为///////// -->
</p>
<p onclick=" alert('写作业中') ">
<!-- 这里其实很好理解,this就是实例app中,url呢就是app中的url -->
<!-- 这里事件已经进行了冒泡 所以用什么行为阻止呢? 使用.stop -->
<a href="http://php.cn" @click.prevent.stop="this.url = $event.target ">VUE3中 事件修饰符的实现阻止事件冒泡</a>
<span class="url">{{url}}</span>
</p>
</div>
<script>
const app = Vue.createApp({
data() {
return {
url: null,
};
},
// 在原生的es6中,我们的点击事件是对应function函数的,但是在vue中是使用methods的
// 所以这里的点击事件要写到methods函数中 就是把functon写到这个函数中
methods: {
// {}是一个对象,所以可以放多个值
// 把点击事件的showurl方法写到里面
showurl(ev) {
// 阻止默认事件
ev.preventDefault();
// 我们看到在vue3中点击事件中的$event就等于es6中的event
console.log(ev);
console.log(ev === event); //测试一下,发现页面输出的是true
// console.log(this);这里打印的发现,这个this是vue中的实例
console.log(ev.target);
// 一直好奇target跟currentTarget 哪儿会有区别 每次看到target就像反着用curr来测试
// this.url = ev.target.href;
this.url = ev.currentTarget.href;
},
},
}).mount(".app");
</script>
</body>
</html>
示例截图(没给画图):
列表渲染之 for of列表的渲染其实分为三部分:1.数组渲染2.对象渲染3.数组中对象的渲染以及for of中 尽量都加一个v-bind:key指令,为提高效率使用diff算法数组渲染的格式是for(值,索引) of 数组而对象的渲染和对象的渲染稍微有一点不同格式是:for(值,键,索引) of 对象数组中对象的渲染,其实和数组渲染类似for(值,索引) of 对象剩下的使用部分和es6中其实是类似的写法,具体请看下面的代码吧代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div class="app">
<ul>
<li>{{cities[0]}}</li>
<li>{{cities[1]}}</li>
<li>{{cities[2]}}</li>
<li>{{cities[3]}}</li>
</ul>
<!-- array:指令 v-for ,对应es6中原生的for of -->
<!-- 下面是改写的方法 -->
<ul>
<!-- 指令的写法 -->
<!-- 从实例中就可以看出,cities是一个数组,city是数组每个成员赋给city -->
<!-- 那遍历的li标签内就应该放置city -->
<!-- 而且v-for指令支持索引,索引跟数组的每个成员是一个组合 -->
<li v-for="city of cities">{{city}}</li>
<li>---------------</li>
</ul>
<!-- 为了提交效率,为了借助diff算法,使用v-for指令时,需加一个v-bind:key指令,也就是:key指令 -->
<li v-for="(city,index) of cities" :key="index">数组中索引是{{index}},值是{{city}}</li>
</ul>
<!-- ///////用v-for指令遍历obj对象////// -->
<ul>
<!-- prop->property 代表属性 也就是当前对象的键 -->
<!-- item代表的是值,index代表的是索引 -->
<li v-for="(item,prop,index) of user" :key="index" > 对象中的键为:{{prop}},值为:{{item}},既然对象也是一个数组,那么输出一下他的索引{{index}} </li>
</ul>
<!-- //////开发中用到比较多的对象数组//////// -->
<ul>
<!-- 遍历一个数组 数组里面都是对象 -->
<!-- 数组是没有键的 -->
<!-- 当前item等于数组的值,也就是对象 -->
<li v-for="(item,index) of users" :key="index" >{{item.name}}"他的邮箱是"{{item.email}}</li>
</ul>
</div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
// 先创建一个数组 array
cities: ["济南", "青岛", "北京", "上海"],
//object对象遍历
user:{name:"老王",
email:"123456@qq.com"},
///声明一个数组对象 arr-obj
users:[
{name:"老王",
email:"123456@qq.com"},
{name:"老刘",
email:"11211111@qq.com"},
{name:"老炸",
email:"22222222@qq.com"},
],
};
},
}).mount(".app");
</script>
</html>
示例截图(家里电脑小,将就一下吧,改天赚钱买个大的学前后端,给点力啊):
条件渲染之v-if/多分支v-else-if条件渲染部分一般使用v-if及多条件判断v-else-if来判断,并且下面演示中,在v-text中使用了es6中的,条件判断(简写的语法)代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<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>
<script src="https://unpkg.com/vue@next"></script>
<!-- vue三部曲,引入,建立挂载点,然后实例挂载,学习中,感觉卡卡卡出来这么多代码 好有成就感...... -->
</head>
<body>
<div class="app">
<!-- v-if指令 单分支判断 -->
<!-- 在p标签增加一个v-if指令 -->
<p v-if="metrue">{{message}}</p>
<!-- 点击事件,这里=!metrue是取反结果的意思, -->
<!-- 其中v-text中语法与es6中一样,不过要注意"及' -->
<button @click="metrue=!metrue" v-text="metrue ? '行' : '不行' "></button>
<!-- /////////////多分支 if else if else else vue中的写法 -->
<p v-if="point>=500 && point < 1000">{{namevip[0]}}</p>
<p v-else-if="point>=1000 && point < 2000">{{namevip[1]}}</p>
<p v-else="point>=2000">{{namevip[2]}}</p>
</div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
// 将在p标签显示的内容,赋值给一个变量
message: "今晚可能写不完作业,明天再写,行不行?",
// 创建一个是否显示的标志
metrue: true,
namevip: ["月会员", "季会员", "年会员"],
point: 3000,
};
},
}).mount(".app");
</script>
</html>
示例截图:vue事件之键盘事件+数组方式参数传递此部分使用了键盘事件,演示了当用户提交一个值的使用方式,以及用户添加多个值的添加方式,其中又重新使用了es6中的.unshift给数组内传递N+参数,以及使用了昨天的v-for of方式循环遍历输出到页面中代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>键盘事件指令</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div class="app">
<input type="text" @keydown="submint($event)" />
<ul>
<li>
{{item}}
</li>
</ul>
<hr></hr>
<input type="text" @keydown="submint2($event)" />
<ul>
<!-- 昨天刚做了v-for 今天差点忘了,模模糊糊写出来,还错了 又改的 -->
<li v-for="(item2,index) of list" @key="index">
{{item2}}
</li>
</ul>
</div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
item: "", //但个值不行,那么启动数组方式
list: []
};
},
methods: {
submint(ev) {
console.log(ev.key);
// 如果ev.key = Enter
if (ev.key === "Enter") {
// 那么ev函数获取到当前标签的value字段赋值给this实例里面的item
this.item = ev.currentTarget.value;
}
},
// 数组模式
submint2(ev) {
if (ev.key === "Enter") {
// 回顾es6知识,.unshift是向数组内添加一个或者多个元素,所以这里是传参,其中unshift()括号内就是要传的参数
this.list.unshift(ev.currentTarget.value)
// 传参完毕后给value框清空操作
ev.currentTarget.value = null
}
}
},
}).mount(".app");
</script>
/////////////////下面的这个是老师使用修饰符语法糖写的,原理是一样,///////
看看有啥区别?其实就是当我这个键按下的是Enter回车键时就调用这个方法
<body>
<div class="app">
<!-- <input type="text" @keydown="submit($event)" /> -->
<input type="text" @keydown.enter="submit($event)" />
<ul>
<li v-for="(item,index) of list" :key="index">{{item}}</li>
</ul>
</div>
<script>
Vue.createApp({
data() {
return {
list: [],
}
},
methods: {
submit(ev) {
// console.log(ev.key)
// if (ev.key === 'Enter') {
// this.list.unshift(ev.currentTarget.value)
// ev.currentTarget.value = null
// }
this.list.unshift(ev.currentTarget.value)
ev.currentTarget.value = null
},
},
}).mount('.app')
</script>
</body>
</html>
</html>
示例截图:
vue计算属性/访问器属性案例:购物车价格计算流程,先通过访问器属性computed:计算出价格总和,再通过这侦听器属性watch:来侦听当前的总价格变化,watch:侦听器内总价格的属性有2个值,一个是新值,一个是旧值,侦听这两个值,然后对新值进行折扣计算,折扣计算后watch里面的值的属性,最后都会归并到data实例中,通过实例打入app页面html中,在watch中进行价格计算computed:
访问器属性来计算mon的值,最后会返回到data实例中示例区块代码:
//访问器计算属性 是: 不是()函数 找错误找了半天 靠
computed: {
mon: {
get() {
return this.price * this.num;
},
},
},
watch:
侦查器属性讲需要循环判断的代码放到侦查器属性中,类似下面的mon总和的值,来侦听总和的值区块示例代码:
// 侦听器属性 来通过值的变化来判断折扣结果
watch: {
//侦听当前总金额的变化
// 侦听属性的变化有2个值,侦听的那个属性的当前的值,和原值/旧值
// mon(当前的值/新值,原值/旧值)
mon(mona, monb) {
console.log(mona, monb); //在这里就是侦听购物车的当前价格 和原来的价格
switch (
true //循环判断开始
) {
case mona >= 500 && mona < 1000:
// 折扣的价格 actualmon 就等于原价*折扣价格
this.actualmon = this.mon * 0.9;
break;
default:
// 无折扣情况下就默认价格
this.actualmon = this.mon;
break;
}
// 实际中折扣了多少钱 不就是原价-折扣后的价格?
this.discountmon = this.mon - this.actualmon; //最后合并到data示例中
},
},
声明周期函数:mounted(){}
mounted() {
this.num = 1; //这里要注意的是 num 的1 必须要比data中实例的1要大
},
代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/vue@next"></script>
<title>vue中的访问器属性计算属性侦听器属性</title>
</head>
<body>
<!-- <div class="app">{{a}}+{{b}}={{sum}}</div> -->
<div class="app">
<table>
<caption>
购物车
</caption>
<thead>
<tr>
<th>ID</th>
<th>品名</th>
<th>单价</th>
<th>数量</th>
<th>金额</th>
</tr>
</thead>
<tbody>
<tr>
<td>HA110</td>
<td>蒙牛纯牛奶</td>
<td>{{price}}</td>
<!-- 使用:value属性是错误的,更新数量时,在页面中与实例中的num值始终绑定的,不会更新 -->
<!-- <td><input type="number" :value="num"></td> -->
<!-- 该怎么样绑定数量更新呢? 使用v-model 双向绑定-->
<td><input type="number" v-model="num" /></td>
<!-- <td>{{price*num}}</td>//数量等于50 -->
<!-- 下面使用计算属性进行计算金额的值 -->
<td>{{mon}}</td>
</tr>
</tbody>
</table>
<!-- <p>实付金额为:{{actualmon}},原价为:{{mon}},折扣了{{mon-actualmon}}</p> -->
<p>实付金额为:{{actualmon}},原价为:{{mon}},折扣了{{discountmon}}</p>
<!-- 通过在侦听器上增加一个属性,赋值给折扣价格discountmon -->
<!-- //{{discountmon}} -->
</div>
</body>
<!-- <script>
const app = Vue.createApp({
data() {
return {
a: 1,
b: 2,
};
},
// 计算属性//也就是es6中的访问器属性
// vue中计算属性有个语法糖为 computed
computed: {
// 本身computed就是访问器属性 get sum:前面的get可以不要了,但不代表不写,需要写到里面
sum: {
get() {
return this.a + this.b;
},
},
},
}).mount(".app");
</script> -->
<script>
const app = Vue.createApp({
data() {
return {
price: 50,
num: 0,
};
},
//访问器计算属性 是: 不是()函数 找错误找了半天 靠
computed: {
mon: {
get() {
return this.price * this.num;
},
},
},
// 侦听器属性 来通过值的变化来判断折扣结果
watch: {
//侦听当前总金额的变化
// 侦听属性的变化有2个值,侦听的那个属性的当前的值,和原值/旧值
// mon(当前的值/新值,原值/旧值)
mon(mona, monb) {
console.log(mona, monb); //在这里就是侦听购物车的当前价格 和原来的价格
switch (
true //循环判断开始
) {
case mona >= 500 && mona < 1000:
// 折扣的价格 actualmon 就等于原价*折扣价格
this.actualmon = this.mon * 0.9;
break;
default:
// 无折扣情况下就默认价格
this.actualmon = this.mon;
break;
}
// 实际中折扣了多少钱 不就是原价-折扣后的价格?
this.discountmon = this.mon - this.actualmon; //最后合并到data示例中
},
},
// 当开发完上面的之后,你发现保存后的价格并没有真实的改变,就是没初始化,需要初始化一下当前的价格
mounted() {
this.num = 1; //这里要注意的是 num 的1 必须要比data中实例的1要大
},
}).mount(".app");
</script>
<style>
table {
width: 26em;
text-align: center;
border-collapse: collapse;
}
table caption {
font-size: 1.5em;
margin-bottom: 0.6em;
}
thead {
background-color: lightcyan;
}
th,
td {
border: 1px solid #000;
height: 2em;
}
</style>
</html>
代码已完成 来看看截图吧
vue注册组件之自定义标签说的可能不太明白,请看1月14日的视频注册组件需要用vue自带的属性app.component 来实现,且有两个值,一个值为注册标签的名字,第二个为,标签的行为,比如我注册一个标签名字为ButtonCounter,后面他的行为就是一个点击按钮,后面的行为需要放到{}中,并且行为要放到一个系统自带的template属性中,注册的标签需放到html中,因为html不区分大小写,所以标签的命名需改为蛇形命名,如:ButtonCounter,在html页面中需改为button-counter
第二种,与html结合放到页面中放到页面中,需要在页面放到<template id="counter"></template>标签中,然后再注册组件的内部,绑定template的id,然后将html再放到html中,请注意下面的代码部分属性代码:app.component
注册组件/标签template
模板参数ButtonCounter 自定义属性,遇大写蛇形命名传递到html页面props
向html的template中传递ButtonCounter中的参数(向子组件传参)
///////////////////////////////////////声明多个组件,可以使用compoents,需在主组件下面声明//////////////////看看截图吧,没事需要看看手册
代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/vue@next"></script>
<title>vue组件全局组件</title>
</head>
<body>
<div class="app">
<div v-text="'hello'"></div>
<!-- vue自定义标签组件 -->
<!-- 自定义组件如果名称有大小写,需要将大小写改成小写且改成蛇形命名 -->
<button-counter></button-counter>
</div>
<!-- ///////////////////第二个自定义标签//////// -->
<template id="counter">
<button @click="count++">点赞: {{count}}</button>
</template>
</body>
<script>
const app = Vue.createApp({});
//注册组件 创建组件,创建组件时,组件要放到app实例的外面
// 组件的名称就是app.component('组件名称',{组件的行为});
app.component("ButtonCounter", {
// 使用template属性声明一下,注意template 是vue自带的属性,不可更改
// template: '<button @click="count++" >点赞{{count}}</button>',
// 将tmplate的值进行和html绑定,绑定到页面中,需使用template包裹,且定义一个id 如下定义了一个counter
template: "#counter",
data() {
return {
count: 0,
};
},
});
// 创建组件时,挂载要延时挂载,感觉意义上是,实例下面写自定义组件,到最后部分,才进行绑定到app示例中,然后渲染到html页面中
app.mount(".app");
</script>
</html>
示例截图:
注册组件之向子属性传参:上面说的是全局组件,下面是全局组件下子组件传参,通过向子组件template中传参,当自定义标签也就是父组件button-counter中有多个属性时,向子组件传参,通过props数组传递到html页面的template子组件中
代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue子组件的传参</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div class="app">
<button-counter username="admin" email="123456@qq.com"></button-counter>
</div>
<template id="counter">
<button @click="count++">点赞: {{count}}</button>
<p>{{username}}</p>
<p>{{email}}</p>
</template>
</body>
<script>
// 1. 创建实例
const app = Vue.createApp({});
// 2. 注册组件
app.component("ButtonCounter", {
props: ["username", "email"],
template: "#counter",
data() {
return {
count: 0,
};
},
});
// 3. 绑定挂载点
app.mount(".app");
</script>
</html>
示例截图:
子组件向父组件传参 自己感觉流程就是,首先在子组件使用$emit()参数,在子组件html中定义一个自定义事件,然后再父组件进行监听,监听的参数就是子组件的自定义事件,值是自定义的一个事件方法事件的方法需要写在”创建的实例的data中“,因为@review-count是一个自定义事件,所以使用methods:{},把事件的值放到里面接收,当前的值就是review,当得到了值的结果时,然后进行处理,比如判断下面是老师的意思
$emit(customEvent, ...args)
2.2 父组件: @customEvent(...args)
args可以是多个参数,可能是数组吧,这句话是我说的,不是老师一遍看不懂,就多看几遍吧代码部分:```php<!DOCTYPE html><html lang="zh-CN">
<head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>vue子组件的传参</title> <script src="https://unpkg.com/vue@next"></script></head>
<body> <div class="app"> <!-- 增加reviewCount增加监听自定义事件,调用一个方法,review自己写的,不是vue带的,来监听这个方法 --> <button-counter username="admin" email="123456@qq.com" @review-count="review"></button-counter> </div> <template id="counter"> <button @click="count++">点赞: {{count}}</button> <p>{{username}}</p> <p>{{email}}</p> <!-- 想拿到点赞数,就要搞清原理,点击触发是在button上触发,就像向父组件button-counter传递, --> <!-- 类似订阅事件,一对多触发,只要点击了事件就触发下面所有的功能走一遍 --> <!-- $emit()是一个方法,是一个发布,触发,发射的意思,支持两个参数,第一个是自定义事件,最终会被注册到发布订阅的调度中心,也是个数组,调度中心 --> <!-- 第二个是向父组件传递的参数 ,不一定有,需要就有,不需要就没有 --> <!-- $emit(自定义事件,向父组件传递的参数[可选]) 当写到这里的时候,需要在父组件,button-counter添加一个事件,来订阅接收,添加的自定义事件就是emint中的自定义事件,也就是监听自定义事件--> <button @click="$emit('reviewCount',this.count)">评价</button> </template></body>
<script> // 1. 创建实例 const app = Vue.createApp({ methods: { review(count) { console.log(count); if (count >= 5) { alert(“太牛了”); } }, }, });
// 2. 注册组件
app.component("ButtonCounter", {
props: ["username", "email"],
template: "#counter",
data() {
return {
count: 0,
};
},
});
// 3. 绑定挂载点
app.mount(".app");
</script><!-- 自己感觉流程就是,首先在子组件使用$emit()参数,在子组件html中定义一个自定义事件,然后再父组件进行监听,监听的参数就是子组件的自定义事件,值是自定义的一个事件方法 --><!-- 事件的方法需要写在”创建的实例的data中“,因为@review-count是一个自定义事件,所以使用methods:{},把事件的值放到里面接收,当前的值就是review,当得到了值的结果时,然后进行处理,比如判断 --><!-- 下面是老师的意思 --><!-- // 1. 向子组传传参: props: [....] --><!-- // 2. 子组件向父组通信: --><!-- // 2.1 子组件: $emit(customEvent, ...args) --><!-- // 2.2 父组件: @customEvent(...args) --><!-- args可以是多个参数,可能是数组吧,这句话是我说的,不是老师 -->
</html>```示例截图:
相关推荐
© 2020 asciim码
人生就是一场修行