目录
- 一、介绍
- 二、准备
- 三、⽬标
- 四、代码
- 五、完成
一、介绍
外卖是现代⽣活中必备的⼀环。收到外卖后,各⼤平台软件常常会邀请⽤户在⼝味,配送速度等多个⽅⾯给与评分。在 element-ui 组件中,已经有相应的 Rate 组件,但是已有组件只能对单⼀维度进⾏评分,在外卖评分这种场景中,样式基本上是固定的,功能也基本⼀样。若每写⼀个⻚⾯都要去复制⼀份类似代码,就会产⽣⼤量重复的代码,既不利于后期的维护,代码也不够简洁。为此需要前端⼯程师对element-ui 的原 Rate 组件进⾏⼆次封装。
二、准备
开始答题前,需要先打开本题的项⽬代码⽂件夹,⽬录结构如下:
├── element-ui-2.6.2
│ ├── element-icons.ttf
│ ├── element-icons.woff
│ ├── element-ui.min.js
│ └── element-ui.style.min.css
├── index.html
├── js
│ ├── http-vue-loader.min.js
│ └── vue.min.js
├── my-rate.vue
└── effect.gif
其中:
- index.html 是主⻚⾯。
- element-ui-2.6.2 ⽂件夹中存放的是 element-ui 库相关的脚本⽂件、样式⽂件及字体。
- js ⽂件夹中存放的是 vue 及 http-vue-loader 库相关⽂件。
- my-rate.vue 是待封装的评分组件⽂件。
- effect.gif 是完成后的效果图。
在浏览器中预览 index.html ⻚⾯,显示如下所示
三、⽬标
请在 my-rate.vue ⽂件中补充代码,具体要求如下:
- my-rate.vue 组件能够对不同的维度进⾏评分。
- my-rate.vue 组件对外抛出 change 事件,在三项评分均完成后,触发 change 事件, change事件包含⼀个参数,⽤于传递改变后的分数值,其类型是对象,包含以下属性:
{
speed: number;
flavour: number;
pack: number;
}
最终效果可参考⽂件夹下⾯的 gif 图,图⽚名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览gif 图⽚)。
实现该功能所需的 el-rate 组件 api 如下:
四、代码
index.html
<!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>
<link rel="stylesheet" href="./element-ui-2.6.2/element-ui.style.min.css" />
<style>
body {
padding: 20px;
}
.result {
margin-top: 20px;
}
</style>
</head>
<body>
<div id="app">
<my-rate @change="onRateChange"></my-rate>
<div class="result">评分结果:{{JSON.stringify(rate)}}</div>
</div>
<script src="./js/vue.min.js"></script>
<script src="./js/http-vue-loader.min.js"></script>
<script src="./element-ui-2.6.2/element-ui.min.js"></script>
<script>
Vue.use(httpVueLoader);
const app = new Vue({
el: "#app",
components: {
"my-rate": "url:./my-rate.vue",
},
data() {
return {
rate: {},
};
},
methods: {
onRateChange(rate) {
this.rate = rate;
},
},
});
</script>
</body>
</html>
my-rare.vue
<template>
<div class="block">
<span class="demonstration">请为外卖评分: </span>
<ul class="rate-list">
<li>
<!-- TODO: 补全 el-rate 属性 -->
送餐速度:<el-rate></el-rate>
</li>
<li>
<!-- TODO: 补全 el-rate 属性 -->
外卖口味:<el-rate></el-rate>
</li>
<li>
<!-- TODO: 补全 el-rate 属性 -->
外卖包装:<el-rate></el-rate>
</li>
</ul>
</div>
</template>
<style>
.block {
border: 1px solid #c7c5c5;
padding: 10px;
}
.rate-list {
list-style: none;
padding-inline-start: 20px;
margin-block-start: 10px;
margin-block-end: 10px;
}
.el-rate {
display: inline-block;
}
</style>
<script>
module.exports = {
data() {
return {
speed: 0, // 送餐速度
flavour: 0, // 外卖口味
pack: 0, // 外卖包装
};
},
/* TODO:待补充代码 */
};
</script>
五、完成
<template>
<div class="block">
<span class="demonstration">请为外卖评分: </span>
<ul class="rate-list">
<li>
<!-- TODO: 补全 el-rate 属性 -->
送餐速度:<el-rate @change="sendRate('speed')" show-score="true" v-model="speed"></el-rate>
</li>
<li>
<!-- TODO: 补全 el-rate 属性 -->
外卖口味:<el-rate @change="sendRate('flavour')" show-score="true" v-model="flavour"></el-rate>
</li>
<li>
<!-- TODO: 补全 el-rate 属性 -->
外卖包装:<el-rate @change="sendRate('pack')" show-score="true" v-model="pack"></el-rate>
</li>
</ul>
</div>
</template>
<style>
.block {
border: 1px solid #c7c5c5;
padding: 10px;
}
.rate-list {
list-style: none;
padding-inline-start: 20px;
margin-block-start: 10px;
margin-block-end: 10px;
}
.el-rate {
display: inline-block;
}
</style>
<script>
module.exports = {
data() {
return {
speed: 0, // 送餐速度
flavour: 0, // 外卖口味
pack: 0, // 外卖包装
obj: {},
}
},
/* TODO:待补充代码 */
methods: {
sendRate(key) {
this.obj[key] = this[key]
const values = Object.keys(this.obj)
if (values.length == 3) {
//这里一定要将obj结构出来 不然不能实时更新
// const copy ={...this.obj} 或者
const copy = Object.assign({}, this.obj)
this.$emit('change', copy)
}
},
},
}
</script>