Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:
首先写一端Html,添加一些事件
<div class="app">
<p onclick="console.log('hello world')">
<!-- 事件属性 -->
<!-- .prevent.stop: 事件修饰符, prevent禁用默认行为,stop: 防止冒泡 -->
<a href="https://www.php.cn" @click.prevent.stop="showUrl($event)">show URL(Vue) : </a>
<span class="url">{{url}}</span>
</p>
</div>
vue代码
methods 当前属性中的事件对象
<script>
Vue.createApp({
// 实例数据
data() {
return {
// 插值变量
url: null,
};
},
// 事件方法
methods: {
showUrl(ev) {
// 禁用默认行为
// ev.preventDefault();
// 防止事件冒泡
// ev.stopPropagation();
// 上面两个禁用可以使用这个语法直接一步达成(写在html代码中).prevent.stop: 事件修饰符, prevent禁用默认行为,stop: 防止冒泡
this.url = ev.currentTarget.href;
},
},
}).mount('.app');
</script>
首先有一组vue数据
<script>
const app = Vue.createApp({
data() {
return {
// array
cities: ['合肥', '苏州', '南京'],
// object: 关联数组
user: {
name: '猪老师',
email: 'laozhu@php.cn',
},
// array of object
users: [
{
name: '猪老师',
email: 'laozhu@php.cn',
},
{
name: '灭绝老师',
email: 'miejue@php.cn',
},
{
name: '欧阳老师',
email: 'ouyang@php.cn',
},
],
};
},
}).mount('.app');
</script>
列表渲染就是将类或者对象,在页面中渲染出来
1.通过列表的方式,在列表中直接调用模板字面量,接收数据(如果在后面通过指定健名的方式,可以调用数组中的某一个指定数据)
<div class="app">
<!-- array -->
<ul>
<li>{{cities[0]}}</li>
<li>{{cities[1]}}</li>
<li>{{cities[2]}}</li>
</ul>
</div>
2.V-for循环输出
V-for也会接收两个值,就是当前遍历的值和对应的健名,就比如我们下方代码用city和index来接收
<ul>
<!-- <li v-for="city of cities">{{city}}</li> -->
<li v-for="(city,index) of cities" :key="index">{{index}} : {{city}}</li>
</ul>
3.V-for 输出对象数组
<!-- v-for: 对象数组 -->
<ul>
<li v-for="(user,index) of users" :key="index">{{user.name}} : ({{user.email}})</li>
</ul>
首先创建一个vue数据
Vue.createApp({
data() {
return {
message: '今天是前端最后一课',
flag: true,
// 会员级别
grade: ['纸片会员', '木头会员', '铁皮会员', '金牌会员', '非会员'],
// 积分
point: 3500,
};
},
}).mount('.app');
然后我们需要在页面中有条件的显示数据内容,可以通过v-if
v-if
注释:
1.首先如果flag为真 显示模板字面量关联的数据
2.给按钮一个vue(Vue事件前缀用@)点击事件,点击之后改变当前按钮状态(我们在上方代码中定义了flag为真 !flag就是取反的意思,flag=!flag 的意思就是切换当前状态 如果为真点击后变为假,如果为假点击后变为真)然后判断当前状态来改变显示在按钮上的文字
3.这是一个单分支操作
<div class="app">
<p v-if="flag">{{message}}</p>
<button @click="flag=!flag" v-text="flag ? '隐藏' : '显示'"></button>
注释:
这个和之前的if多分支一样,一级一级的判断
只是将语法变成了 v-if v-if-eles v-eles
<!-- if-else, if else if else -->
<p v-if="point>=1000 && point< 2000">{{grade[0]}}</p>
<p v-else-if="point>=2000 && point< 3000">{{grade[1]}}</p>
<p v-else-if="point>=3000 && point< 4000">{{grade[2]}}</p>
<p v-if="point>=4000">{{grade[3]}}</p>
<!-- <p v-else>{{grade[4]}}</p> -->
</div>
利用vue重写之前的留言板案例
<div class="liuyan">
<!-- enter: 键盘修饰符, 代表回车 -->
<!-- 创建一个输入框,并定义一个vue事件-->
<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);
// 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('.liuyan');
</script>
计算器属性:computed
侦听器属性: watch 被侦听的属性,其实是一个方法,它有二个参数第一个参数是新值(当前值),第二个参数是原值(旧值)
先写一个商品结算页面
<style>
table {
width: 20em;
height: 10em;
text-align: center;
border-collapse: collapse;
margin: 1em;
}
table caption {
font-size: 1.2em;
padding: 1em;
margin-bottom: 2em;
border-bottom: 1px solid;
}
tbody tr th:first-of-type {
background: linear-gradient(to left, lightcyan, #fff);
border-right: 1px solid;
}
body tbody tr:not(:last-of-type) > * {
border-bottom: 1px solid;
}
</style>
</head>
<body>
<div class="app">
<table>
<caption>
商品结算
</caption>
<tbody>
<tr>
<th>ID</th>
<td>HA110</td>
</tr>
<tr>
<th>品名</th>
<td>伊利纯牛奶</td>
</tr>
<tr>
<th>单价</th>
<td>100</td>
</tr>
<tr>
<th>数量</th>
<td><input type="number" v-model="num" style="width: 5em" /></td>
</tr>
<tr>
<th>金额</th>
<!-- <td>{{num * price}}</td> -->
<td>{{amount}}</td>
</tr>
</tbody>
</table>
<p style="font-size: 1.2em">
实付金额: {{realAmount}}, 优惠了 :
<span style="color: red">{{difAmount}}</span>
</p>
</div>
然后下面是vue代码
<script>
const app = Vue.createApp({
data() {
return {
// 单价
price: 100,
// 数量
num: 0,
// 折扣
discount: 1,
};
},
// 计算属性(访问器属性)
computed: {
// 计算属性金额 = 单价 * 数量
amount: {
get() {
return this.price * this.num;
},
set(value) {
//...
},
},
},
// 侦听器属性
watch: {
// 访问器属性
// 被侦听的属性,其实是一个方法,它有二个参数
// 第一个参数是新值(当前值),第二个参数是原值(旧值)
amount(current, origin) {
console.log(current, origin);
// 根据当前金额确定打折
switch (true) {
// 1000-2000: 9折
case current >= 1000 && current < 2000:
this.discount = 0.9;
break;
// 2000 -> 3000 : 8折
case current >= 2000 && current < 3000:
this.discount = 0.8;
break;
// 3000 -> 4000 : 7折
case current >= 3000 && current < 4000:
this.discount = 0.7;
break;
// 4000 -> 5000 : 6折
case current >= 4000 && current < 5000:
this.discount = 0.6;
break;
// 5000 : 5折
case current >= 5000:
this.discount = 0.5;
}
// 实付金额 = 原始金额 * 折扣率
this.realAmount = this.amount * this.discount;
// 优惠金额(差价) = 原始金额 - 实付金额
this.difAmount = this.amount - this.realAmount;
},
},
// 实例生命周期: 当实例与挂载点绑定成功时,自动执行
mounted() {
//初始化商品数量,默认为1
this.num = 1;
},
}).mount('.app');
上面的案例中出现了一个属性,叫生命周期
实例生命周期: 当实例与挂载点绑定成功时,自动执行