摘要:項(xiàng)目地址源碼地址預(yù)覽地址沒有做響應(yīng)式,請?jiān)陔娔X上打開使用了我自制的日歷組件初學(xué)時(shí)做的,有些糙任務(wù)描述參考設(shè)計(jì)圖實(shí)現(xiàn)一個(gè)簡易版的問卷管理系統(tǒng),有如下功能問卷管理列表有一個(gè)頭部可以顯示,不需要實(shí)現(xiàn)登錄等操作問卷管理列表頁面默認(rèn)為首頁有一個(gè)表格
項(xiàng)目地址
源碼地址
預(yù)覽地址(沒有做響應(yīng)式,請?jiān)陔娔X上打開)
使用了我自制的日歷組件(初學(xué)vue時(shí)做的,有些糙)calendar-input
任務(wù)描述參考設(shè)計(jì)圖
實(shí)現(xiàn)一個(gè)簡易版的問卷管理系統(tǒng),有如下功能:
問卷管理列表有一個(gè)頭部可以顯示logo,不需要實(shí)現(xiàn)登錄等操作
問卷管理列表頁面默認(rèn)為首頁
有一個(gè)表格用于展示所有已創(chuàng)建的問卷
列表中包括列有:問卷名稱,問卷狀態(tài)(未發(fā)布,發(fā)布中,已結(jié)束),和操作區(qū)域(編輯、刪除、查看數(shù)據(jù))
問卷狀態(tài)為未發(fā)布時(shí),可以做的操作為編輯、刪除、查看問卷
問卷狀態(tài)為發(fā)布中和已結(jié)束時(shí),可以做的操作為查看數(shù)據(jù)、查看問卷
表格最左側(cè)有批量選擇(多選)的checkbox,多選后,可以進(jìn)行批量刪除功能,checkbox樣式用默認(rèn)即可,不需要按照設(shè)計(jì)圖的樣式
當(dāng)一個(gè)問卷都沒有的時(shí)候,表格不展現(xiàn),頁面顯示大大的新建問卷按鈕
問卷新建及編輯點(diǎn)擊問卷管理列表中的新建按鈕后,進(jìn)入到問卷新建頁面
點(diǎn)擊問卷列表中某個(gè)問卷行的編輯按鈕后,進(jìn)入到問卷的編輯頁面
新建頁面和編輯頁面基本相同
問卷有一個(gè)標(biāo)題字段,點(diǎn)擊后可以進(jìn)入編輯狀態(tài)
可以針對問卷中的問題進(jìn)行增刪改操作,每個(gè)問卷最少一個(gè)問題,最多十個(gè)問題
問題類型包括:單選題、多選題、單行文本題
可以對所有問題進(jìn)行位置改變(上移、下移),復(fù)用,刪除的操作
最上面的問題沒有上移操作,最下面的問題沒有下移操作
點(diǎn)擊復(fù)用時(shí),在被復(fù)用的問題緊接著的下方新增一個(gè)和被復(fù)用完全一樣的問題(包括選項(xiàng))
對于單選題和多選題,可以對問題的選項(xiàng)進(jìn)行增、刪、改、排序操作
文本題可以設(shè)定是必填還是非必填的問題
有一個(gè)問卷調(diào)查填寫截止時(shí)間,使用一個(gè)日歷組件來進(jìn)行時(shí)間的選擇,日期選擇不能早于當(dāng)前日期
保存問卷可以進(jìn)行問卷的保存
發(fā)布問卷可以使得問卷狀態(tài)變?yōu)榘l(fā)布中的狀態(tài)
當(dāng)點(diǎn)擊發(fā)布時(shí),如果截止日期早于當(dāng)前日期,則需要提示修改截止日期
刪除問卷在問卷管理列表中點(diǎn)擊某個(gè)問卷的刪除按鈕后,彈出一個(gè)浮出層,讓用戶二次確認(rèn)是否刪除該問卷,如果用戶點(diǎn)擊是,則刪除掉該問卷
查看問卷在問卷管理列表中點(diǎn)擊查看問卷的按鈕后,在新窗口中打開該問卷的頁面,該頁面是可供用戶進(jìn)行問卷填寫的頁面,在問卷未發(fā)布狀態(tài)和已結(jié)束狀態(tài)時(shí),問卷提交是無效的。
該頁面在移動端需要進(jìn)行良好的兼容支持
查看數(shù)據(jù)在問卷管理列表中點(diǎn)擊查看數(shù)據(jù)按鈕后,進(jìn)入到一個(gè)數(shù)據(jù)報(bào)告頁面,用圖表形式呈現(xiàn)各個(gè)單選題和多選題的選擇情況
如設(shè)計(jì)稿中呈現(xiàn),每一個(gè)問題在右側(cè)用某種圖表來呈現(xiàn)答題情況,自行選擇合適的圖表,設(shè)計(jì)稿中僅為示意,圖表樣式不需要和設(shè)計(jì)稿一致。推薦單選題使用餅狀圖,多選題使用條形圖
文本題用一個(gè)百分比圖展現(xiàn)有效回答占比即可
返回按鈕點(diǎn)擊后返回列表頁面
在項(xiàng)目中嘗試模塊化的方法及工具
在項(xiàng)目中嘗試CSS預(yù)處理工具
在項(xiàng)目中嘗試項(xiàng)目構(gòu)建、打包工具
問題總結(jié) 全選功能的實(shí)現(xiàn)首先每個(gè)列表項(xiàng)都使用了v-model進(jìn)行雙向數(shù)據(jù)綁定傳遞是否被選中狀態(tài)
然后給全選按鈕也用v-model綁定是否全選狀態(tài)
下一步在computed中定義三個(gè)計(jì)算屬性
selectAll: 是否全選
selectCount: 計(jì)算有多少項(xiàng)被選中
selectGroup: 存儲當(dāng)前選中項(xiàng),以便對它們進(jìn)行操作
selectAll計(jì)算屬性:
selectAll: { get() { //this.qsList是一個(gè)數(shù)組,理解代碼時(shí)可以看為[{checked: false}, {checked: false}] return this.selectCount === this.qsList.length && this.selectCount !== 0; }, set(value) { this.qsList.forEach( item => { item.checked = value; } ); return value; } }
通過get方法獲取當(dāng)前選中數(shù),從而實(shí)現(xiàn)當(dāng)列表項(xiàng)全被選中時(shí),全選按鈕自動被選中
通過set方法實(shí)現(xiàn)當(dāng)全選按鈕選中時(shí),所有列表項(xiàng)也被選中
selectCount計(jì)算屬性
selectCount() { let i = 0; this.qsList.forEach( item => { if (item.checked) i++; } ); return i; },
計(jì)算當(dāng)前有多少項(xiàng)被選中,selectAll通過此變量來計(jì)算當(dāng)前是否所有列表項(xiàng)都被選中
selectGroup計(jì)算屬性
selectGroup() { let group = []; this.qsList.forEach( item => { if (item.checked) group.push(item); } ); return group; }
存儲被選中項(xiàng),進(jìn)行統(tǒng)一操作
檢測表單必填項(xiàng)是否填寫這個(gè)問題我使用了v-model來解決,問卷中總共有三種類型的表單項(xiàng),radio,checkbox,textarea 因?yàn)閷τ趓adio的v-model來說只能綁定一個(gè)基本類型的值, checkbox的v-model應(yīng)該綁定一個(gè)數(shù)組,這樣選中項(xiàng)就會一個(gè)一個(gè)push到數(shù)組中,而且是雙向綁定的,textarea的v-model也應(yīng)該是一個(gè)基本類型,我設(shè)置的是字符串
//獲取必選項(xiàng),用對象存儲起來,相當(dāng)于 {1: "", 2: [], 3: ""} getRequiredItem() { this.qsItem.question.forEach( item => { if (item.isNeed) { if (item.isNeed) { if (item.type === "checkbox") { this.requiredItem[item.num] = [] //多選框雙向綁定的值 } else { this.requiredItem[item.num] = "" //單選框 文本框雙向綁定的值 } } } } ) } //直接檢測雙向綁定的值的內(nèi)容長度即可知道必填項(xiàng)是否有值 validate() { for (let i in this.requiredItem) { if (this.requiredItem[i].length === 0) return false } return true }
這里還有一個(gè)問題,我現(xiàn)在在v-for中通過v-if來判斷表單項(xiàng)類型,這樣看起來有些冗余,為什么不直接動態(tài)綁定type來渲染表單項(xiàng)呢,這樣就不用v-if了
這樣看起來簡潔多了,但是這樣寫會報(bào)錯(cuò),v-model不能綁定在type屬性為動態(tài)值的表單項(xiàng)上,即type是bind的表單項(xiàng)不能用v-model,所以這里只能退一步使用v-if來選擇渲染哪種類型的表單項(xiàng)
當(dāng)用戶點(diǎn)擊刪除某一項(xiàng)時(shí),一般的做法時(shí)彈出一個(gè)彈出層詢問用戶是否刪除,用戶點(diǎn)擊確定再進(jìn)行刪除操作。這時(shí)只要給確定按鈕綁定一個(gè)點(diǎn)擊事件進(jìn)行刪除操作即可,但是當(dāng)要多次點(diǎn)擊確定進(jìn)行下一個(gè)步驟,或者頁面多個(gè)操作事件都是彈出這個(gè)彈出層,這時(shí)確定按鈕就要去判斷綁定哪個(gè)操作事件等等,很快就變得非常復(fù)雜起來
這里可以使用ES6的Generator函數(shù),可以很方便的解決這個(gè)問題
提示 X {{info}}
彈出層內(nèi)容
data() { return { qsList: [], showDialog: false, //是否顯示彈出層 iterator: {}, //當(dāng)前迭代器 info: "" //彈出層提示內(nèi)容 } }
data中的數(shù)據(jù)
*delItem(num) { yield this.showDialogMsg("確認(rèn)要?jiǎng)h除此問卷") yield (() => { let index = 0; for (let length = this.qsList.length; index < length; index++) { if (this.qsList[index].num === num) break; } this.qsList.splice(index, 1); this.showDialog = false; })(); }, *delItems() { yield this.showDialogMsg("確認(rèn)要?jiǎng)h除選中的問卷?"); yield (() => { this.showDialog = false; if (this.selectAll) { this.qsList = []; return; } if (this.selectGroup == []) return; this.selectGroup.forEach( item => { if (this.qsList.indexOf(item) > -1) this.qsList.splice(this.qsList.indexOf(item), 1); } ) })(); }, *edit(item) { yield (() => { if (item.state === "noissue") { this.showDialogMsg("確認(rèn)要編輯?"); } else { this.showDialogMsg("只有未發(fā)布的問卷才能編輯"); } })(); yield (() => { if (item.state !== "noissue") { this.showDialog = false; } else { this.showDialog = false; this.$router.push({name: "qsEdit", params: { num: item.num }}) } })(); }, *watchData(item) { yield (() => { if (item.state === "noissue") { this.showDialogMsg("未發(fā)布的問卷無數(shù)據(jù)可查看"); } else { this.$router.push({ name: "qsData", params: { num: item.num }}) } })(); yield this.showDialog = false; }
可以看到 頁面中多個(gè)操作都綁定在一個(gè)彈出層上,實(shí)現(xiàn)最大程度的復(fù)用,而且不會沖突,只要把當(dāng)前要執(zhí)行的操作的迭代器賦給確定按鈕,確定按鈕執(zhí)行next方法即可
v-for每次渲染元素就自動執(zhí)行一個(gè)函數(shù)有時(shí)我們需要v-for的每次遍歷中就執(zhí)行一個(gè)函數(shù),我們可以這樣
但是這種做法如果執(zhí)行比較復(fù)雜的方法很容易出現(xiàn)一些錯(cuò)誤比如無限循環(huán)等錯(cuò)誤,而且也不推薦
根據(jù)需要可以考慮在js中再次遍歷這個(gè)數(shù)據(jù)然后在遍歷中對每一項(xiàng)進(jìn)行操作
在編輯問卷功能中,題目號應(yīng)該要根據(jù)題目的上移下移復(fù)用刪除新建等操作進(jìn)行變化,我使用了watch來監(jiān)測變化然后更改題號
watch: { "$route": "fetchData", qsItem: { handler(newVal) { newVal.question.forEach( (item, index) => { item.num = `Q${index + 1}` } ) }, deep: true } }
我在進(jìn)行上移,下移,刪除,新建問題等操作時(shí)都沒有問題,但是在復(fù)用操作時(shí)產(chǎn)生了無限循環(huán)的問題
復(fù)用
復(fù)用按鈕,和復(fù)用方法
copy(index, qs) { if (this.questionLength === 10) return alert("問卷已滿!") this.qsItem.question.splice(index, 0, qs) }
這樣寫看起來沒什么問題,哪個(gè)item下的復(fù)用按鈕被點(diǎn)擊,就將這個(gè)item添加到自己下一項(xiàng)。
但是qs添加到watch監(jiān)測的變量中后,會觸發(fā)watch的方法,更改題目號,即qs的題目號被更改,同時(shí)qs又是那個(gè)被點(diǎn)擊的item,它們之間存在引用,這就會造成qs題目號的更改會使點(diǎn)擊的item的題目號跟著一起變化,這樣item一變化,watch又被觸發(fā),同時(shí)item的題目號因?yàn)楦黄鹱兓?,?dǎo)致題目號不是它正確的題目號,watch觸發(fā)后,item的題目號又會變化為原來的,因?yàn)榇嬖谝胵s的又會跟著變,然后再次觸發(fā)watch....一直循環(huán)下去
解決方法是用Object.assign()進(jìn)行一次深拷貝,這樣qs和item之間就不存在引用了
copy(index, qs) { if (this.questionLength === 10) return alert("問卷已滿!") qs = Object.assign({}, qs) this.qsItem.question.splice(index, 0, qs) }
這種做法不推薦,因?yàn)檫@種情況下使用watch本來就是不應(yīng)該的,非常容易造成想不到的問題
推薦的做法是將watch中的方法封裝成一個(gè)函數(shù),每次操作時(shí)就調(diào)用這個(gè)函數(shù),當(dāng)然還是需要Object.assign()來解除復(fù)用元素之間的綁定
這里我為了練習(xí)還是使用了watch這個(gè)不推薦的方法
總結(jié)完成,交作業(yè)了
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/111844.html
摘要:項(xiàng)目地址源碼地址預(yù)覽地址沒有做響應(yīng)式,請?jiān)陔娔X上打開使用了我自制的日歷組件初學(xué)時(shí)做的,有些糙任務(wù)描述參考設(shè)計(jì)圖實(shí)現(xiàn)一個(gè)簡易版的問卷管理系統(tǒng),有如下功能問卷管理列表有一個(gè)頭部可以顯示,不需要實(shí)現(xiàn)登錄等操作問卷管理列表頁面默認(rèn)為首頁有一個(gè)表格 項(xiàng)目地址 源碼地址 預(yù)覽地址(沒有做響應(yīng)式,請?jiān)陔娔X上打開) 使用了我自制的日歷組件(初學(xué)vue時(shí)做的,有些糙)calendar-input 任...
摘要:年新星調(diào)查中顯示,越來越流行,其熱度已經(jīng)逐漸超過了。及其框架位于全球最受歡迎使用最廣泛的技術(shù)榜榜首。本文轉(zhuǎn)載自框架的游戲年流行趨勢英文原文JavaScript 生態(tài)系統(tǒng)復(fù)雜多變,各種框架讓人眼花繚亂。究竟孰優(yōu)孰劣,如今的發(fā)展趨勢是怎樣的,用人單位又需要怎樣的人才?本文站在一個(gè)中立者的角度,客觀分析了當(dāng)前這場框架的游戲中,JavaScript 的流行趨勢。 Javascript 的生態(tài)環(huán)境讓我...
摘要:是目前唯一一個(gè)支持同步調(diào)用的跨平臺年度上最多的個(gè)項(xiàng)目前端掘金年接近尾聲,在最近的幾篇文章中,會整理總結(jié)一些年度開源項(xiàng)目。 JS 全棧教程 - 前端 - 掘金本課程是基于阮一峰的 js 全棧教程的視頻版本,免費(fèi)供大家觀看... 2016 年 10 個(gè)最佳的 CodePen 作品 - 前端 - 掘金說到 CodePen,前端開發(fā)者們肯定不會陌生。如果說 Dribbble 是設(shè)計(jì)師們聚集的圣...
摘要:上周末看這篇文章時(shí),偶有靈光,所以,分享出來給大家一起看看前端面試四月二十家前端面試題分享請各位讀者添加一下作者的微信公眾號,以后有新的文章,將在微信公眾號直接推送給各位,非常感謝。 前端切圖神器 avocode 有了這個(gè)神器,切圖再也腰不酸,腿不疼了。 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果讀完本文還不懂,...
閱讀 2798·2021-11-22 14:45
閱讀 2946·2021-09-10 11:26
閱讀 3272·2021-09-07 10:18
閱讀 2232·2019-08-30 14:08
閱讀 638·2019-08-29 12:22
閱讀 1405·2019-08-26 13:48
閱讀 2548·2019-08-26 10:24
閱讀 1165·2019-08-23 18:35