vue使用Vue.extend創(chuàng)建全局toast組件實(shí)例
Vue.extend創(chuàng)建全局toast組件
src -> components -> Toast -> toast.vue
<template> ? <transition name="fades"> ? ? <div class="Errormes" ?v-if="show">{{txt}}</div> ? </transition> </template> ? <script> export default { ? name: 'Toast', ? data () { ? ? return { ? ? ? txt: '', ? ? ? show: false ? ? } ? } } </script> <style lang="less" scoped> .fades-enter-active, .fades-leave-active { ? transition: opacity 0.5s; } .fades-enter, .fades-leave-active { ? opacity: 0; } /* 提示彈框 */ .Errormes { ? position: fixed; ? top: 40%; ? left: 50%; ? -webkit-transform: translate(-50%, -50%); ? transform: translate(-50%, -50%); ? padding: 20px 30px; ? background: rgba(0, 0, 0, 0.8); ? border-radius: 16px; ? color: #fff; ? font-size: 28px; ? z-index: 999999; ? max-width: 80%; ? height: auto; ? line-height: 60px; ? text-align: center; } </style>
src -> components -> Toast -> index.js
import Toast from './toast.vue' ? const toast = {} toast.install = (vue) => { ? const ToastClass = vue.extend(Toast) ? const instance = new ToastClass() ? instance.$mount(document.createElement('div')) ? document.body.appendChild(instance.$el) ? ? let t = null ? const ToastMain = { ? ? show (msg, seconds = 2000) { ? ? ? if (t) clearTimeout(t) ? ? ? instance.txt = msg ? ? ? instance.show = true ? ? ? t = setTimeout(() => { ? ? ? ? instance.show = false ? ? ? }, seconds) ? ? } ? } ? vue.prototype.$toast = ToastMain } ? export default toast
main.js
import Vue from 'vue' import App from './App.vue' import toast from '@/components/Toast/index' ? Vue.use(toast)
使用
$toast.show(message)
關(guān)于vue.extend的理解應(yīng)用
基本概念
Vue.extend( options )
使用基礎(chǔ) Vue 構(gòu)造器,創(chuàng)建一個(gè)“子類”。參數(shù)是一個(gè)包含組件選項(xiàng)的對(duì)象。
一般,我們會(huì)用 Vue.extend 接收一個(gè)組件對(duì)象來(lái)創(chuàng)建一個(gè)構(gòu)造器,再利用創(chuàng)建的構(gòu)造器 new 一個(gè)實(shí)例,并將這個(gè)實(shí)例掛載到一個(gè)元素上。
官網(wǎng)基本示例
<div id="mount-point"></div> // 創(chuàng)建構(gòu)造器 var Profile = Vue.extend({ ? template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', ? data: function () { ? ? return { ? ? ? firstName: 'Walter', ? ? ? lastName: 'White', ? ? ? alias: 'Heisenberg' ? ? } ? } }) // 創(chuàng)建 Profile 實(shí)例,并掛載到一個(gè)元素上。 new Profile().$mount('#mount-point')
data 選項(xiàng)是特例,需要注意 - 在 Vue.extend() 中它必須是函數(shù)
結(jié)果如下:
<p>Walter White aka Heisenberg</p>
應(yīng)用
Vue.extend 屬于 Vue 的全局 API,在實(shí)際業(yè)務(wù)開(kāi)發(fā)中我們很少使用,因?yàn)橄啾瘸S玫?Vue.component 寫法使用 extend 步驟要更加繁瑣一些。
但是在一些獨(dú)立組件開(kāi)發(fā)場(chǎng)景中,例如要實(shí)現(xiàn)一個(gè)類似于 window.alert() 提示組件,要求像調(diào)用 JS 函數(shù)一樣調(diào)用它,這時(shí)候 Vue.extend + $mount 這對(duì)組合就是我們需要去關(guān)注的。
1、vue $mount 和 el的區(qū)別說(shuō)明
在應(yīng)用之前我們先了解一下2個(gè)東西 —— $mount 和 el,兩者在使用效果上沒(méi)有任何區(qū)別,都是為了將實(shí)例化后的vue掛載到指定的dom元素中。
如果在實(shí)例化vue的時(shí)候指定el,則該vue將會(huì)渲染在此el對(duì)應(yīng)的dom中,反之,若沒(méi)有指定el,則vue實(shí)例會(huì)處于一種“未掛載”的狀態(tài),此時(shí)可以通過(guò)$mount來(lái)手動(dòng)執(zhí)行掛載。
注:如果$mount沒(méi)有提供參數(shù),模板將被渲染為文檔之外的的元素,并且你必須使用原生DOM API把它插入文檔中。
var MyComponent = Vue.extend({ ?template: '<div>Hello!</div>' }) ? // 創(chuàng)建并掛載到 #app (會(huì)替換 #app) new MyComponent().$mount('#app') ? // 同上 new MyComponent({ el: '#app' }) ? // 或者,在文檔之外渲染并且隨后掛載 var component = new MyComponent().$mount() document.getElementById('app').appendChild(component.$el)
2、Vue.extend實(shí)現(xiàn)Loading插件($mount)
<div id="root"> ? ? <button @click="showLoading">顯示Loading</button> </div> function Loading(msg) { ? ? ? ? // 創(chuàng)建構(gòu)造器 ? ? ? ? const Loading = Vue.extend({ ? ? ? ? ? template: '<div id="loading-msg">{{ msg }}</div>', ? ? ? ? ? props: { ? ? ? ? ? ? msg: { ? ? ? ? ? ? ? type: String, ? ? ? ? ? ? ? default: '加載中' ? ? ? ? ? ? } ? ? ? ? ? }, ? ? ? ? ? name: 'Loading' ? ? ? ? }) ? ? ? ? ? // 創(chuàng)建掛載div ? ? ? ? const div = document.createElement('div') ? ? ? ? div.setAttribute('id', 'loading-div') ? ? ? ? document.body.append(div) ? ? ? ? ? // 創(chuàng)建實(shí)例并掛載到一個(gè)元素上 ? ? ? ? new Loading().$mount('#loading-div') ? ? ? ? ? // 返回一個(gè)移除元素的function ? ? ? ? return () => { ? ? ? ? ? document.body.removeChild(document.getElementById('loading-div')) ? ? ? ? } } ? // 掛載到vue實(shí)例上 Vue.prototype.$loading = Loading ? ?new Vue({ ? ? ?el: '#root', ? ? ?methods: { ? ? ? ? showLoading() { ? ? ? ? ? ? const hide = this.$loading('正在加載,請(qǐng)稍等...') ? ? ? ? ? ? setTimeout(() => { ? ? ? ? ? ? ? hide() ? ? ? ? ? ? }, 1500) ? ? ? ? } ? ? ?} })
3、Vue.extend實(shí)現(xiàn)信息彈窗插件(el)
新建一個(gè)popBox.vue
<template> ? <div id="confirm" v-if='flag'> ? ? <div class="contents" > ? ? ? <div class="content-top">{{ text.title }}</div> ? ? ? <div class="content-center">{{ text.msg }}</div> ? ? ? <div class="content-bottom"> ? ? ? ? <button @click='show' class="left">{{ text.btn.ok }}</button> ? ? ? ? <button @click='hide' class="right">{{ text.btn.no }}</button> ? ? ? </div> ? ? </div> ? </div> </template> ? <script> ? export default { ? data () { ? ? return { ? ? ? flag: true, ? ? ? text: { ? ? ? ? ? title:'標(biāo)題', ? ? ? ? ? msg: '這是一個(gè)信息彈出框組件', ? ? ? ? ? btn: { ? ? ? ? ? ? ? ok: '確定', ? ? ? ? ? ? ? no: '取消' ? ? ? ? ? } ? ? ? } ? ? } ? }, ? ? methods: { ? ? show (){ ? ? ? this.flag = false; ? ? }, ? ? ? hide() { ? ? ? this.flag = false; ? ? } ? } } ? </script>
新建一個(gè)popBox.js
import Vue from 'vue' import PopBox from './popBox.vue' ? // Vue.extend返回一個(gè)實(shí)例創(chuàng)建的構(gòu)造器,但實(shí)例構(gòu)造器需要進(jìn)行掛載到頁(yè)面中 let popBox = Vue.extend(PopBox) ?? ? popBox.install = (vue, text) => { ? ? ?? ? ? ? ? // 在body中動(dòng)態(tài)創(chuàng)建一個(gè)div元素,之后此div將會(huì)替換成整個(gè)vue文件的內(nèi)容 ? ? ? ? // 此時(shí)的popBoxDom通俗講就是相當(dāng)于是整個(gè)組件對(duì)象,通過(guò)對(duì)象調(diào)用屬性的方法來(lái)進(jìn)行組件中數(shù)據(jù)的使用 ? ? ? ? let popBoxDom = new popBox({ ? ? ? ? ? ? el: document.createElement('div') ? ? ? ? }) ? ? ? ? ?? ? ? ? ? // 可以通過(guò)$el屬性來(lái)訪問(wèn)創(chuàng)建的組件實(shí)例 ? ? ? ? document.body.appendChild(popBoxDom.$el) ? ? ? ? ? ? ? // 將需要傳入的文本內(nèi)容傳給組件實(shí)例 ? ? ? ? popBoxDom.text = text; ? ? ? ? ? // 返回一個(gè)promise,進(jìn)行異步操作,成功時(shí)返回,失敗時(shí)返回 ? ? ? ? return new Promise((res, rej) => { ? ?? ? ? ? ? ? ? popBoxDom.show = () => { ?? ? ? ? ? ? ? ? ? res() ? //正確時(shí)返回的操作 ? ? ? ? ? ? ? ? popBoxDom.flag = false; ? ? ? ? ? ? } ? ? ? ? ? ? ? popBoxDom.hide = ()=>{ ? ? ? ? ? ? ? ? rej() ? //失敗時(shí)返回的操作 ? ? ? ? ? ? ? ? popBoxDom.flag = false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ? vue.prototype.$popBox = popBox ? ? ? ? }) } ? // 將邏輯函數(shù)進(jìn)行導(dǎo)出和暴露 export default popBox
頁(yè)面使用
import PopBox from './popBox.js' ? Vue.use(popBOx); ? ? this.$popBox({ ? ? ? title:'標(biāo)題', ? ? ? msg:'內(nèi)容', ? ? ? btn:{ ok:'確定', no:'取消'} }).then(()=>{ ? ? ? console.log('ok') }).catch(()=>{ ? ? ? console.log('no') })
其他
import toastCom from "./Toast"; ? const toast = {}; toast.install = vue => { ?const ToastCon = vue.extend(toastCom); ?const ins = new ToastCon(); ?ins.$mount(document.createElement("div")); ?document.body.appendChild(ins.$el); ?console.log(ins.toast) ?vue.prototype.$toast = ins.toast; }; ? ? ? const globalComponent = { ?install: function(Vue) { ? ?Vue.use(toast); ?} }; ? export default globalComponent;
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
解讀Vue3中keep-alive和動(dòng)態(tài)組件的實(shí)現(xiàn)邏輯
這篇文章主要介紹了Vue3中keep-alive和動(dòng)態(tài)組件的實(shí)現(xiàn)邏輯,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05element-plus 如何設(shè)置 el-date-picker 彈出框位置
el-date-picker 組件會(huì)自動(dòng)根據(jù)空間范圍進(jìn)行選擇比較好的彈出位置,但特定情況下,它自動(dòng)計(jì)算出的彈出位置并不符合我們的實(shí)際需求,故需要我們手動(dòng)設(shè)置,這篇文章主要介紹了element-plus 如何設(shè)置 el-date-picker 彈出框位置,需要的朋友可以參考下2024-07-07Vue實(shí)現(xiàn)簡(jiǎn)單基礎(chǔ)的圖片裁剪功能
這篇文章主要為大家詳細(xì)介紹了如何利用Vue2實(shí)現(xiàn)簡(jiǎn)單基礎(chǔ)的圖片裁剪功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2022-09-09Element 的 el-table 表格實(shí)現(xiàn)單元格合并功能
這篇文章主要介紹了Element 的 el-table 表格實(shí)現(xiàn)單元格合并功能,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-07-07vue 根據(jù)數(shù)組中某一項(xiàng)的值進(jìn)行排序的方法
這篇文章主要介紹了vue 根據(jù)數(shù)組中某一項(xiàng)的值進(jìn)行排序的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08vue使用Proxy實(shí)現(xiàn)雙向綁定的方法示例
這篇文章主要介紹了vue使用Proxy實(shí)現(xiàn)雙向綁定的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03淺談vuejs實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)視圖原理
這篇文章主要介紹了淺談vuejs實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)視圖原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局的實(shí)現(xiàn)
這篇文章主要介紹了從零開(kāi)始在vue-cli4配置自適應(yīng)vw布局,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06vue?element-plus中el-input修改邊框border的方法
element樣式還是蠻好的,只是有時(shí)候我們需要做一些調(diào)整,比如el-input的邊框,下面這篇文章主要給大家介紹了關(guān)于vue?element-plus中el-input修改邊框border的相關(guān)資料,需要的朋友可以參考下2022-09-09