今天遇到一件令我有点气愤的事情,大致的事情经过是这样的,昨天晚上九点多的时候接到一个电话面试,是一个hr姐姐,她和我聊了10多分钟,我介绍了下我的技术栈,以及我曾经做过的某些业务,最后hr姐姐说她这边面试通过了,然后后面会有一轮面试题考核,需要线上做完发代码给她,让技术考核,考核通过了之后线下面试。 然后昨天晚上我搞一个外包项目折腾到了凌晨四点
然后顶着困意实现完之后,把代码发给他了,我个人测试效果都是没有问题的,虽然有些代码确实可以再优化,当时害怕时间超时,有些地方就没考虑太多,大概过了三个小时,hr姐姐说代码审核没通过,我想问原因,hr姐姐给我发了这样一张图
当时看完我就有点气愤了,搜索功能是我没有注意,但是他后面说的使用原生js的实现方式效率低,然后就给我扣上了个前端开发经验不足的帽子。
一个小小的to do list,我不用moment处理日期格式化,不用element-plus的form组件来进行表单校验,看漏了一个功能就能代表这些吗?
而且我应聘的是8k的前端岗位。我个人的技术栈,底层html+css+js,h5+css3,es6,promise,工程化(es module,common js),vue2,vue3,微信小程序,uniapp,后端熟悉nodejs,express,egg,怎么说也是一个能够独立开发前后端的开发者,感觉给说的一文不值,还不如别人刚应届出来的实习生。
下面放我写的代码吧
大致的项目结构
具体代码
main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App);
app.use(ElementPlus)
app.mount('#app')
App.vue
<template>
<TodoList></TodoList>
</template>
<script lang="ts">
import TodoList from './components/TodoList.vue'
export default {
components : {
TodoList
}
}
</script>
<style>
</style>
util/index.ts
export function timeFormat(date:any, isDateOnly = false) {
let Y = date.getFullYear();
let M = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1);
let D = date.getDate() < 10 ? ('0' + date.getDate()) : date.getDate();
let hours = date.getHours()
let minutes = date.getMinutes() < 10 ? ('0' + date.getMinutes()) : date.getMinutes()
let seconds = date.getSeconds() < 10 ? ('0' + date.getSeconds()) : date.getSeconds()
if (isDateOnly) {
date = Y + '-' + M + '-' + D;
} else {
date = Y + '-' + M + '-' + D + ' ' + hours + ':' + minutes + ':' + seconds;
}
return date;
}
TodoList.vue
<template>
<div class="todo-list-container">
<div class="op-container">
<el-input
v-model="input"
style="width: 240px"
placeholder="请输入任务名称"
/>
<el-button type="primary" style="margin-left: 5px" @click="submitHandle"
>提交</el-button
>
</div>
<el-radio-group v-model="status" size="large" @change="changeHandle">
<el-radio-button label="全部" :value="2" />
<el-radio-button label="已完成" :value="1" />
<el-radio-button label="未完成" :value="0" />
</el-radio-group>
<el-table :data="showTodoList" border style="width: 100%">
<el-table-column fixed prop="sign" label="#">
<template #default="scope">
<el-checkbox
v-model="scope.row.isComplete"
@change="signComplete(scope.row)"
/>
<!-- <el-button link type="primary" size="small">Edit</el-button> -->
</template>
</el-table-column>
<el-table-column fixed prop="todoName" label="任务描述" />
<el-table-column prop="createTime" label="创建时间" width="150" />
<el-table-column prop="completeTime" label="完成时间" width="150" />
<el-table-column prop="taskStatus" label="是否完成" width="120">
<template #default="scope">
{{ getTaskStatus(scope.row.taskStatus) }}
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="120">
<template #default="scope">
<el-button
link
type="primary"
size="small"
@click="deleteHandle(scope.row)"
>
删除
</el-button>
<!-- <el-button link type="primary" size="small">Edit</el-button> -->
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { ref, reactive, computed } from "vue";
import { timeFormat } from "@/util/index";
const input = ref("");
const todoList = ref([]);
const status = ref(2);
const showTodoList = ref([]);
function init() {
const todoLocalStorage = localStorage.getItem("todoList")
? JSON.parse(localStorage.getItem("todoList"))
: [];
todoList.value.push(...todoLocalStorage);
// 全部
setShowTodoList();
}
init();
// 单选框change
function changeHandle() {
setShowTodoList();
}
// 设置显示的todolist
function setShowTodoList() {
showTodoList.value = [];
if (status.value === 2) {
showTodoList.value.push(...todoList.value);
} else if (status.value === 1) {
const ftTodoList = todoList.value.filter((todo) => {
return todo.isComplete;
});
showTodoList.value.push(...ftTodoList);
} else if (status.value === 0) {
const ftTodoList = todoList.value.filter((todo) => {
return !todo.isComplete;
});
showTodoList.value.push(...ftTodoList);
}
}
// 进行提交
function submitHandle() {
const inpVal = input.value;
if (!inpVal) {
ElMessage({
message: "文本框值不能为空",
type: "error",
});
return;
}
createToList(inpVal);
input.value = "";
}
// 创建一条任务清单
function createToList(todoName) {
const todoIndex = todoList.value.findIndex((to) => {
return to.todoName === todoName;
});
if (todoIndex !== -1) {
ElMessage({
message: "添加任务失败,该任务已存在",
type: "error",
});
return;
}
todoList.value.push({
todoName: todoName,
createTime: timeFormat(new Date()),
completeTime: null,
isComplete: false,
taskStatus: 0,
});
setShowTodoList();
setStorage(todoList.value);
}
function deleteHandle(row) {
const index = todoList.value.findIndex((to) => {
return to.todoName === row.todoName;
});
const showIndex = showTodoList.value.findIndex((to) => {
return to.todoName === row.todoName;
});
showTodoList.value.splice(showIndex, 1);
todoList.value.splice(index, 1);
setStorage(todoList.value);
}
// 标记完成
function signComplete(row) {
const index = todoList.value.findIndex((to) => {
return to.todoName === row.todoName;
});
todoList.value[index].taskStatus = todoList.value[index].isComplete ? 1 : 0;
todoList.value[index].completeTime = timeFormat(new Date());
setStorage(todoList.value);
setShowTodoList();
}
// 获取任务的状态
function getTaskStatus(val) {
let str = "";
switch (val) {
case 0:
str = "未完成";
break;
case 1:
str = "已完成";
break;
}
return str;
}
function setStorage(todoList) {
localStorage.setItem("todoList", JSON.stringify(todoList));
}
</script>
<style lang="scss" scoped>
.op-container {
margin-bottom: 10px;
}
.todo-list-container {
max-width: 800px;
margin: 0 auto;
}
.filters {
margin: 0;
padding: 0;
list-style: none;
li {
display: inline;
a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
&:hover {
border-color: rgba(175, 47, 47, 0.1);
}
&.selected {
border-color: rgba(175, 47, 47, 0.2);
}
}
}
}
</style>
这边的代码我是这么写的,当时大脑不是很清晰,代码还有可优化的地方,我再提供一个优化后的代码
下面的这段代码加上了一些ts的代码进行了约束
<template>
<div class="todo-list-container">
<div class="op-container">
<el-input
v-model="input"
style="width: 240px"
placeholder="请输入任务名称"
/>
<el-button type="primary" style="margin-left: 5px" @click="addTodoHandle"
>提交</el-button
>
</div>
<el-radio-group v-model="filterStatus" size="large" @change="changeHandle">
<el-radio-button label="全部" :value="2" />
<el-radio-button label="已完成" :value="1" />
<el-radio-button label="未完成" :value="0" />
</el-radio-group>
<el-table :data="showTodoList" border style="width: 100%">
<el-table-column fixed prop="sign" label="#">
<template #default="scope">
<el-checkbox
v-model="scope.row.isComplete"
@change="signTodoComplete(scope.row.id)"
/>
</template>
</el-table-column>
<el-table-column fixed prop="todoName" label="任务名称" />
<el-table-column prop="createTime" label="创建时间" width="150" />
<el-table-column prop="completeTime" label="完成时间" width="150" />
<el-table-column prop="showTaskStatus" label="是否完成" width="120" />
<el-table-column fixed="right" label="操作" width="120">
<template #default="scope">
<el-button
link
type="primary"
size="small"
@click="deleteTodo(scope.row)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { ref, reactive, computed } from "vue";
import { timeFormat, generateId } from "@/util/index";
enum TaskStatus {
no = 0, //未完成
yes = 1, //完成
}
interface Todo {
id: number;
todoName: string;
createTime: string;
completeTime: string | null;
taskStatus: TaskStatus;
}
const input = ref(""); //总任务列表
const todoList: Todo[] = []; //总任务列表
const todoListRef = ref(todoList);
const filterStatus = ref(2); //给个默认值,默认显示全部
init();
/**
* 初始化会去从缓存里面读取值
*/
function init() {
const todoLocalStorage = localStorage.getItem("todoList");
const todoList = todoLocalStorage ? JSON.parse(todoLocalStorage) : [];
todoListRef.value.push(...todoList);
}
// 添加一个任务处理函数
function addTodoHandle() {
if (!input.value) {
ElMessage({
showClose: true,
message: "任务名称不能为空!!",
type: "error",
});
return;
}
// 创建任务
createTodo(input.value);
// 清空文本框的值
input.value = "";
}
//当前显示的todolist
const showTodoList = computed(() => {
const newTodoList = [];
// 显示全部
if (filterStatus.value === 2) {
newTodoList.push(...todoListRef.value);
}
// 其他两个显示
else {
const ftTodoList = todoListRef.value.filter((todo) => {
return todo.taskStatus === filterStatus.value;
});
newTodoList.push(...ftTodoList);
}
const showTodoList = newTodoList.map((todo) => {
const newTodo = {
...todo,
showTaskStatus: getShowTaskStatus(todo.taskStatus),
isComplete: todo.taskStatus === TaskStatus.yes ? true : false,
};
return newTodo;
});
return showTodoList;
});
/**
* 创建一个任务
*/
function createTodo(todoName: string) {
// 任务对象
const todoObj: Todo = {
id: generateId(),
todoName,
createTime: timeFormat(new Date()),
completeTime: null,
taskStatus: TaskStatus.no,
};
todoListRef.value.push(todoObj);
// 记录到缓存
setStorage(todoListRef.value);
}
/**
* 删除一个任务
*/
function deleteTodo(id: number) {
const index = todoListRef.value.findIndex((todo) => {
return todo.id === id;
});
todoListRef.value.splice(index, 1);
// 记录到缓存
setStorage(todoListRef.value);
}
/**
* 给某个任务标记完成
*/
function signTodoComplete(id: number) {
const index = todoListRef.value.findIndex((todo) => {
return todo.id === id;
});
// 完成和未完成的切换
todoListRef.value[index].taskStatus =
todoListRef.value[index].taskStatus === TaskStatus.no
? TaskStatus.yes
: TaskStatus.no;
// 缓存记录
setStorage(todoListRef.value);
}
/**
* 拿到任务状态的中文信息
*/
function getShowTaskStatus(val: number) {
let str = "";
switch (val) {
case 0:
str = "未完成";
break;
case 1:
str = "已完成";
break;
}
return str;
}
function setStorage(todoList: Todo[]) {
localStorage.setItem("todoList", JSON.stringify(todoList));
}
</script>
<style lang="scss" scoped>
.op-container {
margin-bottom: 10px;
}
.todo-list-container {
max-width: 800px;
margin: 0 auto;
}
.filters {
margin: 0;
padding: 0;
list-style: none;
li {
display: inline;
a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
&:hover {
border-color: rgba(175, 47, 47, 0.1);
}
&.selected {
border-color: rgba(175, 47, 47, 0.2);
}
}
}
}
</style>
效果预览
最后回复
结语
我觉得一个前端开发者来说,熟悉底层熟悉原理是最重要的事情,知道了原理,知道了哪些工具是用来干什么的,解决什么样的问题的,大局观比较重要,至于ui框架,一些js库都是顺带学习的事情,那些ui,js框架等等不都是基于原生的吗,能够解决问题的人不才是公司所需要的吗?我是一个热爱it的存粹的技术开发,就算一时找不到工作也无法让我气馁,只会越挫越勇把,加油,就算it这行走不通,也不影响我对它的兴趣和热情。