欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue在頁面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單

 更新時(shí)間:2018年05月04日 09:45:19   作者:榕樹島  
這篇文章主要介紹了Vue在頁面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單,實(shí)現(xiàn)思路大概是通過props將showCancel這個(gè)Boolean值傳遞到子組件,對父子組件分別綁定事件,來控制這個(gè)系統(tǒng)菜單的顯示狀態(tài)。需要的朋友可以參考下

這是個(gè)大多數(shù)網(wǎng)站很常見的功能,點(diǎn)擊頁面右上角頭像顯示一個(gè)懸浮菜單,點(diǎn)擊頁面其他位置或再次點(diǎn)擊頭像則菜單隱藏。

作為一個(gè)jQuery前端攻城獅實(shí)現(xiàn)這個(gè)功能可以說是很easy了,但是對只剛粗看了一遍vue文檔的菜鳥來說,坑還是要親自踩過才算圓滿。

知識(shí)點(diǎn)

  • 組件及組件間通信
  • 計(jì)算屬性

正文

1. 父組件

這里暫時(shí)只涉及系統(tǒng)菜單這一個(gè)功能,因此路由暫未涉及。

基本思路是:通過props將showCancel這個(gè)Boolean值傳遞到子組件,對父子組件分別綁定事件,來控制這個(gè)系統(tǒng)菜單的顯示狀態(tài)。其中在父組件的綁定click事件中,將傳入子組件的showCancel值重置。

這里就涉及第一個(gè)小知識(shí)點(diǎn)——子組件調(diào)用:

首先寫好等待被子組件渲染的自定義元素:

<t-header :showCancel=showCancel></t-header>

接著import寫好的子組件:

import THeader from "./components/t-header/t-header";

然后在組件中注冊子組件:

components: {
 THeader
}

到這里,新入坑的同學(xué)可能會(huì)比較疑惑這幾行代碼是怎樣把子組件對應(yīng)到<t-header>標(biāo)簽的,官方文檔是這樣說的:

當(dāng)注冊組件 (或者 prop) 時(shí),可以使用 kebab-case (短橫線分隔命名)、camelCase (駝峰式命名) 或 PascalCase (單詞首字母大寫命名);

在 HTML 模板中,請使用 kebab-case;

我的理解是(舉例),當(dāng)自定義元素為<t-header>時(shí),注冊組件名可以有三種寫法:t-header、tHeader和THeader,在這種情況下注冊的組件會(huì)自動(dòng)識(shí)別并渲染到<t-header>。

需要注意的是,以上使用的是HTML 模板,是在單文件組件里用<template><template/>指定的模板;另外存在一種字符串模板,是用在組件選項(xiàng)里用template: "" 指定的模板。當(dāng)使用字符串模板時(shí),自定義標(biāo)簽可以用三種寫法,具體情況請移步官方文檔 組件命名約定。

這樣父組件的雛形就誕生了:

<template>
 <div id="app" @click="hideCancel">
 <t-header :showCancel=showCancel></t-header>
 <!-- <router-view/> -->
 </div>
</template>
<script>
 import THeader from "./components/t-header/t-header";
 export default {
 name: "app",
 components: {
  THeader
 },
 data() {
  return {
  showCancel: false
  };
 },
 methods: {
  hideCancel() {
  this.showCancel = false;
  }
 }
 };
</script>

2. 子組件

子組件中.cancel為打開系統(tǒng)菜單的按鈕,.cancel-div為系統(tǒng)菜單,最開始是這個(gè)樣子:

<template>
 <div class="header-wrapper">
 /*這里是logo和title*/
 ...
 /*這里是用戶名和按鈕*/
 <div class="info-wrapper">
  <span class="username">你好,管理員!</span>
  <span class="cancel" @click.stop="switchCancelBoard">
  <div class="cancel-div" v-show="showCancel">
   <ul>
   <li @click.stop="doSomething" title="用戶設(shè)置">設(shè)置 </li>
   <li @click.stop="doSomething" title="退出登錄">退出 </li>
   </ul>
  </div>
  </span>
 </div>
 </div>
</template>

按照踩坑之前的思路,在子組件接到showCancel值后用v-show控制顯示隱藏,那么在父子組件的綁定click事件中只需要根據(jù)情況更改showCancel值就可以了,只要注意對系統(tǒng)菜單內(nèi)幾個(gè)選項(xiàng)的綁定事件不要觸發(fā)父子組件上的綁定事件——總不能一點(diǎn)菜單它就沒了,所以在綁定事件中用到了.stop,即
@click.stop="doSomething"

于是萬事大吉,也就是像這樣:

<script>
 export default {
 props: {
  showCancel: {
  type: Boolean
  }
 },
 methods: {
  doSomething() {},
  switchCancelBoard() {
  this.showCancel = !this.showCancel;
  }
 },
 computed: {
  ifShowCancel() {
  return this.showCancel;
  }
 }
 };
</script>

然而第一波踩坑之后一起表明顯然我還是太年輕。下面是一些不好的示范:

