at 功能实现vue
实现 Vue 中的 @ 功能
在 Vue 中实现类似社交平台的 @ 提及功能,通常需要结合输入框(如 <textarea> 或可编辑的 <div>)和用户列表的交互。以下是具体实现方法:
监听输入事件
通过 @input 或 @keyup 监听输入框内容的变化,检测用户是否输入了 @ 符号。可以使用正则表达式匹配 @ 后的字符:
methods: {
handleInput(event) {
const text = event.target.value;
const lastAtPos = text.lastIndexOf('@');
if (lastAtPos >= 0) {
const query = text.substring(lastAtPos + 1);
this.showUserList = true;
this.filterUsers(query);
} else {
this.showUserList = false;
}
}
}
过滤和显示用户列表
根据输入的字符过滤用户列表,动态展示匹配的用户:
filterUsers(query) {
if (query.trim() === '') {
this.filteredUsers = this.users;
return;
}
this.filteredUsers = this.users.filter(user =>
user.name.toLowerCase().includes(query.toLowerCase())
);
}
插入提及的用户
当用户从列表中选择一个用户时,将用户名插入到输入框中,并替换 @ 后的部分:
selectUser(user) {
const text = this.message;
const lastAtPos = text.lastIndexOf('@');
this.message = text.substring(0, lastAtPos) + `@${user.name} `;
this.showUserList = false;
}
高亮提及的用户名
在显示消息时,使用 v-html 或自定义组件高亮 @ 提及的用户名:
highlightMentions(text) {
return text.replace(/@(\w+)/g, '<span class="mention">@$1</span>');
}
完整示例代码
<template>
<div>
<textarea
v-model="message"
@input="handleInput"
placeholder="输入消息..."
></textarea>
<ul v-if="showUserList" class="user-list">
<li
v-for="user in filteredUsers"
:key="user.id"
@click="selectUser(user)"
>
{{ user.name }}
</li>
</ul>
<div v-html="highlightMentions(message)"></div>
</div>
</template>
<script>
export default {
data() {
return {
message: '',
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
],
filteredUsers: [],
showUserList: false
};
},
methods: {
handleInput(event) {
const text = event.target.value;
const lastAtPos = text.lastIndexOf('@');
if (lastAtPos >= 0) {
const query = text.substring(lastAtPos + 1);
this.showUserList = true;
this.filterUsers(query);
} else {
this.showUserList = false;
}
},
filterUsers(query) {
if (query.trim() === '') {
this.filteredUsers = this.users;
return;
}
this.filteredUsers = this.users.filter(user =>
user.name.toLowerCase().includes(query.toLowerCase())
);
},
selectUser(user) {
const text = this.message;
const lastAtPos = text.lastIndexOf('@');
this.message = text.substring(0, lastAtPos) + `@${user.name} `;
this.showUserList = false;
},
highlightMentions(text) {
return text.replace(/@(\w+)/g, '<span class="mention">@$1</span>');
}
}
};
</script>
<style>
.mention {
color: blue;
font-weight: bold;
}
.user-list {
border: 1px solid #ccc;
max-height: 150px;
overflow-y: auto;
}
.user-list li {
padding: 5px;
cursor: pointer;
}
.user-list li:hover {
background-color: #f0f0f0;
}
</style>
注意事项
- 如果输入框支持富文本(如使用
contenteditable),需要额外处理 HTML 转义。 - 对于大型用户列表,建议加入防抖(debounce)优化搜索性能。
- 后端需要配合存储和解析提及的用户 ID,而不仅仅是用户名。







