心愿便利贴

介绍

小蓝发现人之间面对面交流逐渐减少,倾诉的机会变少了,有些人比较腼腆保守,不敢大声说出自己的心里话,期盼之类的,容易造成压力过大,心愿便利贴可以匿名,提供大家安全隐秘方便的倾诉平台。

小蓝希望大家写下自己的目标、理想、愿望等,激励自己奋斗,积极向上……写出来做一个精神寄托。

可是,小蓝对 Vue 语法不熟,便利贴没能完成,快来帮助小蓝完成吧!

准备

本题已经内置了初始代码,打开实验环境,目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
├── css
│ ├── fonts
│ │ ├── element-icons.ttf
│ │ └── element-icons.woff
│ ├── index.css
│ └── wish.css
├── images
│ ├── bg.jfif
│ └── ding.png
├── index.html
└── js
├── index.js
└── vue.min.js

其中:

  • index.html 是主页面。
  • csselement-ui 存放项目样式的文件夹。
  • images 是图片文件夹。
  • js 是项目所依赖的 js 库的文件夹。

注意:打开环境后发现缺少项目代码,请复制下述命令至命令行进行下载。

1
wget https://labfile.oss.aliyuncs.com/courses/18164/wish.zip && unzip wish.zip && rm wish.zip

在浏览器中预览 index.html 页面效果如下:

初始效果

在初始化的时候输入框并没有做验证,输入内容发布后,许愿贴并不能出现。

目标

请在 index.html 文件中补全代码,具体需求如下:

  1. 将填写完的表单正确渲染到许愿墙上。
  2. 完成表单验证,姓名(必填项) 2-4 个字符,许愿内容(必填项)长度在 1 到 30 个字符。

本项目使用到的 element-ui 表单验证 API 如下:

表单属性

参数 说明 类型
rules 表单验证规则 object

表单项属性

参数 说明 类型 可选值 默认值
prop 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 string 传入 Form 组件的 model 中的字段 -
required 是否必填 boolean - false
trigger 验证时触发的事件 string click/focus/change/blur/input -
min 最小长度 number - -
max 最大长度 number - -
message 验证不通过时的错误信息 string - -

使用示例

1
2
3
4
5
6
7
8
9
10
   <el-form-item label="姓名" prop="activeName">
<el-input v-model="form.activeName" placeholder="请输入姓名"></el-input>
</el-form-item>
// ....
rules: {
activeName: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
}

完成后效果如下:

完成效果

规定

  • 请按照给出的步骤操作,切勿修改默认提供的文件名称、文件夹路径等。
  • 满足需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动检测。

判分标准

  • 本题完全实现题目目标得满分,否则得 0 分。

总通过次数: 1297 | 总提交次数: 1346 | 通过率: 96.4%

难度: 中等 标签: 2022, 省模拟赛, Web 前端, Vue.js, ElementUI

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>心愿便利贴</title>
<!-- 引入element-ui样式 -->
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="./css/wish.css">
<!-- 引入element-ui组件库 -->
<script src="./js/vue.min.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<div id="app">
<h1>心愿便利贴</h1>
<div class="container">
<!-- TODO 待修改的代码 -->
<div class="card" :class="item.css" v-for="(item,index) in wishList" :key="index">
<div class="header">
<img class="close" @click="closeCard(index)" src="./images/ding.png" alt="close">
</div>
<el-image
v-if="item.pic"
style="width: 100px; height: 100px"
:src="item.pic"
:preview-src-list="picList">
</el-image>
<div class="content">
{{item.content}}
</div>
<div class="name">{{item.name}}</div>
</div>
</div>
<div class="form">
<el-form ref="form" :rules="rules" label-position="left" :model="form" label-width="80px">
<el-form-item label="姓名" prop="name">
<el-input id="firstName" v-model="form.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="许愿内容" prop="content">
<el-input type="textarea" id="content" placeholder="请输入内容" v-model="form.content" show-word-limit></el-input>
</el-form-item>
<el-form-item label="图片上传">
<el-upload
ref="uploadRef"
action="#"
:limit="1"
list-type="picture-card"
:on-remove="handleRemove"
:on-change="getPic"
:auto-upload="false">
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{file}">
<img
class="el-upload-list__item-thumbnail"
:src="file.url"
>
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
@click="handlePictureCardPreview(file)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button id="onSubmit" type="primary" @click="onSubmit">发布</el-button>
<el-button @click="onRest">重置</el-button>
</el-form-item>
</el-form>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="form.pic" alt="">
</el-dialog>
</div>
</div>
</body>
<script>
const app = new Vue({
el: "#app",
data: {
wishList: [],
form: {
name:'',
content: '',
pic: ''
},
rules: {
// TODO 待补充验证的代码
name: [
{required: true, trigger: 'blur', min: 2, max: 4, message: '长度在2-4字符'}
],
content: [
{
required: true,
trigger: 'blur',
min: 1,
max: 30,
message: '长度在1-30'
}
]
},
num:1,
picList: [],
textarea: '',
dialogVisible: false,
disabled: false
},
methods: {
// 提交方法
onSubmit() {
this.$refs['form'].validate((valid) => {
if (valid) {
let obj = this.form;
obj.css = 'item' + this.num;
this.num++;
if(this.num > 4) {
this.num = 1;
}
this.wishList.push(obj)
this.form = {};
this.$refs.uploadRef.uploadFiles.pop()
console.log(this.wishList);
// render
} else {
this.$message({
message: '提交错误!请检查输入内容',
type: 'warning'
});
return false;
}
});
},
// 关闭许愿卡
closeCard(index) {
this.wishList.splice(index,1)
},
// 重置表单
onRest() {
this.$refs['form'].resetFields();
},
// 图片删除
handleRemove(file) {
let index = this.$refs.uploadRef.uploadFiles.findIndex(e => e.uid === file.uid);
this.$refs.uploadRef.uploadFiles.splice(index,1);
},
// 模拟上传图片
getPic(e) {
this.form.pic = e.url;
this.picList.push(e.url)
},
// 预览图片
handlePictureCardPreview(file, fileList) {
this.form.pic = file.url;
this.dialogVisible = true;
}
}
});
</script>
</html>