<button class="btn"><slot>按钮</slot></button>(2)默认导出一个组件名,值为“my-button”
export default{ name:'my-button' }(3)给模板中的按钮设置样式
.btn{ padding: 3px 15px; border: 0 none; outline: none; background-color: #FF0000; font-size:14px; color: #FFFFFF; }View Code 2、在src》components》my-button》创建文件index.js(用来存放my-button插件)》 (1)导入my-button组件
import MyButton from "./button"(2)在默认导出的方法中,全局注册导入的组件。
export default{ install(Vue){ Vue.component("my-button",MyButton); } }3、在src》App.vue》 (1)导入Vue组件
import Vue from "vue"(2)导入插件
import MyButton from "./components/my-button"(3)启用插件
Vue.use(MyButton);(4)在模板中引用插件
<my-button @click="submit()">提交</my-button>【npm run serve】 4、在src》components》my-button》button.vue》 (1)在模板中,给button按钮添加click事件。
@click="handleClick()"(2)在click事件的处理函数中,传递一个click事件的别名(click)给父组件:this.$emit("click")。
methods:{ handleClick(){ this.$emit("click") }5、在src》App.vue》 (1)在模板中,给插件设置(别名)事件。
<my-button @click="submit()">提交</my-button>(2)在methods对象中,在(别名)事件的处理函数中,做逻辑》 调用Vue实例的toast方法(该方法是在后续插件中定义的),传入一个对象(自己模拟数据创建出来的对象)。 { message:"请输入姓名", duration:3000, onClose:()=>{ console.log("已关闭"); } }
methods:{ submit(){ this.$toast({ //出现this.$XXX的形式,说明XXX是挂载在原型链上的一个自定义方法或者自定义属性。 message:"请输入姓名",//出现的属性,说明自定义方法会把它赋值给vm实例对应的属性中 duration:3000, onClose:()=>{ //出现这种方法,说明自定义方法XXX需要设置一个时间延迟函数,来调用这个方法。 console.log("已关闭"); } }) } }【npm run serve】 -------------------------------------------------------------------------------------------------- 总结:toast插件的开发, 1、在App.vue中,(在某个事件处理函数中)调用一个(后续在toast插件会自定义的)vue实例方法, 并且给该实例方法传递一个对象字面量(模拟多组自己想要的key和value)。 2、在toast插件中,在Vue的原型链上创建一个自定义方法(供App.vue调用)。 3、在toast插件中,手动创建标签挂载到vue组件上,创建出vue组件实例vm。 4、把创建的标签,追加到页面上。 5、在自定义方法中,把调用这个方法时传进来的参数对象,一一赋值给实例vm对应属性上。 6、设置时间延迟函数,在回调函数中,把创建的标签,从页面上删除。 -------------------------------------------------------------------------------------------------- 1、在src》components》创建文件夹my-toast(用来存放组件和插件)》创建文件toast.vue(用来存放组件)》 (1)在模板中,创建标签元素
<div class="toast-wrap"></div>(2)默认导出一个组件名,值为“my-toast“
export default{ name:'my-toast' }(3)设置标签样式
.toast-wrap{ padding: 8px 15px; background-color: rgba(0,0,0,0.8); font-size: 14px; color:#FFFFFF; text-align: center; position: fixed; z-index: 99; left:50%; top:50%; transform: translate(-50%,-50%); border-radius: 5px; }View Code 【在src》App.vue》注册组件,引用组件,npm run serve 测试组件是否有效。】 2、在src》components》my-toast》创建文件index.js(用来存放插件)》 (1)导入my-toast组件
import MyToast from "./toast"(2)在默认导出的方法中,全局extend导入的组件:let VueComp = Vue.extend(MyToast);
export default { install(Vue) { let VueComp = Vue.extend(MyToast); //(3)... } }/*ƒ VueComponent (options) { //返回一个组件对象的初始化方法或构造方法。 this._init(options); }*/
Vue.prototype.$toast = function (opts) { //4(1)(2)... }3、在src》App.vue》 (1)导入Vue组件 (2)导入插件 (3)启用插件 (4)在模板中引用插件 【npm run serve,点击按钮,查看控制台是否打印出自己的模拟数据】 4、在src》components》my-toast》index.js》 (1)在toast方法中,动态创建一个标签元素挂载到组件实例上:let vm = new VueComp().$mount(document.createElement("div"));
let vm = new VueComp().$mount(document.createElement("div"));//创建一个标签元素挂载组件。 console.log(vm);(2)在toast方法中,把创建的标签,追加到页面上:document.body.appendChild(vm.$el);
document.body.appendChild(vm.$el);【npm run serve,点击按钮,出现提示框】 5、在src》components》my-toast》toast.vue》 (1)在模板中做动态数据:{{message}}
<div class="toast-wrap">{{message}}</div>(2)在data数据对象中,添加:message:""
data(){ return{ message:"" } }【npm run serve,点击按钮,出现空白提示框】 /*VueComponent {_uid: 7, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …} vm.message:""*/ 6、在src》components》my-toast》index.js》 (1)在toast方法中,把参数opts对象里面的属性值赋值给组件实例vm:
vm.message=opts.message; let duration=opts.duration||2000; setTimeout(()=>{ document.body.removeChild(vm.$el); if(opts.onClose){ opts.onClose(); } },duration)(2)解决重复点击出现提示框问题:
let isToast=false; if(!isToast){ isToast=true; //... isToast=false; }src》components》my-toast》toast.vue》代码 View Code src》components》my-toast》index.js》代码
import MyToast from "./toast" //2(1) export default { install(Vue) { let VueComp = Vue.extend(MyToast); //2(2) let isToast=false; //6(2) Vue.prototype.$toast = function (opts) { //2(3)供App.vue调用 if(!isToast){ //6(2) isToast=true; //6(2) console.log(opts); let vm = new VueComp().$mount(document.createElement("div"));//4(1)创建出vue组件实例vm console.log(vm); document.body.appendChild(vm.$el);//4(2)把创建的标签,追加到页面上 vm.message=opts.message;//6(1)赋值给实例vm对应属性 let duration=opts.duration||2000; setTimeout(()=>{ //设置时间延迟函数 isToast=false; //6(2) document.body.removeChild(vm.$el);//把创建的标签,从页面上删除。 if(opts.onClose){ opts.onClose(); } },duration) } } } }