Skip to content
This repository was archived by the owner on Oct 17, 2023. It is now read-only.

woshiluo #14

Merged
merged 9 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions woshiluo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
13 changes: 13 additions & 0 deletions woshiluo/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"singleQuote": true,
"printWidth": 80,
"editor.formatOnSave": true,
"proseWrap": "always",
"tabWidth": 4,
"requireConfig": false,
"useTabs": true,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"semi": true
}
15 changes: 15 additions & 0 deletions woshiluo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Hduhelp frontend freshman task

本项目实现了以下功能:

- 大致还原要求的布局,自己有所修改。
- 支持弹窗查看、修改、添加信息。
- 通过 LocalStorage 持久化保存用户信息。
- 有一定动画过渡。

## 可以改进的部分

- 命名规范尚未统一。
- 部分动画尚未实现。
- 尚不支持导出和导入/基于请求的数据交互。
- 不支持路由和调整每页显示信息条数。
13 changes: 13 additions & 0 deletions woshiluo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<!--<link rel="icon" type="image/svg+xml" href="/vite.svg" />-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>学生信息管理系统</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
19 changes: 19 additions & 0 deletions woshiluo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "student-list",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"typescript": "^5.2.2",
"vue": "^3.3.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"vite": "^4.4.5"
}
}
45 changes: 45 additions & 0 deletions woshiluo/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup>
import { ref } from 'vue';

import StuentList from './components/student-list.vue';

const students = ref(JSON.parse(localStorage.getItem('students')));

const toggle_student = (idx) => {
students.value[idx].checked = !students.value[idx].checked;
};

const delete_student = () => {
let list = [];
for (const idx in students.value) {
if (!students.value[idx].checked) list.push(students.value[idx]);
}
students.value = list;
};
</script>

<template>
<h1 class="title main-title">学生信息管理系统</h1>
<div class="main-table">
<StuentList
:data="students"
@toggle="toggle_student"
@delete="delete_student"
></StuentList>
</div>
</template>

<style scoped>
.title {
text-align: center;
margin-top: 8vh;
margin-bottom: 4vh;
}

.main-table {
margin-left: auto;
margin-right: auto;
border-radius: 0.1em;
width: 96vw;
}
</style>
215 changes: 215 additions & 0 deletions woshiluo/src/components/student-dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<script setup>
import { ref } from 'vue';

const props = defineProps({
id: Number,
title: String,
editable: Boolean,
student: Object
});
const emit = defineEmits(['destory', 'submit']);

const destory_self_when_body = (e) => {
if (e.srcElement.className === 'dialog-body') emit('destory');
};

const student_id = ref(props.student.student_id);
const name = ref(props.student.name);
const college = ref(props.student.college);
const major = ref(props.student.major);
const year = ref(props.student.year);
const class_id = ref(props.student.class_id);
const old = ref(props.student.old);

const destory_self = () => {
emit('destory');
};

const submit_self = () => {
emit('submit', props.id, student_id, name, college, major, year, class_id, old);
emit('destory');
};
</script>

<template>
<div class="dialog">
<div class="dialog-overlay"></div>
<div class="dialog-body" @click.stop="destory_self_when_body">
<div class="dialog-card">
<h2 class="card-title">{{ title }}</h2>
<div class="input-box">
<label>学号</label>
<input
:disabled="!editable"
v-model="student_id"
type="number"
class="input input-student-id"
/>
</div>
<div class="input-box">
<label>姓名</label>
<input
:disabled="!editable"
v-model="name"
class="input input-name"
/>
</div>
<div class="input-box">
<label>学院</label>
<input
:disabled="!editable"
v-model="college"
class="input input-college"
/>
</div>
<div class="input-box">
<label>专业</label>
<input
:disabled="!editable"
v-model="major"
class="input input-major"
/>
</div>
<div class="input-box">
<label>年级</label>
<input
:disabled="!editable"
v-model="year"
type="number"
class="input input-year"
/>
</div>
<div class="input-box">
<label>班级</label>
<input
:disabled="!editable"
v-model="class_id"
type="number"
class="input input-class-id"
/>
</div>
<div class="input-box">
<label>年龄</label>
<input
:disabled="!editable"
v-model="old"
type="number"
class="input input-old"
/>
</div>
<div class="button-panel">
<button @click="destory_self" class="button button-cancel">
取消
</button>
<button
v-if="editable"
@click="submit_self"
class="button button-cancel"
>
保存
</button>
</div>
</div>
</div>
</div>
</template>

<style scoped>
.dialog {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 100;
}

.dialog-overlay {
cursor: pointer;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #000;
opacity: 0.5;
}

.dialog-body {
position: fixed;
z-index: 200;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}

.dialog-card {
margin: auto;
position: fixed;
max-height: 60vh;
width: calc(100% - 5em);
border-radius: 0.3em;
padding: 1em;
padding-bottom: 2em;
z-index: 200;
background: #fff;
overflow: scroll;
box-shadow:
rgba(0, 0, 0, 0.2) 0px 3px 1px -2px,
rgba(0, 0, 0, 0.14) 0px 2px 2px 0px,
rgba(0, 0, 0, 0.12) 0px 1px 5px 0px;
}

.card-title {
text-align: center;
}

.input-box {
font-size: 1.2em;
line-height: 1.5em;
padding-top: 1em;
display: flex;
}

.input-box > label {
min-width: 3em;
}

.input {
margin-left: 1em;
width: 100%;
border: 0;
border-bottom: 1px #bdbdbd solid;
transition: border-bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0s;
}

.input:focus,
.input:focus-visible {
border: 0;
outline: none;
border-bottom: 1px #424242 solid;
}

.button-panel {
padding: 0.2em;
padding-top: 1em;
text-align: right;
}

.button {
font-size: 1.1em;
cursor: pointer;
background: #fff;
border: 0;
padding: 0.5em;
transition: background 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0s;
}

.button:hover {
background: #e0e0e0;
}
</style>
Loading