this.$toast() 了解一下?


Posted in Javascript onApril 18, 2019

前言

在平时的开发过程中,我们总是先写好一个组件,然后在需要的页面中用 import 引入即可,但如果是下面这种类型的组件呢?

this.$toast() 了解一下?

上面这种类型的浮层提示有一个很大的特点,就是使用频率特别高,几乎每个页面都会用到它,于是乎我们就要在每个页面中去引入该组件,并且在每个页面都得通过一个变量来控制它的显隐,这显然不是我们想要的?。。。那我们想要的是什么样呢??用过一些 UI 框架的同学们应该知道有这样一种用法:

this.$toast({
 duration: 3000,
 content: '这是一条消息提示'
});

没错,就是这么简单的一句话就万事大吉了(就是用 js 调用组件而已啦?)。那这种效果究竟是怎么实现的呢?今天就让我们来(手把手? )一探究竟吧!

前置知识

不知道小伙伴们有没有用过 Vue.extend() 这个东东,反正我是很少碰过,印象不深,所以这里我们先来短暂了解一下 Vue.extend() 主要是用来干嘛的。先来个官方说明(不多的,坚持下):

this.$toast() 了解一下?

没怎么看懂??没关系,不重要,你只要记住(加少许理解)以下用法即可:

// 导入以往的普通组件
import Main from './main.vue';
// 用 Vue.extend 创建组件的模板(构造函数)
let mainConstructor = Vue.extend(Main);
// 实例化组件
let instance = new mainConstructor();
// 挂载到相应的元素上
instance.$mount('#app');

 不知道你看懂没有,上面的 Vue.extend(Main) 就是一个基于 main.vue 的组件模板(构造函数),instance 是实例化的组件,$mount() 是手动挂载的意思。其中 Vue.extend() 和 $mount() 就是我们通过 js 调用、渲染并挂载组件的精髓所在,相当于早前的 createElement 和 appendChild,有异曲同工之效。这个点需要我们好好熟悉一下,所以你可以先停下来屡屡思路?。

补充一下?:$mount() 里面如果没有参数,说明组件只是渲染了但还没有挂载到页面上,如果有正确的(元素)参数则直接挂载到元素下面。

写一个 toast 组件

js 调用归调用,最原始的组件还是要有的,只是我们不通过 import 来引入到页面中而已。ok,我们就以最开始的那个 toast 图片来简单写一下这个 vue 组件(message 和 alert 也是一样的)。这里就直接上代码啦,毕竟它的结构简单到爆了,也不是本章节的重点:

<!-- main.vue -->
<template>
 <div class="toast">
 <p>服务器错误,请稍后重试</p>
 </div>
</template>
<script>
export default {
 name: "Toast",
 mounted() {
 setTimeout(() => {
  // 3s 后通过父级移除子元素的方式来移除该组件
  this.$el.parentNode.removeChild(this.$el);
 }, 3000);
 }
};
</script>
<style lang="scss" scoped>
.toast {
 display: flex;
 align-items: center;
 justify-content: center;
 position: fixed;
 top: 0;
 bottom: 0;
 left: 0;
 right: 0;
 color: #fff;
 z-index: 9999;
 background: transparent;
 > p {
 padding: 12px 22px;
 font-size: 18px;
 border-radius: 4px;
 background: rgba(17, 17, 17, 0.7);
 }
}
</style>

上面的内容想必大家应该都能看懂,所以这里就直接讲下面的重点了。

写一个 main.js

我们在 main.vue 的同级目录下新建一个 main.js 文件。我们先瞟一眼文件内容(也不多,已经是个最简版了)?:

// main.js
import Vue from "vue"; // 引入 Vue 是因为要用到 Vue.extend() 这个方法
import Main from "./main.vue"; // 引入刚才的 toast 组件

let ToastConstructor = Vue.extend(Main); // 这个在前面的前置知识内容里面有讲到
let instance;

const Toast = function() {
 instance = new ToastConstructor().$mount(); // 渲染组件
 document.body.appendChild(instance.$el); // 挂载到 body 下
};

export default Toast;

。

上面的代码暴露了一个 Toast 函数。为什么要暴露一个函数呢?原因很简单:你想想,我们最终是不是要根据 this.$toast() 来调用一个组件,说白了,通过 js 调用,本质就是调用一个 函数。也就是说 this.$toast() 就是执行了上面代码中导出的 export default Toast,也就是执行了 Toast 函数(const Toast = function() {}),所以当我们调用 this.$toast() 的时候其实就是执行了 Toast() 函数。而 Toast() 函数只做了一件事情:就是通过手动挂载的方式把组件挂载到 body 下面。

补充一下?:一般来说我们常见的是 $mount("#app"),也就是把组件挂载到 #app 下面,<router-view /> 也包含在 #app 中,但是我们这种 toast 提示是放在 body 下面的,也就是说它不受 #app 和 <router-view /> 的管控,所以当我们切换页面(路由)的时候,这个 toast 组件是不会跟着立马消失的,这点要注意哦?。

这里顺便给个组件的目录结构,如下图所示:

this.$toast() 了解一下?

开始调用

调用方式很简单,首先我们在入口文件 main.js(和上面不是同一个?) 里加上两行代码,这样我们就能在需要的地方直接用 js 调用它了,如下图所示:

this.$toast() 了解一下?

然后在页面中测试一下,就像下面这样子:

this.$toast() 了解一下?

运行一下代码:

 this.$toast() 了解一下?

嗯,挺好,小有成就的 feel ???。

支持可传参数

别急,我们好像还漏了点什么?。。。对了,现在还不支持传参呢,直接调用 this.$toast() 就只能显示————服务器错误,请稍后重试(这下全都是后端的锅了?)。但我们可是个有追求的前端,不能局限于此,所以现在让我们来尝试增加下两个可配置参数,这里拿 duration 和 content 举个栗子?。

首先我们要修改 main.vue 组件里面的内容(其实没啥大变化),就像下面这样:

<!-- main.vue 可配置版 -->
<template>
 <div class="toast">
 <p>{{ content }}</p>
 </div>
</template>

<script>
// 主要就改了 data
export default {
 name: "Toast",
 data() {
 return {
  content: "",
  duration: 3000
 };
 },
 mounted() {
 setTimeout(() => {
  this.$el.parentNode.removeChild(this.$el);
 }, this.duration);
 }
};
</script>

上面的代码应该算是浅显易懂了,接下来我们看下 main.js 里面改了啥:

// main.js 可配置版
import Vue from "vue";
import Main from "./main.vue";

let ToastConstructor = Vue.extend(Main);

let instance;

const Toast = function(options = {}) { // 就改了这里,加了个 options 参数
 instance = new ToastConstructor({
 data: options // 这里的 data 会传到 main.vue 组件中的 data 中,当然也可以写在 props 里
 });
 document.body.appendChild(instance.$mount().$el);
};

export default Toast;

其实 main.js 也没多大变化,就是在函数里面加了个参数。要注意的是 new ToastConstructor({ data: options }) 中的 data 就是 main.vue 组件中的 data,不是随随便便取的字段名,传入的 options 会和组件中的 data 合并(Vue 的功劳)。
em。。。是的,就这么简单,现在让我们继续来调用一下它:

<script>
export default {
 methods: {
 showToast() {
  this.$toast({
  content: "哈哈哈哈,消失的贼快",
  duration: 500
  });
 }
 }
};
</script>

运行一下就可以看到:

this.$toast() 了解一下?

当然,这还没完,我们继续添加个小功能点?。。。

支持 this.$toast.error()

这里我们打算支持 this.$toast.error() 和 this.$toast.success() 这两种方式,所以我们第一步还是要先去修改一下 main.vue 文件的内容(主要就是根据 type 值来修改组件的样式),就像下面这样:

<!--main.vue-->
<template>
 <div class="toast" :class="type ? `toast--${type}` : ''">
  <p>{{ content }}</p>
 </div>
</template>
<script>
export default {
 ...
 data() {
  return {
   type: "",
   content: "",
   duration: 3000
  };
 },
 ...
};
</script>
<style lang="scss" scoped>
.toast {
 ...
 &--error p { background: rgba(255, 0, 0, 0.5); }
 &--success p { background: rgba(0, 255, 0, 0.5); }
}
</style>

其次,this.$toast.error() 其实就等价于 Toast.error(),所以我们现在的目的就是要给 Toast 函数扩充方法,也比较简单,就先看代码再解释吧:

// main.js
const Toast = function(options = {}) {
 ...
};
// 以下就是在 Toast 函数中拓展 ["success", "error"] 这两个方法
["success", "error"].forEach(type => {
 Toast[type] = options => {
  options.type = type;
  return Toast(options);
 };
});
export default Toast;

我们可以看到 Toast.error() 和 Toast.success() 最终还是调用 Toast(options) 这个函数,只不过在调用之前需要多做一步处理,就是将 ["success", "error"] 作为一个 type 参数给合并进 options 里面再传递,仅此而已?。
那就试试效果吧:

<script>
export default {
 methods: {
  showToast() {
   this.$toast({ content: "这是正常的" });
  },
  showErrorToast() {
   this.$toast.error({ content: "竟然失败了" });
  },
  showSuccessToast() {
   this.$toast.success({ content: "居然成功了" });
  }
 }
};
</script>

this.$toast() 了解一下?

大赞无疆,大。赞。。无。。。疆。。。。。?

结语

至此,一个通过 js 调用的简单 toast 组件就搞定啦,短短的几行代码还是挺考验 js 功底的?。当然这只是个超简易版的 demo,显然不够完善和健壮,所以我们可以在此基础上扩充一下,比如当 duration <= 0 的时候,我们让这个 toast 一直显示,然后扩展一个 close 方法来关闭等等之类的。不过还是那句老话,实践才是检验真理的唯一标准。纸上得来终觉浅,绝知此事要躬行。step by step, day day up !  ? ? ?

 以上所述是小编给大家介绍的vue this.$toast()用法详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery实现table鼠标经过变色代码
Sep 25 Javascript
HTTP 304错误的详细讲解
Nov 13 Javascript
JQuery Highcharts 动态生成图表的方法
Nov 15 Javascript
jQuery获取动态生成的元素示例
Jun 15 Javascript
jQuery插件PageSlide实现左右侧栏导航菜单
Apr 12 Javascript
javascript鼠标滑动评分控件完整实例
May 13 Javascript
用js动态添加html元素,以及属性的简单实例
Jul 19 Javascript
Three.js学习之网格
Aug 10 Javascript
Javascript日期格式化format函数的使用方法
Aug 30 Javascript
bootstrap fileinput 上传插件的基础使用
Feb 17 Javascript
javascript编程实现栈的方法详解【经典数据结构】
Apr 11 Javascript
Angular弹出模态框的两种方式
Oct 19 Javascript
Vue-input框checkbox强制刷新问题
Apr 18 #Javascript
vue axios封装及API统一管理的方法
Apr 18 #Javascript
Vue组件系列开发之模态框
Apr 18 #Javascript
详解vue的数据劫持以及操作数组的坑
Apr 18 #Javascript
微信小程序 setData 对 data数据影响问题
Apr 18 #Javascript
详解JavaScript中关于this指向的4种情况
Apr 18 #Javascript
vue.js高德地图实现热点图代码实例
Apr 18 #Javascript
You might like
用PHP实现的生成静态HTML速度快类库
2007/03/31 PHP
php adodb介绍
2009/03/19 PHP
了解Joomla 这款来自国外的php网站管理系统
2010/03/11 PHP
php判断电脑访问、手机访问的例子
2014/05/10 PHP
常用PHP数组排序函数归纳
2016/08/08 PHP
解决Laravel自定义类引入和命名空间的问题
2019/10/15 PHP
小议Function.apply() 之一------(函数的劫持与对象的复制)
2006/11/30 Javascript
JavaScript脚本性能的优化方法
2007/02/02 Javascript
JavaScript 常见对象类创建代码与优缺点分析
2009/12/07 Javascript
封装的原生javascript弹出层代码
2010/09/24 Javascript
基于jquery实现的可以编辑选择的下拉框的代码
2010/11/19 Javascript
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
jQuery form插件之formDdata参数校验表单及验证后提交
2016/01/23 Javascript
JavaScript中的跨浏览器事件操作的基本方法整理
2016/05/20 Javascript
JS判断非空至少输入两个字符的简单实现方法
2017/06/23 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
JavaScript中BOM对象原理与用法分析
2019/07/09 Javascript
[02:51]2014DOTA2 TI小组赛总结中国军团全部进军钥匙球馆
2014/07/15 DOTA
python3简单实现微信爬虫
2015/04/09 Python
python中dir函数用法分析
2015/04/17 Python
python保存网页图片到本地的方法
2018/07/24 Python
Python递归函数特点及原理解析
2020/03/04 Python
python实现梯度下降法
2020/03/24 Python
SkinCeuticals官网:美国药妆品牌
2018/04/19 全球购物
美国林业供应商:Forestry Suppliers
2019/05/01 全球购物
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
爱祖国演讲稿
2014/05/04 职场文书
党员一帮一活动总结
2014/07/08 职场文书
领导班子四风对照检查材料思想汇报
2014/09/26 职场文书
环境工程专业毕业生求职信
2014/09/30 职场文书
基于HTML十秒做出淘宝页面
2021/10/24 HTML / CSS
nginx从安装到配置详细说明(安装,安全配置,防盗链,动静分离,配置 HTTPS,性能优化)
2022/02/12 Servers
Pandas实现DataFrame的简单运算、统计与排序
2022/03/31 Python
Ubuntu安装Mysql+启用远程连接的完整过程
2022/06/21 Servers