成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

vue實現點擊出現操作彈出框的示例

瀏覽:3日期:2022-11-06 08:23:19

vue實現點擊出現操作彈出框的示例

如上圖所示,這次要實現一個點擊出現操作彈框的效果;并將這個功能封裝成一個函數,便于在項目的多個地方使用。

具體思路是:

封裝一個組件,組件保護一個插槽,我們可以根據不同的場景,利用插槽隨意在這個彈框里插入任何元素,這個彈框顯示時根據我鼠標的點擊位置,定位彈窗的位置,并在組件里面監聽鼠標抬起事件,觸發事件時將彈窗隱藏;

接著在函數中利用createElement和appendChild方法將彈出框創建并插入到頁面中;

  本次實現基于vuecli3

接下來,具體實現:

首先,我們先寫一個demo組件

  在點擊出現彈出框的元素上把事件對象數據傳遞一下,以便獲取點擊時鼠標的數據,以此確定彈出框的位置

// 文件路徑參考: src > views > demo> index.vue<template> <div class='demo-wrapper'> <div class='demo-div'> <span>更多功能</span> <i @click.stop=’showMenu($event)’></i> // 為了獲取鼠標位置,這里把事件對象數據傳遞一下 </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){ // 點擊時出現彈出框 } };</script>

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

組件隨便命名為ActionList,組件里面把把列表數據及點擊事件都基于父組件傳遞的值而定,由于只是小demo,所以我們傳遞的menu數據數組只是簡單的字符串數組

// 文件路徑參考: src > components > ActionList > index.vue<template> <ul class='menu-wrapper'> <li 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’;@Componentexport default class ActionList extends Vue { @Prop() menu: string[]; handleClick(str: string) { this.$emit(’click’, str); }}</script>

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

  1、彈框組件的顯示隱藏用v-show控制,為什么不用v-if ?因為這里我監聽了mouseup事件來讓彈框隱藏,如果在插槽里的元素綁定事件,比如點擊事件,用v-if 的話,點擊插槽里的元素時,彈框先消失,插槽里的點擊事件就不會生效了。

2、handleOpen事件里我們根據鼠標點擊位置定位彈框位置。

// 文件路徑參考: src > components > PublicModel > index.vue<template> <div : 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;}@Componentexport default class PublicModel extends Vue { showModel:boolean = false; style:IStyle = {}; // 組件顯示時 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) } // 隱藏關閉此組件 closeModel(){ this.showModel = false; document.removeEventListener(’mouseup’, this.closeModel); } // 組件銷毀生命周期 destroyed(){ document.removeEventListener(’mouseup’, this.closeModel); }}</script>

接著,重點來了,書寫公用封裝函數

  我們要在demo組件點擊時觸發這個函數,即在demo組件里的showMenu事件觸發函數,這個函數要利用createElement和appendChild方法將彈出框創建并插入到頁面中。

  因為是點擊時創建并插入元素,所以為了性能優化,避免有惡意瘋狂點擊,不斷創建和插入元素,我們利用throttle-debounce插件做一個節流。

  先直接看代碼,其他注釋寫在了代碼里,函數名隨意取:ModelFun

// 文件路徑參考: src > components > PublicModel > index.tsimport Vue from ’vue’;import PublicModel from ’./index.vue’; // 導入上面所寫的彈框組件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) => { // 這里兩個參數一個是彈框里插槽的組件,還有就是點擊的事件對象(方便定位彈框位置) if(!instance){ initInstance() } instance.$slots.default = [slotVNode]; // 將傳遞過來的插槽組件插入彈框組件中 instance.handleOpen($event) // 觸發彈框組件(見上一段代碼)的彈框獲取定位信息并顯示的事件}const ModelFun = debounce(200, false, insertInstanceSlot) // 使用throttle-debounce里的debounce保證在一系列調用時間中回調函數只執行一次,這里是200毫秒 // 第二個參數為false時,在點擊時會在200毫秒后再執行callback(即insertInstanceSlot),但為true時,會立即先執行一次;export default ModelFun

接著,重點來了,書寫公用封裝函數

  我們要在demo組件點擊時觸發這個函數,即在demo組件里的showMenu事件觸發函數,這個函數要利用createElement和appendChild方法將彈出框創建并插入到頁面中。

  因為是點擊時創建并插入元素,所以為了性能優化,避免有惡意瘋狂點擊,不斷創建和插入元素,我們利用throttle-debounce插件做一個節流。

  先直接看代碼,其他注釋寫在了代碼里,函數名隨意取:ModelFun

