--- tags: Vue 直播班 - 2021 夏季班 --- # 6/23 線上 Slack 助教 ## 今日助教輪班時間 佩涵:6/23 (三) 回覆時間:下午 1:00 -下午 5:00 ## 發問規範 老師助教同學們好,**這是我的 Codepen**,我**原本預期**「JS 第 8 行會出現數字 8」,**但卻出現**「預期外的結果是 0」,想問下問題出在哪裡? ## 注意 1. 請各位先到 Slack 上將問題放在助教服務內的 thread,如圖  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 會直接跳出警告說不能這麼做(下圖) > >  > > 所以才需要透過 ++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 上詢問喔)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up