1 import ConfirmComponent from '../../components/confirm/index' 2 import { mergeOptions } from '../pluginHelper' 3 4 function plugin (Vue) { 5 if (plugin.install) { 6 return 7 } 8 const Confirm = Vue.extend(ConfirmComponent) 9 let $vm = new Confirm({ 10 el: document.createElement('div') 11 }) 12 document.body.appendChild($vm.$el) 13 const confirm = { 14 show (options) { 15 if ($vm.showValue) { 16 return 17 } 18 if (typeof options === 'object') { 19 mergeOptions($vm, options) 20 } 21 if (options && (options.onShow || options.onHide)) { 22 this.watcher = $vm.$watch('showValue', (val) => { 23 val && options.onShow && options.onShow($vm) 24 if (val === false) { 25 if (options.onHide) { 26 options.onHide($vm) 27 } 28 this.watcher && this.watcher() 29 } 30 }) 31 } 32 $vm.$off('on-cancel') 33 $vm.$off('on-confirm') 34 $vm.$on('on-cancel', () => { 35 options && options.onCancel && options.onCancel() 36 }) 37 $vm.$on('on-confirm', () => { 38 options && options.onConfirm && options.onConfirm() 39 }) 40 $vm.showValue = true 41 }, 42 hide () { 43 $vm.showValue = false 44 } 45 } 46 if (!Vue.confirm) { 47 Vue.confirm = confirm 48 } 49 Vue.mixin({ 50 created: function () { 51 this.$confirm = Vue.confirm 52 } 53 }) 54 } 55 56 export default plugin
pluginHelper
1 // merge 2 export const mergeOptions = function ($vm, options) { 3 const defaults = {} 4 for (let i in $vm.$options.props) { 5 defaults[i] = $vm.$options.props[i].default 6 } 7 const _options = Object.assign({}, defaults, options) 8 for (let i in _options) { 9 $vm[i] = _options[i] 10 } 11 } 12 13 export const initializeProps = function ($vm) { 14 for (let i in $vm.$options.props) { 15 $vm[i] = $vm.$options.props[i].default 16 } 17 }
loading
1 <template> 2 <div> 3 <transition name="transition"> 4 <div class="loading" v-show="show"> 5 <div class="toast"> 6 <i class="icon"></i> 7 <p class="text" v-if="text">{{text}}</p> 8 </div> 9 </div> 10 </transition> 11 </div> 12 </template> 13 14 <script> 15 export default { 16 name: 'loading', 17 props: { 18 show: Boolean, 19 text: String 20 } 21 } 22 </script> 23 24 <style lang="scss" scoped> 25 .loading { 26 position: fixed; 27 z-index: 1000; 28 top: 0; 29 right: 0; 30 left: 0; 31 bottom: 0; 32 33 .toast { 34 position: fixed; 35 z-index: 5000; 36 92px; 37 min-height: 92px; 38 top: 180px; 39 left: 50%; 40 margin-left: -46px; 41 background: rgba(17, 17, 17, 0.7); 42 text-align: center; 43 border-radius: 5px; 44 color: #FFFFFF; 45 } 46 47 .icon { 48 margin: 27px 0 0; 49 38px; 50 height: 38px; 51 display: inline-block; 52 vertical-align: middle; 53 -webkit-animation: loading 1s steps(12, end) infinite; 54 animation: loading 1s steps(12, end) infinite; 55 background: transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=") no-repeat; 56 background-size: 100%; 57 } 58 59 .text { 60 display: block; 61 margin: 2px 0 15px; 62 font-size: 12px; 63 } 64 } 65 66 // 转 67 @-webkit-keyframes loading { 68 0% { 69 transform: rotate3d(0, 0, 1, 0deg); 70 } 71 72 100% { 73 transform: rotate3d(0, 0, 1, 360deg); 74 } 75 } 76 77 @keyframes loading { 78 0% { 79 transform: rotate3d(0, 0, 1, 0deg); 80 } 81 82 100% { 83 transform: rotate3d(0, 0, 1, 360deg); 84 } 85 } 86 87 // 延时动画 88 .transition-enter, .transition-leave-active { 89 opacity: 0; 90 } 91 92 .transition-leave-active, .transition-enter-active { 93 transition: opacity 300ms; 94 } 95 </style>
pluginLoadind
1 import LoadingComponent from '../../components/loading/index' 2 3 function plugin (Vue) { 4 if (plugin.install) { 5 return 6 } 7 const Loading = Vue.extend(LoadingComponent) 8 let $vm = new Loading({ 9 el: document.createElement('div') 10 }) 11 document.body.appendChild($vm.$el) 12 const loading = { 13 show (options) { 14 if ($vm.show) { 15 return 16 } 17 $vm.text = $vm.$options.props.text.default 18 if (typeof options === 'string') { 19 $vm.text = options 20 } 21 $vm.show = true 22 }, 23 hide () { 24 $vm.show = false 25 }, 26 isVisible () { 27 return $vm.show 28 } 29 } 30 if (!Vue.loading) { 31 Vue.loading = loading 32 } 33 Vue.mixin({ 34 created: function () { 35 this.$loading = Vue.loading 36 } 37 }) 38 } 39 40 export default plugin
Vue.use() 挂载