prop來的showCancel值的確可以用,點(diǎn)擊子組件按鈕的時(shí)候,

this.showCancel=!this.showCancel

實(shí)現(xiàn)了菜單的顯示/隱藏,但是一打開控制臺(tái),每次點(diǎn)擊貢獻(xiàn)了一條報(bào)錯(cuò):

vue.esm.js?efeb:578 [Vue warn]: 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值,因?yàn)楦附M件一旦re-render,這個(gè)值就會(huì)被覆蓋;

另外,盡管在這個(gè)按鈕上實(shí)現(xiàn)了顯示狀態(tài)的切換,但是點(diǎn)擊其他區(qū)域的時(shí)候,并不會(huì)隱藏它,原因是:子組件prop值的變化并沒有影響到父組件,因此showCancel的值一直保持初始值沒有變化,而只有在這個(gè)值被更新時(shí)才會(huì)觸發(fā)子組件中相關(guān)值的更新。

——好吧,那么老老實(shí)實(shí)的用一個(gè)計(jì)算屬性接收showCancel值,這樣實(shí)現(xiàn)點(diǎn)擊子組件控制系統(tǒng)菜單的狀態(tài)切換;

獲得了計(jì)算屬性ifShowCancel,組件相應(yīng)的變成了v-show="ifShowCancel",我試圖在綁定事件里通過this.ifShowCancel=!this.ifShowCancel切換菜單狀態(tài),報(bào)錯(cuò),得到報(bào)錯(cuò)信息:Computed property "ifShowCancel" was assigned to but it has no setter;

明白了,要以直接賦值的形式改變計(jì)算屬性ifShowCancel的值,需要一個(gè)setter函數(shù),但是setter函數(shù)中無法修改prop值,因此在getter中也就無法通過return this.showCancel來更新這個(gè)計(jì)算屬性,所以這個(gè)方法貌似也行不通;

到此為止,好像路都成了堵死狀態(tài):prop值不能改->要用計(jì)算屬性;計(jì)算屬性不能改->需要setter;而寫入了getter、setter,計(jì)算屬性的值依賴于prop值->prop值不能改?!粋€(gè)堪稱完美的閉環(huán)誕生了!

走投無路之際我想起了$emit和$on這一對。

3. 父子互相通信

前邊的prop實(shí)現(xiàn)了從父到子的單向通信,而通過$emit和$on,就可以實(shí)現(xiàn)從子組件到父組件的通信:這不能直接修改父組件的屬性,但卻可以觸發(fā)父組件的指定綁定事件,并將一個(gè)值傳入父組件。

在這一步我摒棄了點(diǎn)擊按鈕時(shí)的去操作子組件內(nèi)屬性的想法,既然計(jì)算屬性ifShowCancel依賴于prop值,那么就在點(diǎn)擊按鈕時(shí),通過$emit觸發(fā)父組件的事件,并將需要修改的屬性值傳入父組件,于是:

/*父組件自定義元素綁定switch-show事件*/
<t-header :showCancel=showCancel @switch-show="switchShow"></t-header>
// 父組件js
methods: {
 //會(huì)被子組件$emit觸發(fā)的方法
 switchShow(val) {
 this.showCancel = val;
 }
}
// 子組件js
methods: {
 //按鈕上的綁定click事件
 switchCancelBoard() {
 this.$emit("switch-show", this.ifShowCancel);
 }
}

這樣處理流程就變成了:點(diǎn)擊按鈕->作為計(jì)算屬性的ifShowCancel值傳入父組件并觸發(fā)父組件事件,對showCancel賦值->父組件屬性更新->觸發(fā)子組件prop更新->觸發(fā)重新compute,更新ifShowCancel值->v-show起作用。
另外在點(diǎn)擊其他區(qū)域時(shí),通過父組件綁定的click事件,就可以重置showCancel值,進(jìn)而隱藏掉出現(xiàn)的系統(tǒng)菜單。

下邊放出這個(gè)功能的完整代碼。

4. 完整代碼

/*父組件*/
<template>
 <div id="app" @click="hideCancel">
 <t-header :showCancel=showCancel @switch-show="switchShow"></t-header>
 <!-- <router-view/> -->
 </div>
</template>
<script>
 import THeader from "./components/t-header/t-header";
 export default {
 name: "app",
 components: {
  THeader
 },
 data() {
  return {
  showCancel: false
  };
 },
 methods: {
  hideCancel() {
  this.showCancel = false;
  },
  switchShow(val) {
  this.showCancel = val;
  }
 }
 };
</script>
<style scope lang="stylus">
</style>
/*子組件*/
<template>
 <div class="header-wrapper">
 <div class="title-wrapper">
  <div class="logo"></div>
  <h2 class="title">Title</h2>
 </div>
 <div class="info-wrapper">
  <span class="username">你好,管理員!</span>
  <span class="cancel" @click.stop="switchCancelBoard">
  <div class="cancel-div" v-show="ifShowCancel">
   <ul>
   <li @click.stop="doSomething" title="用戶設(shè)置">設(shè)置 </li>
   <li @click.stop="doSomething" title="退出登錄">退出 </li>
   </ul>
  </div>
  </span>
 </div>
 </div>
