仅在使用 Vue 悬停时显示截断的文本 [英] Showing truncated text only on hover with Vue
问题描述
我是这样试的:
...<b-card-group 牌组 v-for="row in formattedClubs"><b-card v-for="club in row"img-src="http://placehold.it/130?text=No-image"img-alt="Img"img-top><h4 class="card-title"@mouseover="showAll = true"@mouseout="showAll = false">{{getWord(club.description)}}<p class="card-text">{{club.price}}</p><p class="card-text">{{club.country}}</p><div slot="footer"><b-btn variant="primary" block>添加</b-btn>
</b-card></b-card-group>...模板><脚本>导出默认{数据 () {返回 {全部显示:假,俱乐部:[{id:1, description:'切尔西是世界上最好的俱乐部,切尔西有一个伟大的球员',价格:1000,国家:'英格兰'},{id:2, description:'liverpool has salah', price:900, country:'england'},{id:3, description:'mu fan', price:800, country:'england'},{id:4, description:'city 有一位很棒的教练.这是瓜迪奥拉',价格:700,国家:'英格兰'},{id:5, description:'arsenal player', price:600, country:'england'},{id:6, description:'tottenham in London', price:500, country:'england'},{id:7,描述:'尤文图斯体育场',价格:400,国家:'意大利'},{id:8, description:'madrid sell Ronaldo', price:300, country:'spain'},{id:9, description:'西班牙的巴塞罗那', price:200, country:'spain'},{id:10, description:'psg 以超值的价格买下内马尔', price:100, country:'france'}]}},计算:{格式化俱乐部(){返回 this.clubs.reduce((c, n, i) => {if (i % 4 === 0) c.push([]);c[c.length - 1].push(n);返回 c;}, []);}},方法: {getWord(降序){if (this.showAll) 返回 desc让价值= desc;让长度= 30;如果(值.长度<=长度){返回值;} 别的 {return value.substring(0, length) + '...';}}}}
这几乎有效.但是当我将鼠标悬停在框 1 中的描述上时,所有其他框上的描述也会悬停.它应该只悬停在框 1 上显示截断的文本.
我该如何解决这个问题?
问题是你只有一个属性来控制所有项目的截断.
首先,您需要确保每个俱乐部都有自己的布尔值来控制文本截断.让我们使用您现有的计算属性为每个俱乐部添加一个新的反应性属性:
formattedClubs () {返回 this.clubs.reduce((c, n, i) => {if (i % 4 === 0) c.push([]);c[c.length - 1].push(n);this.$set(n, 'truncate', true);//这里我们添加了新的反应性属性.返回 c;}, []);}
其次,让我们使用 来处理视觉事物,保持关注点的正确分离,使用带有
的新的个人
/club.truncate
属性>v-ifv-else
块:
<h4 class="card-title"@mouseenter="club.truncate = false"@mouseleave="club.truncate = true"><template v-if="club.truncate">{{trucateText(club.description)}}</template><template v-else>{{club.description}}</template>
现在,trucateText
方法只需要关心返回被截断的文本,因为它只在我们截断一个俱乐部的描述时被调用:
方法:{trucateText(值){常量长度 = 30;返回值.长度 <= 长度?value : value.substring(0, length) + "...";}}
如果仍有任何疑问,请查看此处的完整代码.
I tried it like this:
<template>
...
<b-card-group deck v-for="row in formattedClubs">
<b-card v-for="club in row"
img-src="http://placehold.it/130?text=No-image"
img-alt="Img"
img-top>
<h4 class="card-title"
@mouseover="showAll = true"
@mouseout="showAll = false">
{{getWord(club.description)}}
</h4>
<p class="card-text">
{{club.price}}
</p>
<p class="card-text">
{{club.country}}
</p>
<div slot="footer">
<b-btn variant="primary" block>Add</b-btn>
</div>
</b-card>
</b-card-group>
...
</template>
<script>
export default {
data () {
return {
showAll: false,
clubs: [
{id:1, description:'chelsea is the best club in the world and chelsea has a great player', price:1000, country:'england'},
{id:2, description:'liverpool has salah', price:900, country:'england'},
{id:3, description:'mu fans', price:800, country:'england'},
{id:4, description:'city has a great coach. Thas is guardiola', price:700, country:'england'},
{id:5, description:'arsenal player', price:600, country:'england'},
{id:6, description:'tottenham in london', price:500, country:'england'},
{id:7, description:'juventus stadium', price:400, country:'italy'},
{id:8, description:'madrid sell ronaldo', price:300, country:'spain'},
{id:9, description:'barcelona in the spain', price:200, country:'spain'},
{id:10, description:'psg buys neymar at a fantastic price', price:100, country:'france'}
]
}
},
computed: {
formattedClubs () {
return this.clubs.reduce((c, n, i) => {
if (i % 4 === 0) c.push([]);
c[c.length - 1].push(n);
return c;
}, []);
}
},
methods: {
getWord (desc) {
if (this.showAll) return desc
let value = desc;
let length = 30;
if (value.length <= length) {
return value;
} else {
return value.substring(0, length) + '...';
}
}
}
}
</script>
That almost works. But when I hover over the description in box 1, the description on all the other boxes also hover. It should only hover showing the truncated text on the box 1.
How can I solve this problem?
The problem is that you have only one property to control the truncation of all items.
Firstly, you need to ensure that each club has its own boolean to control the text truncation. Lets use your already existing computed property to add a new reactive property for each club:
formattedClubs () {
return this.clubs.reduce((c, n, i) => {
if (i % 4 === 0) c.push([]);
c[c.length - 1].push(n);
this.$set(n, 'truncate', true); // Here we add the new reactive property.
return c;
}, []);
}
Secondly, let's use the <template>
to handle visual things, keeping the right separation of concerns, using the new individual club.truncate
property with a v-if
/v-else
block:
<h4 class="card-title"
@mouseenter="club.truncate = false"
@mouseleave="club.truncate = true">
<template v-if="club.truncate">{{trucateText(club.description)}}</template>
<template v-else>{{club.description}}</template>
</h4>
And now, the trucateText
method only needs to care about returning the truncated text, since it's only called if we're truncating a description of one club:
methods: {
trucateText (value) {
const length = 30;
return value.length <= length ?
value : value.substring(0, length) + "...";
}
}
Take a look at the fully working code here if any doubts persists.
这篇关于仅在使用 Vue 悬停时显示截断的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!