每日一题:一起会议吧
发表于:2024-12-10
字数统计:1892 字
预计阅读7分钟
介绍
网络会议已经成为当下最流行的会议模式,为网络会议提供支持的当然是一些优秀的会议软件。
本题需要在已提供的基础项目中使用 Vue 2.x 知识完善代码,最终实现网络会议软件中,参会人员列表的几个展示效果。
准备
开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:
txt
├── effect.gif
├── index.html
├── css
├── images
└── js
├── axios.min.js
├── userList.json
└── vue.js其中:
effect.gif是最终实现的效果图。index.html是主页面。css是样式文件夹。images是图片文件夹。js/axios.min.js是 axios 文件。js/userList.json是需要请求的数据文件。js/vue.js是 Vue 2.x 文件。
注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:
bash
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/9788/07.zip && unzip 07.zip && rm 07.zip在浏览器中预览 index.html 页面,显示如下所示:

目标
请在 index.html 文件中补全代码,最终实现网络会议中参会人员列表的几个展示效果。
具体需求如下:
- 实现异步数据读取和渲染功能。
- 使用 axios 异步获取
./js/userList.json中的用户数据(注意:调试完成后请将请求地址写死为./js/userList.json),并显示在登录窗口及参会人员窗口中。效果如下:


- 实现登录、注销切换功能。
- 在登录窗口选取用户登录后,登录窗口切换为注销窗口,具体变化为:登录标题变为注销字样;选择用户下拉框变为显示当前登录用户名;登录按钮变为注销按钮。参会人员窗口显示,并默认只显示当前登录用户信息。效果如下:

- 在注销窗口点击注销按钮后,注销窗口切换为登录窗口,参会人员窗口消失。效果如下:

- 实现参会列表中的首位用户始终为登录用户功能。
- 参会列表中的首位用户始终为登录用户。效果如下:

- 实现用户窗口显隐切换功能。
- 通过点击隐藏参会用户窗口或显示参会用户窗口按钮图标,可切换参会人员窗口的显隐。效果如下:


- 实现用户列表显示效果切换功能。
- 点击显示所有参会人员的按钮图标,图标变色(即 **
class=active**),参会人员窗口内的人员列表显示所有参会人员信息。效果如下:

注意,参会人员列表中用户名称前面的黄色小图标,代表的是该成员为会议发起者,与当前登录用户无关。与之对应的
./js/userList.json中的字段为isHost,其中"isHost": true为会议发起人,"isHost": false为普通参会成员。
- 点击最左侧的不显示参会人员列表的按钮图标,图标变色(即 **
class=active**),参会人员窗口内的人员列表隐藏。效果如下:

- 点击只显示当前登录用户的按钮图标,图标变色(即 **
class=active**),参会人员窗口内的人员列表中只显示当前登录用户信息。效果如下:

完成后的效果见文件夹下面的 gif 图,图片名称为 effect.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。
注意:本题涉及到的登录/注销流程仅为当前题目需要而设计,非真实场景模拟。
规定
- 请勿修改
index.html文件外的任何内容。 - 请严格按照上述要求来完成代码,页面中需要显示的文本内容,与具体说明里的内容保持一致,不要自定义,以免造成无法判题通过。
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。
判分标准
- 实现异步数据读取功能,得 5 分。
- 实现登录、注销切换功能,得 4 分。
- 实现参会列表首位用户始终为登录用户功能,得 3 分。
- 实现用户窗口显隐切换功能,得 2 分。
- 实现用户列表显示效果切换功能,得 6 分。
总通过次数: 214 | 总提交次数: 332 | 通过率: 64.5%
难度: 中等 标签: 2022, 国赛, Web 前端, Vue.js
题解
js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>一起会议吧</title>
<link rel="stylesheet" type="text/css" href="./css/index.css" />
<link rel="stylesheet" href="./css/iconfont/iconfont.css" />
</head>
<body>
<div id="app">
<!-- TODO:请在下面实现需求 -->
<!-- 登录/注销窗口 -->
<div class="login">
<div class="left-tools">
<a class="close-btn"></a>
<a class="shrink-btn"></a>
</div>
<h3>{{ isLogin ? '注销' : '登录' }}</h3>
<p v-if="!isLogin">
选择用户:<select id="selectUser" @change="changeUser($event)" ref="selectUser">
<option :value="item.id" v-for="item in userList" :key="item.id">{{ item.name }}</option>
</select>
</p>
<p v-if="isLogin">当前用户为:{{ currentUser }}</p>
<a class="login-btn" @click="login" >{{ isLogin ? '注销' : '登录' }}</a>
</div>
<!-- 右侧显示用户列表窗口按钮 -->
<button id="show" class="right-btn" @click="isShow = true" v-if="!isShow && isLogin">
<span class="iconfont icon-left-arrow"></span>
</button>
<!-- 用户列表窗口 -->
<div class="user-dialog" v-if="isLogin && isShow">
<!-- 用户列表窗口上侧工具栏 -->
<ul class="tools">
<li class="tools-left">
<button :class="activeIndex === 0 ? 'active' : ''" @click="changeActiveIndex(0)">
<span class="iconfont icon-close" ></span>
</button>
<button :class="activeIndex === 1 ? 'active' : ''" @click="changeActiveIndex(1)">
<span class="iconfont icon-dialog"></span>
</button>
<button :class="activeIndex === 2 ? 'active' : ''" @click="changeActiveIndex(2)">
<span class="iconfont icon-list"></span>
</button>
</li>
<li class="tools-right" @click="isShow = !isShow">
<button class="show-list">
<span class="iconfont icon-retract"></span>
</button>
</li>
</ul>
<!-- 用户列表 -->
<ul class="say-list">
<li>
<span class="iconfont icon-microphone"></span>
</li>
<li class="line"></li>
<li>正在讲话:Tom;</li>
</ul>
<ul class="user-list" v-if="activeIndex !== 0">
<li v-for="item in sortList" :key="item.key">
<img class="header" :src="item.imgPath" />
<div class="user-name">
<span class="iconfont icon-user header-icon" v-if="item.isHost"></span>
<span class="iconfont icon-microphone"></span>
{{ item.name }}
</div>
</li>
</ul>
</div>
</div>
<script type="text/javascript" src="./js/vue.js"></script>
<script type="text/javascript" src="./js/axios.min.js"></script>
<script type="text/javascript">
// TODO:请在下面实现需求
new Vue({
el: "#app",
data: {
userList: [],
value: 1,
isLogin: false,
isShow: true,
activeIndex: 2
},
computed: {
currentUser() {
return this.userList.length > 0 ? this.userList[this.value - 1].name : 'Tom'
},
sortList() {
if (this.activeIndex === 1) {
return this.userList.filter(item => item.name === this.currentUser)
}
else {
const tmpList = [...this.userList]
const result = this.userList.length > 0 ? tmpList.sort((a,b) => {
if (a.name === this.currentUser) {
return -1
} else if (b.name === this.currentUser) {
return 1
} else return 0
}) : []
return result
}
}
},
mounted() {
axios.get('./js/userList.json').then(res => {
this.userList = res.data
})
},
methods: {
changeUser(event) {
this.value = event.target.value !== undefined ? event.target.value : 1
},
login() {
this.isLogin = !this.isLogin
if (!this.isLogin) {
this.value = 1
}
},
changeActiveIndex(val) {
this.activeIndex = val
}
}
});
</script>
</body>
</html>