// 文件路徑參考: src > components > PublicModel > index.tsimport Vue from ’vue’;import PublicModel from ’./index.vue’; // 導入上面所寫的彈框組件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) => { // 這里兩個參數一個是彈框里插槽的組件,還有就是點擊的事件對象(方便定位彈框位置) if(!instance){ initInstance() } instance.$slots.default = [slotVNode]; // 將傳遞過來的插槽組件插入彈框組件中 instance.handleOpen($event) // 觸發彈框組件(見上一段代碼)的彈框獲取定位信息并顯示的事件}const ModelFun = debounce(200, false, insertInstanceSlot) // 使用throttle-debounce里的debounce保證在一系列調用時間中回調函數只執行一次,這里是200毫秒 // 第二個參數為false時,在點擊時會在200毫秒后再執行callback(即insertInstanceSlot),但為true時,會立即先執行一次;export default ModelFun

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

利用vue的 $createElement 將ActionList組件插入彈框中,并將數據和事件傳遞給ActionList組件,這里我們傳遞的事件是簡單的彈出我們點擊的數據

// 文件路徑參考: src > views > demo> index.vue<template> <div class='demo-wrapper'> <div class='demo-div'> <span>更多功能</span> <i @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){ // 彈框里插槽的點擊事件 this.$message({message:name,type:’success’}) } showMenu($event:any){ modelFun(this.$createElement( ActionList, { props: { menu:this.menuList }, on:{ click: this.menuClick, } }),$event ) } };</script>

至此,效果如下

vue實現點擊出現操作彈出框的示例

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

