在基於nuxt的移動端頁面中引用mint UI的popup組件之父子組件傳值


  最近在做移動端的wap頁面,考慮到要做SEO,所以選定了nuxt+vue+mint ui。

  有一個需求是這樣的,點擊頭部菜單欄,出現一個氣泡,點擊返回首頁。

  

由於一些頁面沒有統一引用mint的mt-header組件,所以決定把這個氣泡(popup)封裝為一個組件,在需要的地方調用。點擊header右側的三個點時,控制popup的顯示和隱藏,因此涉及到了父子組件傳值。代碼如下:
 1 <template>
 2     <div>
 3        <mt-header :title="title">
 4             <a @click="$router.go(-1)" slot="left">
 5                 <mt-button icon="back" v-if="headerType == 'back'">返回</mt-button>
 6                 <mt-button @click="handleClose" v-if="headerType == 'close'">關閉</mt-button>
 7             </a>
 8             <mt-button icon="more" slot="right" v-if="headerType == 'more'"  @click="TogglePopupMore"></mt-button>
 9             <mt-button  slot="right" v-if="headerType == 'mRight'">{{stringRight}}</mt-button>
10             <mt-button slot="right" v-if="headerType == 'setting'">
11                 <div>
12                     <i class="icon iconfont icon-31shezhi"></i>
13                 </div>
14             </mt-button>
15         </mt-header>
16         <v-indexPopup v-model="tab"></v-indexPopup>
17     </div>
18 </template>

 第8行TogglePopupMore這個方法會切換popupMoreTrigger的true和false,進而控制popup的顯示和隱藏,第16行就是引入的氣泡這個組件。組件代碼如下:

<template>
  <div class="main">
    <mt-popup class="show-more-popup" v-model="popupMoreTrigger" popup-transition="popup-fade">
      <div class="show-more-popup-item">
        <nuxt-link to="/">首頁</nuxt-link>
      </div>
    </mt-popup>
  </div>
</template>

關於popup的官方文檔截圖如下:

划重點:popupVisible是通過v-model綁定的,這個神操作直接導致了后面的一系列事故,當然也促成了這篇博客的誕生...插一句,新版API已經不再使用這種方式了,而是通過:visible.sync="popupVisible"綁定,也許作者大大也意識到這么做的不妥了吧。新版中文文檔地址:http://mint-ui.github.io/docs/#/zh-cn2。於是乎問題如約而至:

這里在beforeMount這個鈎子函數中分別打印了popupMoreTrigger和popupMoreTrigger2,但是發現這兩個值並不像等。我又監聽popupMoreTrigger的值,發現點擊菜單欄的右側按鈕時,popupMoreTrigger的值已經改變了,並且也正確地傳到了子組件中,只是popupMoreTrigger2沒有跟着一起變,所以氣泡不能顯示出來。既然在data中重新聲明不可以,我就放在計算屬性中在試試唄~

 然而...報錯提示:Property or method "showPopup" is not defined on the instance but referenced during render.直接在props中使用也是不可以的,這是由vue自身的單向數據流產生的:(防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解)

報錯內容為:Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "popupMoreTrigger"。

  導致這些問題的根源就在於popup的顯隱性字段是通過v-model綁定的,這本身是雙向綁定的,而vue.js的機制又不允許這么做。用啥不好非用個v-model,看在新版api已經改了的份上,我就原諒你吧。后來朋友說可以嘗試使用對象來傳值,這個可以用雙向綁定。一通修改之后代碼如下:

父組件data部分:

data () { return { tab:{ popupMoreTrigger: false, } }; },

父組件methods部分:

methods: { TogglePopupMore(){ this.tab.popupMoreTrigger = !this.tab.popupMoreTrigger; }, }

父組件調用子組件部分:(此時傳過去的tab是一個對象哦)

<v-indexPopup v-model="tab"></v-indexPopup>

子組件代碼如下:

<template>
  <div class="main">
    <mt-popup class="show-more-popup" v-model="value.popupMoreTrigger" popup-transition="popup-fade">
      <div class="show-more-popup-item">
        <nuxt-link to="/">首頁</nuxt-link>
      </div>
    </mt-popup>
  </div>
</template>

<script type='text/ecmascript-6'> import { Loadmore } from 'mint-ui'; export default { data () { return { }; }, props: { value: { type: Object, default: {} } }, } </script>
<style scoped> .show-more-popup{ width: auto; border-radius: 6px; padding: 5px 15px; top: 50px; bottom: auto; right: 0; left: auto; text-align: center; -webkit-transform: none; transform: none;
  } .show-more-popup:before{ display: inline-block; width: 0; height: 0; border: solid transparent; border-width: 10px; border-bottom-color: #fff; content: ""; position: absolute; top: -20px; right: 10px;
  } .show-more-popup-item{ color: #333;
  }
</style>

主要區別就是把布爾值的popupMoreTrigger改成了對象。

  四五月份的大事是跳槽換了工作,這是一個新的開始。

  六七月份的大事是開始維護博客,這是一個好的開始。anyway,加油干吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM