最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)操作彈出框的示例

 更新時(shí)間:2020年11月05日 09:50:49   作者:陳山豆  
這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)操作彈出框的示例,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下

  如上圖所示,這次要實(shí)現(xiàn)一個(gè)點(diǎn)擊出現(xiàn)操作彈框的效果;并將這個(gè)功能封裝成一個(gè)函數(shù),便于在項(xiàng)目的多個(gè)地方使用。

具體思路是:

  封裝一個(gè)組件,組件保護(hù)一個(gè)插槽,我們可以根據(jù)不同的場(chǎng)景,利用插槽隨意在這個(gè)彈框里插入任何元素,這個(gè)彈框顯示時(shí)根據(jù)我鼠標(biāo)的點(diǎn)擊位置,定位彈窗的位置,并在組件里面監(jiān)聽鼠標(biāo)抬起事件,觸發(fā)事件時(shí)將彈窗隱藏;

接著在函數(shù)中利用createElement和appendChild方法將彈出框創(chuàng)建并插入到頁面中;

   本次實(shí)現(xiàn)基于vuecli3

接下來,具體實(shí)現(xiàn):

     首先,我們先寫一個(gè)demo組件

   在點(diǎn)擊出現(xiàn)彈出框的元素上把事件對(duì)象數(shù)據(jù)傳遞一下,以便獲取點(diǎn)擊時(shí)鼠標(biāo)的數(shù)據(jù),以此確定彈出框的位置

// 文件路徑參考: src > views > demo> index.vue
<template>
 <div class="demo-wrapper">
  <div class="demo-div">
   <span>更多功能</span>
   <i class="xk-icon xk-ellipsis" @click.stop='showMenu($event)'></i> // 為了獲取鼠標(biāo)位置,這里把事件對(duì)象數(shù)據(jù)傳遞一下
  </div>
 </div>
</template>

<script lang="ts">
 import { Vue, Component, Prop, Watch} from "vue-property-decorator";
 @Component({

 })
 export default class articleView extends Vue {
  showMenu($event:any){
   // 點(diǎn)擊時(shí)出現(xiàn)彈出框
  }
 };
</script>

     接著,我們把彈出框里面的組件也寫一下

     組件隨便命名為ActionList,組件里面把把列表數(shù)據(jù)及點(diǎn)擊事件都基于父組件傳遞的值而定,由于只是小demo,所以我們傳遞的menu數(shù)據(jù)數(shù)組只是簡(jiǎn)單的字符串?dāng)?shù)組

// 文件路徑參考: src > components > ActionList > index.vue<template>
 <ul class="menu-wrapper">
  <li
   class="menu-item"
   v-for="item in menu"
   :key="item"
   @click="handleClick(item)"
  >
   {{ item }}
  </li>
 </ul>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class ActionList extends Vue {
 @Prop() menu: string[];
 handleClick(str: string) {
  this.$emit('click', str);
 }
}
</script>

    接著,開始著手寫彈框組件

  1、彈框組件的顯示隱藏用v-show控制,為什么不用v-if ?因?yàn)檫@里我監(jiān)聽了mouseup事件來讓彈框隱藏,如果在插槽里的元素綁定事件,比如點(diǎn)擊事件,用v-if 的話,點(diǎn)擊插槽里的元素時(shí),彈框先消失,插槽里的點(diǎn)擊事件就不會(huì)生效了。

     2、handleOpen事件里我們根據(jù)鼠標(biāo)點(diǎn)擊位置定位彈框位置。

// 文件路徑參考: src > components > PublicModel > index.vue<template>
 <div class="dropdown-menu" :style="style" v-show='showModel'>
  <slot></slot>
 </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
interface IStyle {
 left?: string;
 right?: string;
 top?: string;
 bottom?: string;
}
@Component
export default class PublicModel extends Vue {
 showModel:boolean = false;
 style:IStyle = {};

 // 組件顯示時(shí)
 handleOpen($event:any){
  const { clientWidth, clientHeight, scrollWidth, scrollHeight } = document.body || document.documentElement;
  const { pageX, pageY, clientX, clientY } = $event;
  let style:IStyle = {} 
  if(clientX > (clientWidth * 2)/3 ){
   style.right = scrollWidth - pageX + 10 + 'px';
  }else{
   style.left = pageX+10+'px'
  }
  if(clientY > (clientHeight * 2) / 3 ){
   style.bottom = scrollHeight - pageY + 10 + 'px';
  }else{
   style.top = pageY + 10 + "px"
  }
  this.style = style;
  this.showModel = true;
  document.addEventListener('mouseup',this.closeModel)
 }

 // 隱藏關(guān)閉此組件
 closeModel(){
  this.showModel = false;
  document.removeEventListener('mouseup', this.closeModel);
 }

 // 組件銷毀生命周期
 destroyed(){
  document.removeEventListener('mouseup', this.closeModel);
 }
}
</script>

    接著,重點(diǎn)來了,書寫公用封裝函數(shù)

  我們要在demo組件點(diǎn)擊時(shí)觸發(fā)這個(gè)函數(shù),即在demo組件里的showMenu事件觸發(fā)函數(shù),這個(gè)函數(shù)要利用createElement和appendChild方法將彈出框創(chuàng)建并插入到頁面中。

  因?yàn)槭屈c(diǎn)擊時(shí)創(chuàng)建并插入元素,所以為了性能優(yōu)化,避免有惡意瘋狂點(diǎn)擊,不斷創(chuàng)建和插入元素,我們利用throttle-debounce插件做一個(gè)節(jié)流。

  先直接看代碼,其他注釋寫在了代碼里,函數(shù)名隨意?。篗odelFun

// 文件路徑參考: src > components > PublicModel > index.ts
import Vue from 'vue';
import PublicModel from './index.vue'; // 導(dǎo)入上面所寫的彈框組件
const throttleDebounce = require('throttle-debounce'); // throttle-debounce插件
const debounce = throttleDebounce.debounce;
const PublicModelConstructor = Vue.extend(PublicModel);
let instance:any;
const initInstance = () => {
 instance = new PublicModelConstructor({
  el: document.createElement('div'),
 });
 document.body.appendChild(instance.$el);
}
const insertInstanceSlot = (slotVNode:any, $event:any) => { // 這里兩個(gè)參數(shù)一個(gè)是彈框里插槽的組件,還有就是點(diǎn)擊的事件對(duì)象(方便定位彈框位置)
 if(!instance){
  initInstance()
 }
 instance.$slots.default = [slotVNode]; // 將傳遞過來的插槽組件插入彈框組件中
 instance.handleOpen($event) // 觸發(fā)彈框組件(見上一段代碼)的彈框獲取定位信息并顯示的事件
}
const ModelFun = debounce(200, false, insertInstanceSlot) // 使用throttle-debounce里的debounce保證在一系列調(diào)用時(shí)間中回調(diào)函數(shù)只執(zhí)行一次,這里是200毫秒               // 第二個(gè)參數(shù)為false時(shí),在點(diǎn)擊時(shí)會(huì)在200毫秒后再執(zhí)行callback(即insertInstanceSlot),但為true時(shí),會(huì)立即先執(zhí)行一次;
export default ModelFun

    接著,重點(diǎn)來了,書寫公用封裝函數(shù)

  我們要在demo組件點(diǎn)擊時(shí)觸發(fā)這個(gè)函數(shù),即在demo組件里的showMenu事件觸發(fā)函數(shù),這個(gè)函數(shù)要利用createElement和appendChild方法將彈出框創(chuàng)建并插入到頁面中。

  因?yàn)槭屈c(diǎn)擊時(shí)創(chuàng)建并插入元素,所以為了性能優(yōu)化,避免有惡意瘋狂點(diǎn)擊,不斷創(chuàng)建和插入元素,我們利用throttle-debounce插件做一個(gè)節(jié)流。

  先直接看代碼,其他注釋寫在了代碼里,函數(shù)名隨意?。篗odelFun

// 文件路徑參考: src > components > PublicModel > index.tsimport Vue from 'vue';
import PublicModel from './index.vue'; // 導(dǎo)入上面所寫的彈框組件
const throttleDebounce = require('throttle-debounce'); // throttle-debounce插件
const debounce = throttleDebounce.debounce;
const PublicModelConstructor = Vue.extend(PublicModel);
let instance:any;
const initInstance = () => {
 instance = new PublicModelConstructor({
  el: document.createElement('div'),
 });
 document.body.appendChild(instance.$el);
}
const insertInstanceSlot = (slotVNode:any, $event:any) => { // 這里兩個(gè)參數(shù)一個(gè)是彈框里插槽的組件,還有就是點(diǎn)擊的事件對(duì)象(方便定位彈框位置)
 if(!instance){
  initInstance()
 }
 instance.$slots.default = [slotVNode]; // 將傳遞過來的插槽組件插入彈框組件中
 instance.handleOpen($event) // 觸發(fā)彈框組件(見上一段代碼)的彈框獲取定位信息并顯示的事件
}
const ModelFun = debounce(200, false, insertInstanceSlot) // 使用throttle-debounce里的debounce保證在一系列調(diào)用時(shí)間中回調(diào)函數(shù)只執(zhí)行一次,這里是200毫秒               // 第二個(gè)參數(shù)為false時(shí),在點(diǎn)擊時(shí)會(huì)在200毫秒后再執(zhí)行callback(即insertInstanceSlot),但為true時(shí),會(huì)立即先執(zhí)行一次;export default ModelFun

    最后,我們回過頭來完善一下demo組件

     利用vue的 $createElement 將ActionList組件插入彈框中,并將數(shù)據(jù)和事件傳遞給ActionList組件,這里我們傳遞的事件是簡(jiǎn)單的彈出我們點(diǎn)擊的數(shù)據(jù)

// 文件路徑參考: src > views > demo> index.vue<template>
 <div class="demo-wrapper">
  <div class="demo-div">
   <span>更多功能</span>
   <i class="xk-icon xk-ellipsis" @click.stop='showMenu($event)'></i>
  </div>
 </div>
</template>

<script lang="ts">
 import { Vue, Component, Prop, Watch} from "vue-property-decorator";
 import ActionList from "@/components/ActionList/index.vue";
 import modelFun from "@/components/PublicModel/index";
 @Component({

 })
 export default class articleView extends Vue {
  menuList: string[] = ['菜單1','菜單2','菜單3'];
  menuClick(name:string){ // 彈框里插槽的點(diǎn)擊事件
   this.$message({message:name,type:'success'})
  }
  showMenu($event:any){
   modelFun(
    this.$createElement(
     ActionList,
     {
      props: { menu:this.menuList },
      on:{
       click: this.menuClick,
      }
     }
    ),
    $event
   )
  }
 };
</script>

  至此,效果如下

最后,我們利用element ui 的 tree 組件結(jié)合我們封裝的彈框看一下效果
代碼:

<template>
 <div class="demo-wrapper">
  <el-tree
    :data="data"
   node-key="id"
    :default-expand-all="true"
   :expand-on-click-node="false"
   show-checkbox
   >
    <div class="custom-tree-node tree-item" iv slot-scope="{ node }">
     <span>{{ node.label }}</span>
     <span
      class="action"
      @click.stop="showMenu($event)"
     >
      <i class="el-icon-more"></i>
     </span>
    </div>
   </el-tree>
 </div>
</template>

<script lang="ts">
 import { Vue, Component, Prop, Watch} from "vue-property-decorator";
 import ActionList from "@/components/ActionList/index.vue";
 import modelFun from "@/components/PublicModel/index";
 @Component({

 })
 export default class articleView extends Vue {
  menuList: string[] = ['菜單1','菜單2','菜單3'];
  data:any[] = [{
  id: 1,
  label: '一級(jí) 1',
  children: [{
   id: 4,
   label: '二級(jí) 1-1',
   children: [{
   id: 9,
   label: '三級(jí) 1-1-1'
   }, {
   id: 10,
   label: '三級(jí) 1-1-2'
   }]
  }]
  }, {
  id: 2,
  label: '一級(jí) 2',
  children: [{
   id: 5,
   label: '二級(jí) 2-1'
  }, {
   id: 6,
   label: '二級(jí) 2-2'
  }]
  }, {
  id: 3,
  label: '一級(jí) 3',
  children: [{
   id: 7,
   label: '二級(jí) 3-1'
  }, {
   id: 8,
   label: '二級(jí) 3-2'
  }]
  }];
  menuClick(name:string){
   console.log(name)
   this.$message({message:name,type:'success'})
  }
  showMenu($event:any){
   modelFun(
    this.$createElement(
     ActionList,
     {
      props: { menu:this.menuList },
      on:{
       click: this.menuClick,
      }
     }
    ),
    $event
   )
  }
 };
</script>

效果:

以上就是vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)操作彈出框的示例的詳細(xì)內(nèi)容,更多關(guān)于vue 彈出框的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue項(xiàng)目中form?data形式傳參方式

    vue項(xiàng)目中form?data形式傳參方式

    這篇文章主要介紹了vue項(xiàng)目中form?data形式傳參方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Vue3父子通訊方式及Vue3插槽的使用方法詳解

    Vue3父子通訊方式及Vue3插槽的使用方法詳解

    這篇文章主要介紹了Vue3父子通訊方式及Vue3插槽的使用方法詳解,需要的朋友可以參考下
    2023-01-01
  • vue項(xiàng)目啟動(dòng)命令個(gè)人學(xué)習(xí)記錄

    vue項(xiàng)目啟動(dòng)命令個(gè)人學(xué)習(xí)記錄

    最近想要學(xué)習(xí)vue,正好看到資料,如何通過命令創(chuàng)建vue項(xiàng)目的方法,就留個(gè)筆記,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目啟動(dòng)命令的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • 路由vue-route的使用示例教程

    路由vue-route的使用示例教程

    這篇文章主要介紹了路由vue-route的使用,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • vue中獲取滾動(dòng)table的可視頁面寬度調(diào)整表頭與列對(duì)齊(每列寬度不都相同)

    vue中獲取滾動(dòng)table的可視頁面寬度調(diào)整表頭與列對(duì)齊(每列寬度不都相同)

    這篇文章主要介紹了vue中獲取滾動(dòng)table的可視頁面寬度,調(diào)整表頭與列對(duì)齊(每列寬度不都相同),需要的朋友可以參考下
    2019-08-08
  • 詳解如何運(yùn)行vue項(xiàng)目

    詳解如何運(yùn)行vue項(xiàng)目

    這篇文章主要介紹了如何運(yùn)行vue項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vant框架van-cell插槽無法換行問題及解決

    vant框架van-cell插槽無法換行問題及解決

    這篇文章主要介紹了vant框架van-cell插槽無法換行問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 基于Vue.js與WordPress Rest API構(gòu)建單頁應(yīng)用詳解

    基于Vue.js與WordPress Rest API構(gòu)建單頁應(yīng)用詳解

    這篇文章主要介紹了基于Vue.js與WordPress Rest API構(gòu)建單頁應(yīng)用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue 2源碼解析HTMLParserOptions.start函數(shù)方法

    Vue 2源碼解析HTMLParserOptions.start函數(shù)方法

    這篇文章主要為大家介紹了Vue 2源碼解析HTMLParserOptions.start函數(shù)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Vxe-Table開發(fā)中的各種坑以及避坑指南

    Vxe-Table開發(fā)中的各種坑以及避坑指南

    vxe-table是一個(gè)全功能的Vue表格,滿足絕大部分對(duì)Table的一切需求,與任意組件庫完美兼容,下面這篇文章主要給大家介紹了關(guān)于Vxe-Table開發(fā)中各種坑以及避坑的相關(guān)資料,需要的朋友可以參考下
    2022-09-09

最新評(píng)論

金堂县| 芜湖县| 永济市| 两当县| 鄂尔多斯市| 武清区| 广昌县| 尼勒克县| 依安县| 琼海市| 宝兴县| 观塘区| 太仆寺旗| 丽水市| 淮安市| 喀喇沁旗| 芮城县| 岚皋县| 都兰县| 改则县| 聊城市| 建瓯市| 永吉县| 安多县| 虎林市| 特克斯县| 柘城县| 莲花县| 旬阳县| 玉林市| 青铜峡市| 茶陵县| 宁河县| 商水县| 仁怀市| 逊克县| 沂源县| 汽车| 海宁市| 游戏| 永康市|