<template> <div class='demo-wrapper'> <el-tree:data='data' node-key='id':default-expand-all='true' :expand-on-click-node='false' show-checkbox ><div iv slot-scope='{ node }'> <span>{{ node.label }}</span> <span @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: ’一級 1’, children: [{ id: 4, label: ’二級 1-1’, children: [{ id: 9, label: ’三級 1-1-1’ }, { id: 10, label: ’三級 1-1-2’ }] }] }, { id: 2, label: ’一級 2’, children: [{ id: 5, label: ’二級 2-1’ }, { id: 6, label: ’二級 2-2’ }] }, { id: 3, label: ’一級 3’, children: [{ id: 7, label: ’二級 3-1’ }, { id: 8, label: ’二級 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實現點擊出現操作彈出框的示例

以上就是vue實現點擊出現操作彈出框的示例的詳細內容,更多關于vue 彈出框的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
亚洲国产色一区| 中文字幕制服丝袜成人av| 国产日产精品一区二区三区四区的观看方式 | 国产亚洲一区二区三区| 亚洲精品一二三区| 精品一区二区三区视频| 午夜精品一区二区在线观看| 亚洲欧美日韩视频二区| 欧美电影免费观看高清完整版在| 亚洲精品自拍动漫在线| 91香蕉视频污在线| 久久人人97超碰国产公开结果| 精品国产乱码久久久久久久| 亚洲日本va在线观看| 国产一区美女在线| 亚洲大片在线| 7878成人国产在线观看| 1区2区3区国产精品| 激情综合色综合久久综合| 欧美亚洲日本一区| 亚洲欧美综合色| 亚洲午夜极品| 日韩一区二区视频在线观看| 一区二区三区四区在线| 成人伦理片在线| 国产精品久久亚洲7777| 久久综合狠狠综合久久综合88| 日韩av电影天堂| 国产精品mm| 91麻豆精品国产91久久久使用方法| 久久国产尿小便嘘嘘尿| 一区二区三区四区国产| 亚洲美女免费在线| 972aa.com艺术欧美| 91极品美女在线| 亚洲色图在线看| 亚洲欧洲日韩综合二区| 国产午夜精品理论片a级大结局| 波多野结衣一区二区三区 | 亚洲在线观看免费视频| 99久久精品情趣| 欧美国产精品久久| 成人综合在线观看| 久久久国产精品麻豆| 激情深爱一区二区| 性欧美xxxx大乳国产app| 日韩国产在线观看| 欧美一区午夜精品| 经典三级视频一区| 欧美大片拔萝卜| 欧美午夜在线| 午夜欧美大尺度福利影院在线看| 国产精品分类| 精品国产麻豆免费人成网站| 91社区在线播放| 一区二区三区国产精华| 欧美性xxxxx极品少妇| 成人精品免费网站| 国产精品萝li| 午夜精品一区二区三区四区 | 激情深爱一区二区| 国产欧美日韩在线视频| 国产成人免费视频一区| 欧美性淫爽ww久久久久无| 国产在线日韩欧美| 国产日本欧美一区二区| 国产欧美在线| 精品一区精品二区高清| 国产日韩欧美不卡在线| 麻豆成人精品| 亚洲综合一二区| 欧美日韩一区二区电影| 麻豆一区二区99久久久久| 久久久久久亚洲精品不卡4k岛国| 久久精品99国产精品日本| 精品久久国产字幕高潮| 成人免费不卡视频| 中文字幕欧美一区| 欧美日韩精品二区第二页| 免费人成精品欧美精品| 久久亚洲一区| 国产精品一区在线观看乱码| 欧美日本在线看| 欧美1区免费| 国产精品色婷婷| 日本韩国一区二区三区视频| 99免费精品视频| 午夜影院久久久| 色狠狠av一区二区三区| 夫妻av一区二区| www激情久久| 亚洲在线播放电影| 日韩专区中文字幕一区二区| 色天天综合色天天久久| 捆绑变态av一区二区三区 | 日韩va亚洲va欧美va久久| 久久色在线视频| 在线免费不卡电影| 黑人巨大精品欧美一区| 国产精品毛片久久久久久| 欧美最猛黑人xxxxx猛交| 国产精品红桃| 国产资源在线一区| 伊人婷婷欧美激情| 2023国产精品| 欧美特级限制片免费在线观看| 伊大人香蕉综合8在线视| 国产精品中文字幕欧美| 亚洲国产日韩av| 国产亚洲欧美日韩俺去了| 久久深夜福利| 欧美日韩国产色综合一二三四| 韩国精品免费视频| 亚洲精品伦理在线| 精品国产sm最大网站免费看| 日本道免费精品一区二区三区| 欧美精品九九| 国产盗摄视频一区二区三区| 五月激情综合婷婷| 亚洲欧美中日韩| 欧美tk丨vk视频| 欧美在线看片a免费观看| 亚洲黄色天堂| 欧美在线高清| 国产91丝袜在线观看| 婷婷一区二区三区| 一色屋精品亚洲香蕉网站| 精品毛片乱码1区2区3区| 欧美影院精品一区| 国产亚洲综合精品| 欧美网站在线| 99久久久久免费精品国产 | 色综合久久99| 亚洲区欧美区| 女人色偷偷aa久久天堂| 国产不卡视频在线观看| 免费成人在线视频观看| 亚洲图片有声小说| 亚洲欧美区自拍先锋| 久久精品在这里| 日韩一区二区三免费高清| 欧美羞羞免费网站| 美女被久久久| 999亚洲国产精| 美女一区二区在线观看| 亚洲欧美欧美一区二区三区| 国产精品无遮挡| 久久久久久久久久久电影| 欧美一区二区精美| 欧美日韩亚洲国产综合| 一本到不卡免费一区二区| 99pao成人国产永久免费视频| 欧美精品v日韩精品v国产精品| 成人av片在线观看| 亚洲女厕所小便bbb| 久久色.com| 2020国产精品自拍| 精品久久一二三区| 欧美大片拔萝卜| 欧美成人aa大片| 日韩欧美国产电影| 欧美一级久久久久久久大片| 91精品午夜视频| 51久久夜色精品国产麻豆| 欧美人体做爰大胆视频| 欧美少妇一区二区| 在线视频一区二区三| 日本久久精品电影| 在线观看亚洲成人| 欧美日韩久久久| 欧美图区在线视频| 欧美日韩一二区| 在线观看91av| 亚洲欧洲视频| 黄色亚洲免费| 亚洲精选一区| 国产女主播一区二区| 香蕉久久夜色| 色就色 综合激情| 欧美日韩一区二区三区在线 | 欧美一级午夜免费电影| 在线电影一区二区三区| 欧美一级夜夜爽| 久久久五月婷婷| 中文av一区特黄| 亚洲色图视频网站| 亚洲午夜久久久久久久久久久| 午夜精品福利一区二区蜜股av| 日韩av一二三| 国产一区二区三区免费观看| 大尺度一区二区| 午夜电影亚洲| 日韩一级大片| 久久久久久网| 欧美色综合影院| 欧美一级在线免费| 国产午夜精品福利| 亚洲乱码国产乱码精品精可以看| 亚洲成人中文在线| 精品一区二区精品|