公司有个H5项目,简单试一下水,以答题问卷的小功能做示例。可单选题,和多选题(选择题中可以选择某个选项,可上传图片或文字),以及文字题和图片集题(图片,图片描述),必选校验也加了,图片简单压缩处理。为什么选择题选项可以输入文字和图片,只能说甲方永远是爸爸。

但凡在Vue3项目中,使用基于vue的第三方插件(组件)请确保支持Vue3版本,如果不支持,就不要使用基于vue2的(当然你知道如何改包源码)。常见的错误,this的指向,emit,emit,emit,on, new Vue()…

页面


创建

vue create project-name

路由

"vue-router": "^4.0.6"


// main.js
import { router } from "./router";const app = createApp(App);
app.use(router);
app.mount("#app");// router.js
import {createRouter,createWebHashHistory,// createWebHistory,
} from "vue-router";const router = createRouter({routes: [{path: "/",name: "home",component: () => import("./view/Home.vue"),children: [],}]
}
export { router };// page.vue
import { useRouter, useRoute } from "vue-router";setup() {const router = useRouter();  // <=== this.$routerconst route = useRoute(); // <=== this.$route}

问卷答题

后端返回json

{"id":71,"title":"全类型", // 问卷标题"itrQuestions":[  // 页面渲染时需遍历的对象  对应下面vue页面的questionsList{"id":347,"questionnaireId":71,"questionType":1, // 题目类型 1单 2多 3 文本 4 {图片,图片描述}"isRequired":1, // 是否必填 0 是 1 非"questionTitle":"单选题", // 题目标题"itrQuestionOptions":[ // 选项{"id":678,"questionId":347,"context":"选项1","optionFlag":3, // 是否支持选择选项后输入文字/图片/无 这块可以不用    3无 1 文字 2 图片},{"id":679,"questionId":347,"context":"选项2","optionFlag":1,},{"id":680,"questionId":347,"context":"选项3","optionFlag":2,}]},{"id":348,"updateTime":null,"questionnaireId":71,"questionType":2,"isRequired":1,"questionTitle":"多选题","itrQuestionOptions":[{"id":681,"questionId":348,"context":"选项1","optionFlag":1,},{"id":682,"questionId":348,"context":"选项2","optionFlag":2,},{"id":683,"questionId":348,"context":"选项3","optionFlag":3,}]},{"id":349,"questionnaireId":71,"questionType":3,"isRequired":1,"questionTitle":"填空题","itrQuestionOptions":{}},{"id":350,"questionnaireId":71,"questionType":4,"isRequired":1,"questionTitle":"图片题","itrQuestionOptions":{}}]
}
思路

根据不同题型判断渲染不同视图。遍历题目时候,根据题型动态追加属性接受答案 单选radioValue 多选checkboxValue 文本textValue和图片描述 imgAndDesList。在vue3可以使用 reactive的api给对象直接追加新属性, item.xxx 可以使xxx达到双向绑定的效果,不必像vue2 this.$set(obj, key, value)繁琐。对象属性多的话,toRefs()将响应式的对象变为普通对象 再解构,属性可以渲染页面。不需要每次页面{{ 对象.属性}}。

一般情况这样做就行了。因为所有想要的数据字段都是响应式的,到最后,打印questionsList,按照后台格式传参就行了。

因为我这边单选和多选,还能上传图片和文字,所以我又在对应选择题选项遍历时又判断追加动态属性了。这是后话,一般正常题型用不到,有兴趣的话可以看看。

UI组件,选的时vantUI,支持vue3,nice

vue

    <van-form @submit="submit" @failed="failed"> // 验证成功的提交事件  校验失败的事件<div v-if="questionsList.length" class="question-wrap"><divv-for="(item, index) in questionsList":key="item.id"class="question-li"><div class="title"><div><divv-if="item.isRequired == 0">*</div><div v-html="index + 1 + '.' + item.questionTitle"></div></div></div><div v-if="item.questionType === 1"><div v-if="item.itrQuestionOptions"><van-fieldname="radio":rules="[{required: item.isRequired === 0,message: '该选项是必填项',},]"><template #input><van-radio-group v-model="item.radioValue"><divv-for="oItem in item.itrQuestionOptions":key="oItem.id"class="option"><van-radiostyle="color:red"checked-color="#DC3538":name="oItem.id"><template #default><div v-html="oItem.context"></div></template></van-radio><divv-if="item.radioValue == oItem.id"><van-fieldv-if="oItem.optionFlag === 1"v-model="oItem.textSelf"placeholder="请输入"/><van-uploaderv-if="oItem.optionFlag === 2"v-model="oItem.imgSelf":max-count="1"/></div></div></van-radio-group></template></van-field></div></div><div v-if="item.questionType === 2"><div v-if="item.itrQuestionOptions"><van-fieldname="radio":rules="[{required: item.isRequired === 0,message: '该选项是必填项',},]"><template #input><van-checkbox-groupv-model="item.checkboxValue"checked-color="#DC3538"><divv-for="oItem in item.itrQuestionOptions":key="oItem.id"class="option"><van-checkbox shape="square" :name="oItem.id"><template #default><div v-html="oItem.context"></div></template></van-checkbox><divv-if="item.checkboxValue &&item.checkboxValue.indexOf(oItem.id) > -1"><van-fieldv-if="oItem.optionFlag === 1"v-model.stop="oItem.textSelf"placeholder="请输入"/><van-uploaderv-if="oItem.optionFlag === 2"v-model.stop="oItem.imgSelf":max-count="1"/></div></div></van-checkbox-group></template></van-field></div></div><div v-if="item.questionType === 3"><van-fieldclass="text"v-model="item.textValue"rows="3"autosizetype="textarea"maxlength="50"placeholder="请将问题填写在这里"show-word-limit:rules="[{required: item.isRequired === 0,message: '请将问题填写在这里',},]"/></div><div v-if="item.questionType === 4" ><van-fieldname="validator":rules="getRule(item)" // 不是常规校验方法,单独抽离><template #input><divv-if="item.imgAndDesList && item.imgAndDesList.length"><divv-for="(item2, index) in item.imgAndDesList":key="index"><div><van-image:src="item2.base64"width="80"height="80"style="width:80px"fit="contain"></van-image><van-iconname="clear"color="#DC3538"@click="deleteImgItem(item, index)"/></div><van-fieldclass="text"v-model="item2.remark"type="textarea"autosizemaxlength="50"placeholder="请输入图片备注信息"show-word-limit/></div><div v-if="item.imgAndDesList.length !== 10"><van-uploader:after-read="afterRead(item)":before-read="beforeRead"upload-text="上传图片"/></div></div><div v-else><van-uploader:after-read="afterRead(item)":before-read="beforeRead"upload-text="上传图片"/></div></template></van-field></div></div></div><van-buttontype="primary"native-type="submit"block:disabled="btnDisabled"color="#DC3538"round>提交</van-button></van-form>

js

import { compress } from "image-conversion"; //对图片压缩setup(){const answerInfo = reactive({questionsList: [], // 后台接受字段赋值});const beforeRead = async (file) => { // 做图片拦截压缩const resBlob = await compress(file, 0.6); // 它返回的是Blob文件格式,我要File,自己按照项目需求const resFile = new window.File([resBlob], file.name, { type: file.type,});return resFile;};const getRule = (item) => { // 图片 + 描述 自定义校验规则return [{ item: item, validator: validator, message: "图片必选上传" }];};const validator = (item, rule) => {if (rule.item.isRequired === 0) { // 必填if (rule.item.imgAndDesList && rule.item.imgAndDesList.length > 0) {return true;} else {return "图片必选上传";}} else {return true;}};// 图片删除const deleteImgItem = (item, index) => {item.imgAndDesList.splice(index, 1);};const afterRead = (item) => {  // file和自定义传参,注意一下return (file) => {const imgAndDes = {base64: file.content, // 页面我先base64预览的remark: "",file: file.file,};if (item.imgAndDesList && item.imgAndDesList.length) { //虽然是双向绑定,但是初始值类型不确定,push会报错item.imgAndDesList.push(imgAndDes);} else {item.imgAndDesList = [];item.imgAndDesList.push(imgAndDes);}};};const failed = () => {Toast("必答题未答,请重新确认"); // 不仅题目处有提示,最好有个弹框,用户体验};const submit = async () => {btnDisabled.value = true;const answer = answerInfo.questionsList;console.log(answer, "answer"); 到最后数据格式见下文图片,之后根据后台想要的数据格式处理}return {submit,failed,afterRead,getRule,validator,beforeRead,...toRefs(answerInfo),};}
answer打印如下

单选,选择的id, (若选项支持上传图片,字段imgSelf)

多选,选择的id, (若选项支持上传文本,字段textSelf)

单纯文本题目

图片集 [ {图片文件对象,图片描述}]

这边我是整体提交时图片统一上传服务器,个人而已(最好是出两个接口,增与删,免得服务器有压力),到最后根据后台想要的格式整理,完工提交。

友情提示:安卓拍照立马上传是=时文件名是唯一随机,类似于时间戳,但是苹果却是IMAGE。

收工

Vue3答题问卷H5实战相关推荐

  1. 粉丝测试题的软件,套路得粉丝的答题类H5推荐

    原标题:套路得粉丝的答题类H5推荐 互吾小编总结了最近热门的h5,有个结论,就是测试类的H5一直是品牌营销界的常胜将军.特别是一些能够体现高智商,或者是好人品的结果,被分享的几率奇高.测试类产品还有一 ...

  2. h5优秀控件_H5匠人手册:霸屏H5实战解密

    这是一本关于H5设计方法和设计流程的书,作者为近年来佳作频出的网易传媒设计中心,其代表作品有<娱乐圈画传><里约小人大冒险><我是一只快乐的羊驼><滑向童年& ...

  3. Vue3搭建微信H5的项目配置【前端】

    在真实上线的项目中,写UI花费的时间仅仅是一小部分,项目的一些配置才真的头疼(如设备适配等).这里小结一下我自己用vue3写微信H5中的一些配置: 一.项目结构 src - api - assets- ...

  4. 已被多次定制!!“模拟微信答题的H5小游戏

    今天推荐一款"模拟微信"答题的H5小游戏,这个也是涛舅舅这边客户定制的最多的一款游戏,曾经为现代汽车.万达.和<三妹>电视剧都作过定制! 以下是<三妹>定制 ...

  5. vue3.0 + ts H5拍照组件

    vue3.0 + ts H5拍照组件 实现了简单的拍照功能,拍照成功返回文件对象.(待更新,裁剪,缩放,旋转) 效果图 使用 通过npm下载 npm i wl-easy-ui 或者通过yarn add ...

  6. 直播答题html,H5实现直播答题可能吗?

    原标题:H5实现直播答题可能吗? 2018年开局,以王思聪为首的一群自带话题流量的人物,在网络上争起谁是"大撒币"的称号,很难不引起舆论的注意,为了给自家的直播答题争抢流量,各大平 ...

  7. uni-app、Vue3 + ucharts 图表 H5 无法渲染

    当学习成为了习惯,知识也就变成了常识.感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github,欢迎 Watch 和 Star. 简介 ...

  8. 单页应用html5答题问卷,问卷调查:巧用问卷网功能,提高答卷质量

    原标题:问卷调查:巧用问卷网功能,提高答卷质量 于一位问卷设计和收集者来说,答卷的质量真的是非常非常重要的一件事情,尤其是用于市场调研的问卷.数据质量差,所有努力都白搭,出来的结果自然是不靠谱的. 可 ...

  9. 基于vue-next(vue3)企业微信H5搭建

    背景 业务需要,需要编写一个服务在企业微信里面的H5应用.需要解决的问题有: UI库选型 响应式布局 按需引入组件 企业微信登录 本地预览 http请求 水印 企业微信桌面端支持 UI库选型 已有的移 ...

最新文章

  1. Linux下文件如果没有权限不能被Apache访问
  2. atitit.复合变量,也就是类似$$a的变量的原理与实现 java c#.net php js
  3. 安装VMware,出现Microsoft Runtime DLL 安装程序未能完成安装,解决方法
  4. 升级Firefox8后watir-webdriver出现错误“unable to obtain stable firefox connection in 60 seconds”...
  5. oracle fuser lk,oracle错误集锦
  6. python opencv cv2.imdecode()函数(从内存中的缓冲区读取图像)
  7. 【LCT】弹飞绵羊(luogu 3203/金牌导航 LCT-2)
  8. linux 下显卡优化,[转载]Linux 下 NVIDIA 显卡闭源驱动的一些优化
  9. python 函数参数枚举_Python中的枚举:如何在方法参数中强制执行
  10. NeHe OpenGL教程 第四十四课:3D光晕
  11. 网站被k的症状原因有哪些-怎么恢复
  12. .Net Core之MVC项目的简单应用
  13. spring加载bean的流程
  14. 架构 简述负载均衡和CDN技术
  15. [偏相关分析]偏相关系数计算及假设检验
  16. 【转】Filter Concatenation理解
  17. 使用nodejs pkg创建exe文件后更改图标
  18. html5 指南针,14.html5 作业 简单移动端-指南针 用 canvas 画一下.
  19. 利用python多个工作簿合并到一个工作簿
  20. 提高INSERT速度

热门文章

  1. minecraft有自带服务器吗,Minecraft服务器优化教程 —— 让多带50%的玩家不再是梦...
  2. 有关lpk.dll病毒的清除方法
  3. 超市收银系统无法连接服务器,超市收银系统常见问题介绍与回答
  4. 逐字稿整理-中/TED演讲:如何训练思维,突破局限?(大花猫冯夏)
  5. 帝国cms插件|支持7.5/7.2 移动同步生成插件|帝国多端访问必备插件
  6. jQuery多余文字折叠效果
  7. 一分钟搞懂X86架构
  8. Mac 双系统bootcamp不能正常卸载windows系统
  9. 3月刊特别策划:移动应用排名与开发者的机会
  10. RVV线与RV线有什么区别