封装组件
首先需要封装星星评价组件,通常每个评分项为五个星组成,使用v-for循环渲染出五个星星。
var Star={
template:`<div>
<span class="iconfont icon-xing" v-for="i in 5" ></span>
</div>`,
};
注册组件
设计好组件样式先在vue实例中注册组件,在html中使用,检测是否符合预期设计。
new Vue({
el: "#box",
components: {
Star //注册组件
}
})
设计事件
评分组件的事件通常有三种:
- 鼠标划过
- 鼠标离开
- 鼠标点击
所以在数据部分我们至少需要两个参数记录事件变化:
- 鼠标滑过的星星数
- 鼠标状态,记录是否点击
data(){
return {
curindex:0, //鼠标滑过的星星个数
flag:false //判断是否点击过
}
},
methods:{
enter(n){ //鼠标进入
if(!this.flag)
this.curindex=n
},
leave(){ //鼠标离开
if(!this.flag)
this.curindex=-1
},
sure(n){ //点击确定
this.flag=true
this.curindex=n
}
}
};
绑定事件
将事件绑定到星星上,通过i值和curindex值的大小比较,决定是否给星星增加类名,使之变亮。
template:`<div>
<span class="iconfont icon-xing" @mouseenter="enter(i)" @mouseleave="leave" @click="sure(i)" v-for="i in 5" :class="{'active':curindex>=i}"></span>
</div>`,
效果图:
完整代码
star.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="./iconfont.css" />
<script crossorigin="anonymous" integrity="sha384-OZmxTjkv7EQo5XDMPAmIkkvywVeXw59YyYh6zq8UKfkbor13jS+5p8qMTBSA1q+F"
src="https://lib.baomitu.com/vue/2.6.11/vue.min.js"></script>
<style>
.active{
color:yellow
}
</style>
<title></title>
<body>
<div id="box" >
<Star></Star>
<Star></Star>
</div>
<script type="text/javascript">
var Star={
template:`<div>
<span class="iconfont icon-xing" @mouseenter="enter(i)" @mouseleave="leave" @click="sure(i)" v-for="i in 5" :class="{'active':curindex>=i}"></span>
</div>`,
data(){
return {
curindex:0, //鼠标滑过的星星个数
flag:false //判断是否点击过
}
},
methods:{
enter(n){ //鼠标进入
if(!this.flag)
this.curindex=n
},
leave(){ //鼠标离开
if(!this.flag)
this.curindex=-1
},
sure(n){ //点击确定
this.flag=true
this.curindex=n
}
}
};
new Vue({
el: "#box",
components: {
Star //注册组件
}
})
</script>
</body>
</html>
星星图标样式 iconfont.css
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1587557131666'); /* IE9 */
src: url('iconfont.eot?t=1587557131666#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALcAAsAAAAABoAAAAKOAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAqBDIEeATYCJAMICwYABCAFhG0HLhvCBcgekiSQQAEFoqIKACwkgu/3++15734VSKqR7lm00khMpxJJUBpZrNGpNKZ7CX/+19yf2A3TxIemQ9zvEDtu/2z+91ENjehN/XUSNJPQiJqW+3oAPs/l9K4BFMj8QDnOsah3GFAvDqRAxxoUcCDF2DB2gUs4TqBqTBzFdnltK9BLrHGBOJcEFuhzQUlimbJQrFmaxA2NcnaV3QKuw9/Hv+TQkynkrJq9szIzKPwKtkeoZgYzuvNZS/PZwVaRYwWQiKPa5A6VYCyValJtCthXZfAV7PH4ZrFXg2B/nVVeByNQeE8iV3yrmQxuq6cFwMaoK4mF8fvW1raHtpXXdLr19D3iiWHoR3r7IYNjkpyD2+DlrfCGz2tjz+4KIq9zKkrqKpqpHoo2MNGehJ/J//EEn2hDO9Vm7KlqLqnNqcjiGH1yco+pLb5Jfoti6de4JhOd3K1OZlpBIWDAc9Lklz/vPB/Pzs1T39xvvTGBz5tWYyjt5wbKp3AFv0qRZiFIdYllzJJqHEDtmYVbUFR1j0GWt+tzbNN9ZUPZ0Ah3yWiKXNkMmZgrKKhZRVHZGqqWVayu6cFUIlWwZBEgtB0g0/SGXNsdmZgfKBj2haJ2qFB1EoFb1syFRJVgxBJkhgOjUOIcdt6xECqqbEbCoJXFWUnIphF2SxGYZEosZiqQHeE5ZriHhGRCeMhjhw2Wg9OQ1eqATuyQEUdMIiHO7IQEvu5NJs5hA5QtGMIiEDNowChIwnGw4/3OBFX6fjNEMMiKhVsoNUEagrlJ/UNJTBJ7kBVKey/KvbziNkSQjCB4EA9zsIHKwSDEysoBctYPkiEcwkQcEXfKlmC34vsqTeurbV+3C6osXRZ2Yy5dSHYBAAAA') format('woff2'),
url('iconfont.woff?t=1587557131666') format('woff'),
url('iconfont.ttf?t=1587557131666') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1587557131666#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-xing:before {
content: "\e615";
}