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