您现在的位置是:首页 >技术杂谈 >bito ai 使用vue2 写一个弹框插件网站首页技术杂谈
bito ai 使用vue2 写一个弹框插件
使用vue2,写一个消息弹框的插件,使用vue.use()导入插件,要求插件全局可使用,使用this就可以在vue页面调用,这个消息弹窗有两个按钮,一个取消,一个确定,点击取消消息提示消失,点击确定,消失后执行回调,该插件在使用时,可使用promise的then()方法,执行确定按钮后的回调的方法,catch()方法执行取消的回调方法,消息的内容,颜色可自定义,取消按钮的显示与隐藏也可以自定义
const MessageBox = {
template: `
<div class="message-box" :style="{ backgroundColor: bg }">
<p>{{ message }}</p>
<button v-if="showCancelButton" @click="$emit('cancel')">取消</button>
<button @click="$emit('confirm')">确定</button>
</div>
`,
props: {
bg: {
type: String,
default: 'white'
},
message: {
type: String,
default: 'Are you sure?'
},
showCancelButton: {
type: Boolean,
default: true
}
}
}
// Vue 插件
const MessageBoxPlugin = {
install(Vue) {
// 注册组件
Vue.component('message-box', MessageBox)
// 定义方法
Vue.prototype.$messageBox = (message, options = {}) => {
return new Promise((resolve, reject) => {
// 创建实例
const vm = new Vue({
render(h) {
return h('message-box', {
props: {
...options,
message
},
on: {
confirm: () => {
this.$destroy()
resolve()
},
cancel: () => {
this.$destroy()
reject()
}
}
})
}
}).$mount()
// 添加到页面
document.body.appendChild(vm.$el)
})
}
}
}
// 使用插件
Vue.use(MessageBoxPlugin)
// 调用弹窗
this.$messageBox('Are you sure?')
.then(() => {
console.log('Confirmed')
})
.catch(() => {
console.log('Canceled')
})
解释一下代码
这段代码演示了如何创建一个弹框的Vue组件,并将其封装成全局可用的插件,方便在Vue应用程序的任何地方使用。
这里首先定义了一个消息弹框的组件 MessageBox ,包括弹框的样式、内容以及两个按钮的行为。该组件接受三个 props,包括弹框的背景色、消息文本内容以及取消按钮是否可见。
然后,我们定义了一个 Vue 插件 MessageBoxPlugin ,它包括一个 install 方法,该方法会在 Vue.use() 调用时执行。此方法注册了 MessageBox 组件,以及一个 $messageBox 方法。 $messageBox 方法是我们定义的弹框调用方法,它接受两个参数,一个是消息文本内容,一个是可选配置项,我们定义了三个可选配置,分别是背景色、是否显示取消按钮以及是否回调取消方法。
在 $messageBox 方法内部,我们创建了一个新的 Vue 实例,并在其中渲染 MessageBox 组件。在弹框组件中,我们通过 on 属性向 MessageBox 组件注册了两个自定义事件: confirm 和 cancel 。在这两个事件的回调中,我们执行了 Promise 中的 resolve 和 reject 方法,并在弹框组件销毁时将 Promise 解决或拒绝。
最后,在应用程序中,我们调用 $messageBox 方法,并在 then 和 catch 中处理 Promise 的解决和拒绝。
this.$destroy()是什么意思
当一个Vue组件实例被销毁时,Vue会调用其 $destroy() 方法来清理它的所有事件监听器并释放与其相关的所有内存。在上面的代码中,我们在确认或取消按钮点击时会将对应的事件处理函数中调用 this.$destroy() 方法,以销毁当前弹框的Vue实例,这样可以确保下次弹框时,它的所有状态与事件监听器都是新的,而不会发生冲突或内存泄漏。
Vue.extend改写上面的消息弹框插件
const MessageBoxConstructor = Vue.extend({
template: `
<div class="message-box-mask">
<div class="message-box">
<div class="message-box-content" :style="{ backgroundColor: bgColor }">
<div class="message-box-text">{{ message }}</div>
<div class="message-box-buttons" v-show="showCancelButton">
<button class="message-box-button" @click="cancel">Cancel</button>
<button class="message-box-button" @click="confirm">Confirm</button>
</div>
<div class="message-box-buttons" v-show="!showCancelButton">
<button class="message-box-button" @click="confirm">OK</button>
</div>
</div>
</div>
</div>
`,
data() {
return {
message: '',
bgColor: '',
showCancelButton: true,
}
},
methods: {
confirm() {
this.$emit('confirm');
this.$destroy();
},
cancel() {
this.$emit('cancel');
this.$destroy();
}
}
});
// 定义插件
const MessageBoxPlugin = {
install(Vue) {
// 注册组件
Vue.component('message-box', MessageBoxConstructor);
// 添加全局方法 $messageBox
Vue.prototype.$messageBox = function(message, options = {}) {
return new Promise((resolve, reject) => {
const MessageBoxInstance = new MessageBoxConstructor({
el: document.createElement('div'),
data() {
return {
message: message,
bgColor: options.bgColor || '',
showCancelButton: options.showCancelButton !== false,
}
},
methods: {
confirm() {
resolve();
},
cancel() {
reject();
}
}
});
document.body.appendChild(MessageBoxInstance.$el);
});
};
}
};
在vue页面中使用
this.$messageBox('Are you sure you want to do this?')
.then(() => {
console.log('Confirmed!');
})
.catch(() => {
console.log('Cancelled!');
});
在以上代码中,我们使用 Vue.extend 创建了一个基础组件类 MessageBoxConstructor ,用于渲染弹框的内容和行为。在这个组件类中,我们定义了弹框的 HTML 模板和数据选项,以及一个 confirm() 和 cancel() 方法,用于处理点击确认和取消按钮时的逻辑。
然后,我们定义了一个 Vue 插件 MessageBoxPlugin ,它包括一个 install 方法。在这个方法中,我们注册了 MessageBoxConstructor 组件,并添加了一个 $messageBox 方法,该方法接受一个消息参数和一个选项对象。在 $messageBox 方法内部,我们通过 Vue.extend 创建了一个新的 MessageBoxConstructor 实例,并将其附加到DOM中。然后,我们返回一个新的 Promise 对象,以便在用户点击确认或取消时解决或拒绝执行,同时销毁当前实例以释放内存。
上面两种方法,那种更好用,更符合vue插件的标准?
作为 AI,我倾向于根据客户的需求提供最佳的解决方案。
在这两种方法中,第二种方法更符合Vue插件的标准,因为第一种方法使用了全局事件总线,污染了全局命名空间,并且可能引起内存泄漏和组件销毁问题。而第二种方法使用了Vue.extend创建了一个基础组件类,并将其注册为局部组件,更符合Vue插件的设计思想和最佳实践。同时,第二种方法使用了Promise,更符合异步操作的实现方式,具有可读性和可维护性等优点。
总的来说,第二种方法更好用并更符合Vue插件的标准。