---
# System prepended metadata

title: 6/23 線上 Slack 助教
tags: [Vue 直播班 - 2021 夏季班]

---

---
tags: Vue 直播班 - 2021 夏季班
---

# 6/23 線上 Slack 助教


## 今日助教輪班時間

佩涵：6/23 (三) 
回覆時間：下午 1:00 -下午 5:00

## 發問規範

老師助教同學們好，**這是我的 Codepen**，我**原本預期**「JS 第 8 行會出現數字 8」，**但卻出現**「預期外的結果是 0」，想問下問題出在哪裡？

## 注意

1. 請各位先到 Slack 上將問題放在助教服務內的 thread，如圖
 ![](https://i.imgur.com/nHE3sOx.png)
2. 遵循以上的發問規範以便助教查看問題，不可直接貼上網址而沒有說明文字或者只提供截圖
3. 助教會依照 Slack 上的順序回覆問題
4. 以下問題區塊只能由助教自行增加
5. 助教會將回覆寫在下方問題區塊

## 問題

1. **Iven：**
助教好：我使用props把外層的資料傳進內層的productModal，props:['product']
我在內層productModal渲染的資料是，product.title等等的，我記得內層元件使用props，再渲染資料時，是使用props的名稱，但是我在內層元件使用props名稱渲染資料時，編輯modal打開卻沒有任何資料，反而是使用了watch之後才有原本的資料被寫進到modal，想請問助教是我哪裡寫錯沒有發現嗎？為什麼，使用props名稱渲染資料卻出現錯誤，而使用watch之後才看到原本的資料被傳進了內層modal的原因是什麼？這裡是我的[程式碼](https://github.com/Iven10252158/final_project) （檔案是admin>admin_products跟productModal)

> 助教回答：
> 如果同學是把 productModal 裡的 this.tempProduct = this.product 這行放在 mounted() 的話，就只會得到初始狀態的 product 資料（空物件）哦，所以打開 Modal 才會是空的
因此才需要透過 watch 監聽的方式，每當 product 的值有更動時，就會執行 this.tempProduct = this.product 這個動作，此時的 tempProduct 就會得到新的值了～
> 
> 另外，同學的登入驗證有一些問題，目前你有在密碼限制說一定要八碼，但這邊測試若輸入不到八碼還是會成功發送請求
不過「六角學院 Vue 課程練習 API 申請」是沒有規定密碼一定要超過幾字元的哦，所以這部分也需考慮到有些用戶當初設定的密碼是沒有到八碼的XDD 因此建議可以把這個驗證拿掉哩～～

<br>

助教好：
對  我是直接把product 綁在 v-model 上
```
<input type="text" id="title" class='form-control' v-model='product.title'>
```
就是這種寫法，為什麼這樣會產生錯誤呢？

> 助教回覆：
> 這是因為 props 具有<font color="red">**單向數據流**</font>的特性，不能直接修改到 props 的資料
> 若直接用 product 名稱去綁 v-model 的話，就會違反單向數據流規定，ESLint 會直接跳出警告說不能這麼做（下圖）
> 
> ![](https://i.imgur.com/eCvvBaQ.png)
> 
> 所以才需要透過 ++watch 監聽++ 的方式，當 product 的值有更動時（更動時機：重開編輯 Modal，product 會被重新賦值。[程式碼](https://github.com/Iven10252158/final_project/blob/main/src/views/admin/Admin_products.vue#L93)），就會執行 `this.tempProduct = this.product` 這個動作，讓子元件內的 data （tempProduct）去接替傳進來的 data（product），再用接替的那個 data 去修改值才不會出現錯誤哦～

<br>

如果不使用eslint的話，是不會跳錯的，但其實也不建議這樣直接修改props傳來的值，對嗎？

> 助教回覆：
> 對唷～～

---

2. **Sec：**
助教好, 想请问couponModal.vue内的 watch下coupon的console.log不会触发是什么原因呢
https://github.com/SecYJ/Vue_live_week_7 

> 助教回覆：
> 因為 props 有內層物件，所以需要使用「深層監聽」的方式，才可以監聽到 coupon 物件內層的改變
因此程式碼可改成如下：
```javascript
watch: {
　coupon: {
　　handler() {
　　　console.log('出現了！');
　　　this.couponDetails = this.coupon.temp;
　　},
　　deep: true,
　},
},
```
> 這邊也另外附上 [Watch 監聽](https://courses.hexschool.com/courses/vue-2021/lectures/31863086) 影音章節讓同學複習哩 :D
> 
> 另外同學的 check 驗證有一些問題，會出現無法登入的情況，這部分可以參考範例程式碼來做調整唷

---

3. **moitw：**
助教好，我是在後台的 Modal 出現問題
後台產品列表檔案為 /src/views/admin/Products.vue
後台 產品列表Modal 元件為 /src/components/AdminProductModal.vue
在點擊 後台產品列表 上的編輯按鈕時，會出現
    ```
    TypeError: this.$refs.adminProductModal.openModal is not a function
    ```
    我有參考 範例的分支 Base 但這支分支昨天好像就刪掉了，但我的程式碼是參考這支分支的。
    當我點擊 編輯按鈕時，會先去觸發 openModal 這支，因為是編輯(edit)所以會跑進 else ，接著以 this.$refs.adminProductModal.openModal() 打開Modal，對於為什麼是.openModal() 而不是元件裡的 .showModal() 感到疑惑，也試著改成 
    ```
    this.$refs.adminProductModal.showModal()
    ```
    但仍出現錯誤。
    麻煩助教提示出現問題的原因，謝謝～
    [網頁](https://tsuifei.github.io/vue-galerie/dist/#/) 
    [程式碼](https://github.com/tsuifei/vue-galerie)

> 助教回覆：
> 根據同學的程式碼，確實是要改成
> ```
> this.$refs.adminProductModal.showModal()
> ```
> 才是正確的唷！因為同學的 AdminProductModal.vue 裡頭所寫的方法名稱是 showModal() 而非 openModal()
> 
> 另外助教這邊測試改成 `this.$refs.adminProductModal.showModal()`，是可以正確開啟 Modal 的，同學可以再測試看看喔～

---

4. **金金：**
    助教好，有三個問題想詢問><

    1. 元件的樣式問題 (此頁程式碼第16行)
    我有一個frontnav 元件，分別在IndexFront.vue跟Dashboard.vue中都有引用，但我希望在IndexFront.vue頁面時，frontnav 元件的背景色要換成黑色。可是我設定了scoped卻還是無法修改，如果不設定scoped又會將原本元件樣式都覆蓋掉，程式碼在此 https://reurl.cc/pgr4nb
    2. 註冊全域物件的問題
    我在main.js的第45行與72行引入並全域註冊了Loading元件 https://reurl.cc/3a7pLM ，接著想到productsList.vue的頁面第3行使用這個元件 https://reurl.cc/MA4LZL ，但卻無法使用，請問是我元件引用的方式錯誤嗎><
    3. Bootstrap Navbar 的JS引用問題
    我在[此頁](https://reurl.cc/MA4LZL) 引用的BS的navbar，但手機板時navbar toggle無法點擊，有看到老師說要另外引入BS的JS，但具體該怎麼做不太清楚>< 看過之前的Modal 引入JS方式，但Modal好像又跟Navbar不太一樣，再麻煩助教協助了!!!感謝

> 助教回覆：
> 1. 這邊看同學的 Dashboard.vue 是載入 backNav 元件 ><
> 另外助教這邊測試分別在 frontNav、backNav 元件使用 scoped 是可以成功覆蓋樣式的唷
> 
> 2. main.js 的 `app.mount('#app')` 這行一定要擺在最後面執行喔～
> 另外 productsList.vue 的 `components: { loading },` 也需移除
> 3. 需要再到 main.js 導入 boostrap 哦
```javascript
import bootstrap;
```
> 補上後，可能他會提示你要安裝 popper.js，這是因為有些 Bootstrap 元件會使用到 Popper 插件，比如：[Dropdowns](https://bootstrap5.hexschool.com/docs/5.0/components/dropdowns/)、[Popovers](https://bootstrap5.hexschool.com/docs/5.0/components/popovers/) 等，所以需要再自行安裝 popper.js（[文件參考](https://bootstrap5.hexschool.com/docs/5.0/getting-started/webpack/#importing-javascript)）
> 安裝指令如下：
```npm
npm install @popperjs/core
```

> 安裝完後，這邊測試時發現 Navbar 的漢堡按鈕、dropdown 還是不能動
這是因為同學安裝的 Bootstrap 版本是最新版 5（[package.json](https://github.com/vezona/Sweet_Home_Vue3_Project/blob/main/package.json#L20)），但 Navbar 卻參雜了「非」 Bootstrap 5 定義的屬性名稱：data-toggle、data-target，這兩個屬性在 BS5 已經改成 data-bs-toggle、data-bs-target 了，把 bs 字眼加上後就可以正常運作了～
> 另外也提醒一下，mr-sm-2 在 BS5 要改成 me-sm-2 才能正確套用到樣式，這裡也附上 [相關文件](https://getbootstrap.com/docs/5.0/utilities/spacing/) 給你觀看
  
<br>

想再請教的是：
1. 我的前後台都有Dashboard.vue~~~ 主要的問題是在front/Dashboard.vue裡面引用的 frontNav，想問助教看的是這一支嗎><
2. 抱歉可能我問題沒表達清楚，想問的是我在front/Dashboard 跟front/IndexFront.vue裡面都引用了 frontNav元件，但希望這兩個頁面的 frontNav樣式不一樣，請問這個有辦法調整嗎~
一樣再附上頁面程式碼，再麻煩助教了 https://reurl.cc/pgr4nb <=就是此頁的style加上scoped，背景改黑色但還是吃不到

> 助教回覆：
> 可以在 class 前面加上 `::v-deep` or `/deep/` 就可以在該頁面成功覆蓋子元件的樣式，也不會讓影響到其他頁面：）
> 附上 [相關討論文](https://stackoverflow.com/questions/56697673/vue-how-to-change-the-style-of-scoped-child-components) 及 [文章](https://medium.com/@debbyji/deep-%E6%98%AF%E4%BB%80%E9%BA%BC-%E8%81%8A%E8%81%8A-vue-%E8%A3%A1%E7%9A%84-scoped-css-d1877f902845) 給你參考～
> <br>
> 
> 還有另外一個做法是運用 props 狀態來判斷當前頁面是否是某頁面，如果不是某頁面則就使用別的顏色取代（這邊是使用 :style 的方式來覆蓋原樣式～）
> 這邊附上小範例給你參考～
> 
> Indexfront.vue
> ```html
> <frontNav :atIndexfront="true"></frontNav>
> ```
> Dashboard.vue
> ```html
> <frontNav :atIndexfront="false"></frontNav>
> ```
> <br>
> 
> frontNav.vue
> ```html
> <template>
>   <nav
>    class="navbar navbar-expand-md navbar-light bg-light px-3"
>    :style="{ 'background': atIndexfront ? 'black !important' : ''}"
>   >
>   ...
> </template>
> 
> <script>
> export default {
>   props: ['atIndexfront']
> }
> </script>
> ```
 
---

（這邊只能由助教編輯，問題請到 thread 上詢問喔）