</template>
<script>
 export default {
 props: {
  showCancel: {
  type: Boolean
  }
 },
 methods: {
  doSomething() {},
  switchCancelBoard() {
  // this.ifShowCancel = !this.showCancel;
  this.$emit("switch-show", !this.ifShowCancel);
  }
 },
 computed: {
  ifShowCancel() {
  return this.showCancel;
  }
 }
 };
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
 .header-wrapper
 background: #1C60D1
 color: #fff
 width: 100%
 height: 50px
 line-height: 50px
 position: fixed
 top: 0px
 left: 0px
 font-size: 0
 .title-wrapper
  display: block
  position: relative
  float: left
  height: 50px
  .logo
  display: inline-block
  background-image: url('./logo.png')
  background-size: 30px 30px
  background-repeat: no-repeat
  width: 30px
  height: 30px
  margin-top: 10px
  .title
  display: inline-block
  font-size: 16px
  height: 50px
  line-height: 50px
  margin: 0px auto 0px 16px
  font-weight: normal
  vertical-align: top
 .info-wrapper
  display: block
  position: relative
  float: right
  height: 50px
  width: 160px
  font-size: 0
  .username
  display: inline-block
  height: 50px
  line-height: 50px
  font-size: 14px
  vertical-align: top
  .cancel
  display: inline-block
  vertical-align: middle
  background-image: url('./cancel.png')
  background-size: 32px 32px
  cursor: pointer
  background-repeat: no-repeat
  width: 32px
  height: 32px
  .cancel-div
   position: absolute
   display: block
   width: 60px
   height: 80px
   background: #fff
   z-index: 50
   top: 40px
   right: 16px
   font-size: 14px
   color: #646464
   box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.4)
   ul
   padding-left: 0px
   margin: 0px
   li
    width: 100%
    height: 40px
    line-height: 40px
    text-align: center
    list-style-type: none
    &:hover
    background-color: #eaeaea
</style>

總結(jié)

以上所述是小編給大家介紹的Vue在頁面右上角實(shí)現(xiàn)可懸浮/隱藏的系統(tǒng)菜單,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Vue3啟用gzip壓縮nginx配置詳解

    Vue3啟用gzip壓縮nginx配置詳解

    這篇文章主要為大家介紹了Vue3啟用gzip壓縮時(shí)nginx配置gzip示例詳解詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • vue給數(shù)組中對象排序 sort函數(shù)的用法

    vue給數(shù)組中對象排序 sort函數(shù)的用法

    這篇文章主要介紹了vue給數(shù)組中對象排序 sort函數(shù)的用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue輸入框組件開發(fā)過程詳解

    vue輸入框組件開發(fā)過程詳解

    這篇文章主要為大家詳細(xì)介紹了vue輸入框組件開發(fā)過程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vuex管理dialog、toast等常見全局性組件狀態(tài)時(shí)唯一性的問題解決

    Vuex管理dialog、toast等常見全局性組件狀態(tài)時(shí)唯一性的問題解決

    工作中經(jīng)常會(huì)用到類似于?dialog、toast、popover?等一些狀態(tài)提示組件,這篇文章主要介紹了Vuex管理dialog、toast等常見全局性組件狀態(tài)時(shí)唯一性的問題,需要的朋友可以參考下
    2022-11-11
  • vue-devtools的安裝步驟

    vue-devtools的安裝步驟

    vue-devtools 是一款基于chrome游覽器的插件,用于調(diào)試vue應(yīng)用,這篇文章分步驟給大家介紹了vue-devtools的安裝方法,需要的朋友參考下吧
    2018-04-04
  • vue 兄弟組件的信息傳遞的方法實(shí)例詳解

    vue 兄弟組件的信息傳遞的方法實(shí)例詳解

    這篇文章主要介紹了vue 兄弟組件的信息傳遞的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • vue實(shí)現(xiàn)多欄布局拖拽

    vue實(shí)現(xiàn)多欄布局拖拽

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)多欄布局拖拽,改變盒子的寬度,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue通過URL傳參如何控制全局console.log的開關(guān)詳解

    Vue通過URL傳參如何控制全局console.log的開關(guān)詳解

    這篇文章主要給大家介紹了關(guān)于Vue根據(jù)URL傳參如何控制全局console.log開關(guān)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-12-12
  • vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加

    vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加

    這篇文章主要為大家介紹了vue頁面渲染數(shù)組中數(shù)據(jù)文案后添加逗號最后不加逗號示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • vue、react等單頁面項(xiàng)目應(yīng)該這樣子部署到服務(wù)器

    vue、react等單頁面項(xiàng)目應(yīng)該這樣子部署到服務(wù)器

    這篇文章主要介紹了vue、react等單頁面項(xiàng)目應(yīng)該這樣子部署到服務(wù)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論