<style>
* {
margin: 0;
padding: 0;
}
.icons {
display: inline-block;
width: 20px;
height: 20px;
background: url("./star.png") no-repeat;
background-position: 0px 0px;
background-size: 100%;
/* background-color: burlywood; */
}
/* .icons:hover {
background-position: 0px -30px;
} */
.active {
background-position: 0px -30px;
}
</style>
<body>
<script src='./vue.js'></script>
<div id='myApp'>
<h1>平均分:{{myFen}} </h1>
<div>
<input
type="number"
v-for="item,i in score.length"
:key="i"
ref="item"
style="margin: 5px;"
v-model.number="score[i]"
min="0" max="5"
>{{score}}
</div>
<my-com1
v-for="item,i in gradeList"
:key="item"
@mymark="getMark"
:dataa="score[i]"
:index="i"
>
{{item}}
</my-com1>
</div>
<!-- 组件模板 -->
<template id='myTem'>
<!-- <div> -->
<ul>
<li style="list-style: none;">
<slot></slot> :
<i
class="icons"
v-for="item,i in 5"
:class="item<=temp?'active':''"
注释="鼠标悬停时,得到临时评分"
@mouseenter="temp=item"
注释="鼠标离开时,临时分数还原成真实分数"
@mouseleave="temp=dataa"
注释="点击星星时,得到真实评分"
@click="bright(item)"
></i>
<b style="color: coral;">{{dataa}} 分:</b>
<!-- 评分是1-5 评价信息索引是0-4 刚好差了1 -->
<strong>{{appraises[dataa-1]}} </strong>
</li>
</ul>
<!-- </div> -->
</template>
<script>
Vue.component('myCom1', {
template: '#myTem',
props: ["dataa", "index"],
data() {
return {
// temp是临时的分数,用于展示鼠标悬停时显示的分数
temp: this.dataa,
appraises: ["非常差", "一般差", "还凑合", "一般好", "非常好"]
}
},
methods: {
bright(item) {
console.log(item);
// 再次强调,单向数据流限制,子组件千万不要直接改数据
// this.$set(this.mark,this.dataa,item)
// 要发自定义事件, 把数据传给父组件,由父组件改
this.$emit("mymark", {
mark: item,
i: this.index
})
}
}
})
new Vue({
el: '#myApp',
data: {
gradeList: ["商品评价", "物流评价", "客服评价", "快递小哥评价"],
score: [1,2,3,4]
},
methods: {
getMark(data) {
console.log(data)
// this.score[data.i] = data.mark
this.$set(this.score, data.i, data.mark)
}
},
mounted() {
console.log(this.$refs.item) //有多个ref值相同的标签,会得到一个数组
},
computed: {
myFen() {
var fen = 0
this.score.forEach(item => {
fen += item * 1 / 4
});
return fen
}
}
})
</script>
</body>
star.png
父子组件间的双向绑定
<style>
* {
margin: 0;
padding: 0;
}
.icons {
display: inline-block;
width: 20px;
height: 20px;
background: url("./star.png") no-repeat;
background-position: 0px 0px;
background-size: 100%;
/* background-color: burlywood; */
}
/* .icons:hover {
background-position: 0px -30px;
} */
.active {
background-position: 0px -30px;
}
</style>
<body>
<script src='./vue.js'></script>
<div id='myApp'>
<h1>平均分:{{myFen}} </h1>
<div>
<input
type="number"
v-for="item,i in score.length"
:key="i"
ref="item"
style="margin: 5px;"
v-model.number="score[i]"
min="0" max="5"
>{{score}}
</div>
<my-com1
v-for="item,i in gradeList"
:key="item"
注释='@input="getMark"
:value="score[i]"
:index="i" '
注释="@input和:value实现了v-model, 所以以上对input自定义事件的绑定和对value自定义属性的绑定,可以简化为v-model"
v-model="score[i]"
>
{{item}}
</my-com1>
</div>
<!-- 组件模板 -->
<template id='myTem'>
<!-- <div> -->
<ul>
<li style="list-style: none;">
<slot></slot> :
<i
class="icons"
v-for="item,i in 5"
:class="item<=temp?'active':''"
注释="鼠标悬停时,得到临时评分"
@mouseenter="temp=item"
注释="鼠标离开时,临时分数还原成真实分数"
@mouseleave="temp=value"
注释="点击星星时,得到真实评分"
@click="bright(item)"
></i>
<b style="color: coral;">{{value}} 分:</b>
<!-- 评分是1-5 评价信息索引是0-4 刚好差了1 -->
<strong>{{appraises[value-1]}} </strong>
</li>
</ul>
<!-- </div> -->
</template>
<script>
Vue.component('myCom1', {
template: '#myTem',
props: ["value"],
data() {
return {
// temp是临时的分数,用于展示鼠标悬停时显示的分数
temp: this.value,
appraises: ["非常差", "一般差", "还凑合", "一般好", "非常好"]
}
},
methods: {
bright(item) {
console.log(item);
// 再次强调,单向数据流限制,子组件千万不要直接改数据
// this.$set(this.mark,this.dataa,item)
// 要发自定义事件, 把数据传给父组件,由父组件改
// this.$emit("input", {
// mark: item,
// i: this.index
// })
// v-model绑定后, item会被直接赋值到 score[i]
this.$emit("input", item)
}
}
})
new Vue({
el: '#myApp',
data: {
gradeList: ["商品评价", "物流评价", "客服评价", "快递小哥评价"],
score: [1,2,3,4]
},
methods: {
// getMark(data) {
// console.log(data)
// // this.score[data.i] = data.mark
// this.$set(this.score, data.i, data.mark)
// }
},
mounted() {
console.log(this.$refs.item) //有多个ref值相同的标签,会得到一个数组
},
computed: {
myFen() {
var fen = 0
this.score.forEach(item => {
fen += item * 1 / 4
});
return fen
}
}
})
</script>
</body>