---
tags: Vue 直播班 - 2021 夏季班
---
# 7/5 線上 Slack 助教
## 今日助教輪班時間
hsin-yu:7/5 (一)
回覆時間:下午 1:00 -下午 4:00
## 發問規範
老師助教同學們好,**這是我的 Codepen**,我**原本預期**「JS 第 8 行會出現數字 8」,**但卻出現**「預期外的結果是 0」,想問下問題出在哪裡?
## 注意
1. 請各位先到 Slack 上將問題放在助教服務內的 thread,如圖

2. 遵循以上的發問規範以便助教查看問題,不可直接貼上網址而沒有說明文字或者只提供截圖
3. 助教會依照 Slack 上的順序回覆問題
4. 以下問題區塊只能由助教自行增加
5. 助教會將回覆寫在下方問題區塊
## 問題
1. Tori:
助教你好,這是我的
[Github](https://github.com/aer456987/natural/blob/main/src/components/modal/DashboarCouponModal.vue)
[github pages](https://aer456987.github.io/natural/dist/#/login)
我想在後台的 商品modal 和 優惠券modal 中使用 VeeValidate 套件進行驗證,助教可以看 DashboarOrderModal.vue 那份的程式碼(33行開始)。
刷新頁面後,點擊新增 modal,套件可以正常驗證,接著點開修改 modal 也可以正常驗證。
**但如果這時候再點擊一次新增 modal 就會出現跳錯誤(附圖),上一筆資料在畫面上不會被清除(但用vue看會發現資料確實有被清除)**
想問助教這種狀況是哪種問題導致的?
> 助教回覆:
> 這裏因使用 VeeValidate 套件驗證 from 裡面的值不能沒有屬性,不然會無法辨識
以優惠券頁面為例,原本在 DashboardCoupon.vue 打開 modal 時會將
updataCouponData 重新設定([這段](https://github.com/aer456987/natural/blob/main/src/views/admin/DashboardCoupon.vue#L162-L165))
需將所有的屬性都補上才能正確執行驗證
可以在 DashboarCouponModal.vue 打開 modal 的部分將 tempCouponData 設定為
```{
due_date: Math.floor(Date.now() / 1000),
is_enabled: 0,
code: ‘’,
id: ‘’,
num: 0,
percent: 0,
title: ‘’,
};
```
>(這部分也可以參考 [Vue3 直播班 vee-validate 4 問題紀錄](https://hackmd.io/fKY90dVxQtm4qJKfBchj3Q),同學的問題和第二個問題類似)
>
>這樣修改後不會跳出錯誤,不過會出現:打開 modal 因改變 tempCouponData 中的值而觸發表單驗證的情況,
>目前測試可以在設定 tempCouponData 值之前使用 veevalidate 的內建函式 resetForm() 將表單在不觸發驗證的情況下清空值,打開 modal 新增優惠券時就不會在一開始就觸發驗證
---
2. Stacey Huang:
hsin yu 助教你好
關於 Ray 助教提供的第7周 [作業範例](https://github.com/hexschool/live-vue3-dashboard) ,有些問題想要提問。不好意思,問題有點多。
(1)在couponModal.vue中的line84行,Ray助教有註解將時間格式改為 YYYY-MM-DD,想請問這個時間格式是由後端所決定嗎? 一開始沒有注意到要用YYYY-MM-DD,改用其他方式將timestamp轉 YYYY/MM/DD 結果出現錯誤。
>助教回覆:
>這裏因 input type="date" 的 value 主要是接受 yyyy-mm-dd 的日期格式(根據 ISO 8601 國際標準化組織的日期和時間表示方法)
可以參考[<input type=“date”> - HTML: HyperText Markup Language | MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
其中 Value 的部分有提到:
>```
>The displayed date format will differ from the actual value — the displayed date is formatted *based on the locale of the user’s browser*, but the parsed value is always formatted yyyy-mm-dd.
>```
(2)Article.vue利用props將資料傳到 ArticleModal, tempArticle已經包含了tag及isPublic(line124~128),所以不是很清楚為什麼在ArticleModal中,在line 197中, 將this.article淺拷貝並賦於到this. tempArticle,為甚麼還需要tag及isPublic(line 198及 line 199)呢?
>助教回覆:
>這個問題最主要是發生在新增後再去編輯
當使用者如果新增時沒有新增標籤就儲存的話,此時陣列會是空的,而這時候再點一次沒有儲存陣列的資料編輯,這時候跟後端請求的資料就不會帶有 tag 屬性,因此這邊在 Article.vue 淺拷貝下去 this.tempArticle = { ...item }; 如果沒有針對 watch 做一些處理的話是會出現錯誤的
(3)在Article.vue中為什麼在line91 和line111行中,為甚麼會特別使用catch呢?
已經知道當請求失敗時,axios會使用catch來處理,但因為在其他請求中,大多沒有用到catch,幾乎都使用if(res.data.success)與else來做判斷,因此想請問一下。
以上問題,再麻煩助教了,謝謝!
>會建議串接 API 都要接上 catch,為了接收錯誤訊息,而這邊主要是因為每一個後端開 API 方式不同,所以這隻 API 主要是用 if...else 去錯判斷,但是如果出現一些特別的錯誤的時候,例如 5xx 就不會進入 then,因為是屬於 catch
可以測試以下例子,例如:
>```
>const api = >${process.env.VUE_APP_API}/api/${process.env.VUE_APP_PATH}/admin/article/${id};
>```
>改成
>```
>const api = >${process.env.VUE_APP_API}123/api/${process.env.VUE_APP_PATH}/admin/>article/${id};
>```
>這時候如果沒有 catch 是不會出現錯誤訊息的~
---
3. Jordan_Tseng :
老師、助教、同學好,**
這是我的,我想問幾個問題:
(1) 在 [新建職位表單](https://github.com/Jordan-TTC-Design/vue-2021-finalwork/blob/master/src/views/front/AddJob.vue) 中遇到一個問題是,兩個單選選項一樣,就會打架衝突,如果選其他事可以運作。
>這部分想確認同學指的「兩個單選選項一樣會衝突」的具體情況是什麼呢~(是指單選的選項會需要重複,例如:選項一、選項一、選項二 嗎~)
>
>更新:這裏可以調整 input 的 name 屬性,若有五個單選 (radio) 都屬於「工作經驗」選項,這五個選項的 name 必須為相同值,「學歷要求」的五個選項的 name 值也需相同
>可以參考 [<input type=“radio”> - HTML(超文本标记语言) | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/radio),其中有提到
>```
>一個單選按鈕組由具有相同 name 屬性的單選按鈕組成。一個單選按鈕組被建立,選擇那組的任何單選按鈕將自動取消同組當前選擇的任何按鈕
>```
(2)想問在後台產品頁,因為我需要很多產品,我是想取得全部產品列表,全部產品會回傳物件,我找了一個物件轉陣列方式,目前看是可以運作,不知道對不對:this.products = Object.keys(res.data.products).map((_) => res.data.products[_]);
>從 vue 開發者工具查看 products 資料有正確呈現每個產品物件,轉換型別上沒問題哩
(3)我想刪除 [訂單](https://github.com/Jordan-TTC-Design/vue-2021-finalwork/blob/master/src/views/admin/DashBoardOrdersList.vue) 、產品時,當下陣列會再次塞入回傳的東西,我覺得是我在分類時出問題可能是.forEach,但是像我訂單陣列getOrder中也有塞入歸零,但沒效果,不知道怎麼做比較好?
this.addCompanyOrders = [];this.addjobOrders = [];
助教如果要測刪除,可以先從訂單列表按創建,訂單目前設固定的
>這部分也需要請同學多描述一點,讓我們暸解實際上要的需求是什麼,若是以功能來看是正常的
>更新:
>因刪除產品之後會執行取得全部產品,然後透過 map 轉換成新的陣列,接下來會執行 classifyProduct methods 篩選出產品分類,而這邊並不是重新賦予的方式,而是採用 push,因此篩選完之後就又新增了,因此可以改為每次跑這個 forEach 之前都應該要將相關 companiesList 與 jobsList 清空一次,這樣才不會又發生同樣狀況
(4)最後想問說,如果兩個類似modal,像是後台訂單、產品頁面我有企業和職位,我用v-if讓他暫時不存在,因為modal中有些資料還沒生成,避免出現錯誤。但是就變成要多按一次,不知道助教有沒有比較好建議?
> 這裏提供大概方向讓同學思考調整看看:
因同學有提到「如果兩個類似modal,像是後台訂單、產品頁面我有企業和職位」,所以會建議 props 的時候可以傳入一個判斷式到 Modal 在裡面辨別哪些是後台訂單、產品頁面專用的 Modal,而不是直接補在外層 v-if,這樣會出現目前的問題(必須點兩次),因為元件要重新經歷渲染,正確應一開始就一先讓元件渲染,接下來透過傳入的 props 來去 v-if 切換元件內部該顯示的
例如:我們可以透過 props 傳入 status : true or false,然後 Modal 裡面就可以去切換要顯示的 HTML
---
4. Iven :
助教好:
Q1 : 這是我的程式碼,有點不太了解ToastMessages的部分,是怎麼觸發他跳出訊息的,因為我實作時,一開始就算emitter.on有監聽到事件觸發,但是也沒有跳出訊息,後來對照範例程式碼,在toast加上 class= toast show 才順利跳出提示訊息,所以有點不懂,toast是怎麼顯示出來的。
>助教回覆:
>因範例的部分是預設 toast 是顯示的狀態(因此會在 class 加上 show,.show 是 bootstrap 的樣式,
>```
>.toast:not(.showing):not(.show) {
> opacity: 0;
>}
>```
>如果沒有同時出現 .toast 和 .show,透明度就會是 0)
>顯示 toast 部分改為:若 messages 有內容就會顯示 toast 的 html 結構 [參考這裡](https://github.com/hexschool/live-vue3-dashboard/blob/main/src/components/ToastMessages.vue#L7)(使用 v-for 渲染 messages 的部分,當 messages 是空的就不會出現了)
>Messages 的值也是另外寫方法:
在 push-message 事件發生時將提示訊息推到 ToastMessages.vue 的 messages 中
( [參考 PushMessageStatus.js](https://github.com/hexschool/live-vue3-dashboard/blob/main/src/methods/pushMessageState.js)
Q2 : 為什麼PushMessageStatus裡面的export default function不用加上名稱?
>助教回覆:
>可以參考這裡 [export - JavaScript | MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/export#%E4%BD%BF%E7%94%A8%E8%AA%AA%E6%98%8E) export 有兩種使用方式,一種是需要命名的,另一種就是 export default … ,若使用 export default 的方式可以不用名稱~
Q3 :第11行的三元運算子 const message = typeof res.data.message === 'string' ? [res.data.message] : res.data.message
是說 如果回傳的 res.data.message 型別是字串的話 就包成物件,如果不是字串的話,就保持原本的型別嗎? 我覺得我解釋得有點怪怪的,想請問助教有更好理解的解釋嗎?
>助教回覆:
>同學的解釋是沒錯的,這裏因回傳的 response.data.message 會有字串或陣列的格式,因此透過判斷式將格式一律統一為陣列格式哩
---
5. Tori:
[Github](https://github.com/aer456987/natural/blob/main/src/components/ProductCard.vue)
[github pages](http://localhost:8080/natural/dist/#/products)
(問題一) 我正在製作加入最愛的功能,產品 id 可以在存入 localStorage 時同時讀取 localStorage 的資料(第 139 行)。
但如果這時重新刷新頁面時就會報錯(附圖),第 77 行的 this.$refs.favorit.getFavorits() 拿掉就不會報錯。
但是這樣會導致每次刷新頁面時,myFavorits 的資料同時變成空陣列,請問助教這個問題我該怎麼處理?
>如果是在第 77 行 使用 ref 選取 DOM 元素,因無法確定載入 data() 時整個 DOM 是否已載入完成,當找不到 this.$refs.favorit 就會出錯
可以直接將 this.myFavorits 設定
JSON.parse(localStorage.getItem(‘favoritData’)) || [] 取得 localStorage 的資料
(問題二) 關於助教上個問題的解答:目前測試可以在設定 tempCouponData 值之前使用 veevalidate 的內建函式 resetForm() 將表單在不觸發驗證的情況下清空值,打開 modal 新增優惠券時就不會在一開始就觸發驗證
我查過了官方文件,但還是不太懂resetForm() 使用方法,再請助教解惑,謝謝。
>這邊可以參考助教範例中的寫法,用 refs 選取 form 執行 resetForm()
[範例](https://github.com/hexschool/live-vue3-dashboard/blob/17da34a50d11826b7c4689fa6c2f2cf9d7f55cb2/src/views/UserCart.vue#L372)
---
6. moitw
助教好,這是我的 [code](https://github.com/tsuifei/vue-galerie/blob/main/src/components/AdminCouponModal.vue) 和 [page](https://tsuifei.github.io/vue-galerie/dist/#/)
在寫 coupon 的 modal 時,一直無法觸發父層的方法 updateCoupon 出現的錯誤是:Property “updateCoupon” was accessed during render but is not defined on instance
有在父層子層寫了emit 與橋樑,但開啟視窗修改後點確定沒反應,有測試點擊其他方法沒問題,但是就是點擊觸發父層一直沒反應,想麻煩助教幫忙找盲點,應該是emit 的問題自己卻查不出來,另外,在 AdminCouponModal 李的日期也一直無法正確顯示,找不出是哪裡的問題….先謝謝助教~
>Coupons.vue [這邊](https://github.com/tsuifei/vue-galerie/blob/main/src/views/admin/Coupons.vue#L118 )定義的 updateCoupon 函式有多一個字
以及137 行[這裡](https://github.com/tsuifei/vue-galerie/blob/main/src/views/admin/Coupons.vue#L137)應該是 getCoupons
調整後應該就可以正確執行,可以調整看看~
>時間的部分可以參考上方第 2 題同學的提問(第 1 小題),因 input type=“date” 的 value 主要是接受 yyyy-mm-dd 的日期格式,這邊看 AdminCouponModal.vue [這裡](https://github.com/tsuifei/vue-galerie/blob/main/src/components/AdminCouponModal.vue#L133-L135) 有將 this.temp_due_date 轉為 yyyy-mm-dd 的日期格式,因此 modal 中 input type=“date” 應該綁定 temp_due_date,才會正確顯示日期(不需轉為 number 型別)
---
7. 蔡皓全
助教好:
1.我想請問要客製化bootstrap中的button樣式的話,我看了一下文件很像是要先定義一個class名稱,然後在裡面寫@include button-variant(代入的參數),但我看不懂參數的位置分別代表怎樣的樣式,假設用`$primary`的背景色 文字是`$white`,hover後變`$success` 背景色文字是`$success`這樣該怎麼寫
> 因 bootstrap 的 hover 顏色都是根據背景色調深或調淺一定比例
如果是想從 A 背景色的 button,hover 時改為完全不同的 B 背景色,可能需要另外客製化 btn 的樣式,不使用 btn-primary 的 class,客製化 .btn-custom,hover 的樣式就可以另外設定,例如:
>```
>.btn-custom {
> background-color: $primary;
> &:hover {
> background-color: $success;
> }
>}
>```
2.我想問關於使用vue-typed-js 我照著這份 [文件](https://github.com/Orlandster/vue-typed-js) 使用,但加上Index.vue檔中的第7和第9行就會失敗 附上 [github](https://github.com/DavidTsai-whole/vuecli3) 謝謝
>這裡查看 vue-typed-js GitHub 是支援 vue2 的,目前沒有找到是否有支援 vue3 的說明,同學可以先看看是否有支援 Vue3 的替代的套件,或其他方式達成 typing 的動畫效果哩
>
>更新:這裏提供葉子助教的[文章](https://tzuhui.github.io/2019/11/13/CSS/css-typewriter/),也可以參考這裡做法呈現打字機效果唷
---
8. Tori
助教你好,一樣是 VeeValidate 的問題
[Github](https://github.com/aer456987/natural/blob/main/src/views/admin/DashboardCoupon.vue)
[github pages](https://aer456987.github.io/natural/dist/#/admin/coupon)
依助教的解答加入了 resetForm() ( 第 163 行 ),初次點開新增 modal 後會出現 VeeValidate 的驗證訊息,關掉再點一次,驗證訊息就會消失,不太確定自己指令寫的位置是不是對的,再請助教幫忙看看。
>這裡原本提供的寫法是把這段 [這段](https://github.com/aer456987/natural/blob/main/src/views/admin/DashboardCoupon.vue#L163-L170) 放在 DashboarCouponModal.vue 的 openCouponModal() 函式中,同學目前的寫法也是可以的,但需注意初次打開新增 modal 時,因 DashboarCouponModal.vue 這邊 tempCouponData
原本的值是空物件 {},當資料賦予 tempCouponData 值有變動也會觸發驗證,因此可以在[這邊](https://github.com/aer456987/natural/blob/main/src/components/modal/DashboarCouponModal.vue#L189)也設定每個屬性的初始值,初次打開就不會再觸發驗證了
---
9. Jordan_Tseng
助教好,我原本那篇留言有在留影片。這是我的 [頁面](https://jordan-ttc-design.github.io/vue-2021-finalwork/dist/#/products-list) 、。另外想問關於position-sticky的問題,我明明有設定但是他就是出不來,滿奇怪。header時好時壞。我查好像是說外層不能有overflow?外層也沒有這個設定
>這邊用同學提供的頁面操作,滾動頁面時上方導覽列都有固定在視窗上方,效果有正確呈現(不確定同學是否已調整過)
另外同學提供影片的問題有回覆在原本第 3 題問答中,可以調整看看~
>更新:
>因 position: sticky 是讓元素相對於他的外層固定,例如:header 是相對外層 `#app`,因此會固定在 `#app` 最上方
右側職位顯示框 jobSelectBox 和外層 .col-md-6 高度是相同的,因此會沒有固定的效果,需要將 jobSelectBox 移到外層,讓他相對於 `#app` 定位,滾動視窗才會有固定的效果
---
(這邊只能由助教編輯,問題請到 thread 上詢問)