vue使用Vue.extend创建全局toast组件实例

目录
  • Vue.extend创建全局toast组件
  • 关于vue.extend的理解应用
    • 基本概念
    • 官网基本示例
    • 应用
  • 总结

Vue.extend创建全局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)

关于vue.extend的理解应用

基本概念

Vue.extend( options )

使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

一般,我们会用 Vue.extend 接收一个组件对象来创建一个构造器,再利用创建的构造器 new 一个实例,并将这个实例挂载到一个元素上。

官网基本示例

<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')

data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数

结果如下:

<p>Walter White aka Heisenberg</p>

应用

Vue.extend 属于 Vue 的全局 API,在实际业务开发中我们很少使用,因为相比常用的 Vue.component 写法使用 extend 步骤要更加繁琐一些。

但是在一些独立组件开发场景中,例如要实现一个类似于 window.alert() 提示组件,要求像调用 JS 函数一样调用它,这时候 Vue.extend + $mount 这对组合就是我们需要去关注的。

1、vue $mount 和 el的区别说明

在应用之前我们先了解一下2个东西 —— $mount 和 el,两者在使用效果上没有任何区别,都是为了将实例化后的vue挂载到指定的dom元素中。

如果在实例化vue的时候指定el,则该vue将会渲染在此el对应的dom中,反之,若没有指定el,则vue实例会处于一种“未挂载”的状态,此时可以通过$mount来手动执行挂载。

注:如果$mount没有提供参数,模板将被渲染为文档之外的的元素,并且你必须使用原生DOM API把它插入文档中。

var MyComponent = Vue.extend({
 template: '<div>Hello!</div>'
})
 
// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')
 
// 同上
new MyComponent({ el: '#app' })
 
// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

2、Vue.extend实现Loading插件($mount)

<div id="root">
    <button @click="showLoading">显示Loading</button>
</div>
function Loading(msg) {
        // 创建构造器
        const Loading = Vue.extend({
          template: '<div id="loading-msg">{{ msg }}</div>',
          props: {
            msg: {
              type: String,
              default: '加载中'
            }
          },
          name: 'Loading'
        })
 
        // 创建挂载div
        const div = document.createElement('div')
        div.setAttribute('id', 'loading-div')
        document.body.append(div)
 
        // 创建实例并挂载到一个元素上
        new Loading().$mount('#loading-div')
 
        // 返回一个移除元素的function
        return () => {
          document.body.removeChild(document.getElementById('loading-div'))
        }
}
 
// 挂载到vue实例上
Vue.prototype.$loading = Loading
 
 new Vue({
     el: '#root',
     methods: {
        showLoading() {
            const hide = this.$loading('正在加载,请稍等...')
            setTimeout(() => {
              hide()
            }, 1500)
        }
     }
})

3、Vue.extend实现信息弹窗插件(el)

新建一个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:'标题',
          msg: '这是一个信息弹出框组件',
          btn: {
              ok: '确定',
              no: '取消'
          }
      }
    }
  },
 
  methods: {
    show (){
      this.flag = false;
    },
 
    hide() {
      this.flag = false;
    }
  }
}
 
</script>

新建一个popBox.js

import Vue from 'vue'
import PopBox from './popBox.vue'
 
// Vue.extend返回一个实例创建的构造器,但实例构造器需要进行挂载到页面中
let popBox = Vue.extend(PopBox)   
 
popBox.install = (vue, text) => {
      
        // 在body中动态创建一个div元素,之后此div将会替换成整个vue文件的内容
        // 此时的popBoxDom通俗讲就是相当于是整个组件对象,通过对象调用属性的方法来进行组件中数据的使用
        let popBoxDom = new popBox({
            el: document.createElement('div')
        })
 
        
        // 可以通过$el属性来访问创建的组件实例
        document.body.appendChild(popBoxDom.$el)
 
   
        // 将需要传入的文本内容传给组件实例
        popBoxDom.text = text;
 
        // 返回一个promise,进行异步操作,成功时返回,失败时返回
        return new Promise((res, rej) => {     
            popBoxDom.show = () => {   
                res()   //正确时返回的操作
                popBoxDom.flag = false;
            }
 
            popBoxDom.hide = ()=>{
                rej()   //失败时返回的操作
                popBoxDom.flag = false;
            }
        }
 
        vue.prototype.$popBox = popBox    
    })
}
 
// 将逻辑函数进行导出和暴露
export default popBox

页面使用

import PopBox from './popBox.js'
 
Vue.use(popBOx);
 
 
this.$popBox({
      title:'标题',
      msg:'内容',
      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;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 用Vue.extend构建消息提示组件的方法实例

    前提 前段时间自己做的vue练手项目,需要一个通用的消息提示组件,但是消息提示这种组件我更想用方法来调用,而不是在各个页面上都添加个组件(那样感觉很麻烦,重度懒癌患者),于是就上网差查了查,并研究了ElementUI的message源码.自己弄出来一个简陋的消息提示组件 Vue.extend是什么 按照官方文档说法,他是一个类构造器,用来创建一个子类vue并返回构造函数,而Vue.component它的任务是将给定的构造函数与字符串ID相关联,以便Vue.js可以在模板中接收它. 了解了这点之后

  • Vue组件教程之Toast(Vue.extend 方式)详解

    一.效果图 二.说明 这类提示框组件我们通常都会直接在 JS 代码中进行调用.像下面这样: this.$toast('别点啦,到头啦!') 但看到网上大多数还是通过 component 方式实现的,这样的话我们在使用的时候还要在 DOM 中放置一个组件元素,然后通过一个变量来控制它的显示隐藏,这样使用起来非常的不方便.那么有什么方法可以不用在 DOM 中手动放置组件元素就可以直接调用呢?答案就是 Vue.extend.通过 Vue.extend 方式实现的组件,需要两个文件,一个是 .vue 文

  • 手把手教你写一个vue全局注册的Toast的实现

    目录 前言: 我们先思考下面的问题: 首先: 然后: 后来: 再且: 前言: 前几天客户经理不让我用某饿了么之类的UI库做一个轻提示之类的组件,当时一想我是饿了么战士,怎么会写哪个东西,然后我就想着用个alert糊弄过去,但是不行,然后我就细琢磨,发现Vue有个非常不错的Vue.extend. 经过一番努力,我学会了,可能是以前学的时候马虎漏掉了.不过问题不大,还能肝. 我们先思考下面的问题: 在写vue项目的时候啊,我们有了初始化的根实例之后,页面之间都是通过router进行管理,组件也是通过

  • vue使用Vue.extend创建全局toast组件实例

    目录 Vue.extend创建全局toast组件 关于vue.extend的理解应用 基本概念 官网基本示例 应用 总结 Vue.extend创建全局toast组件 src -> components -> Toast -> toast.vue <template>   <transition name="fades">     <div class="Errormes"  v-if="show"&

  • Vue封装全局toast组件的完整实例

    目录 前言 一. 借助 vue-cli 1. 定义 Toast 组件 2. 在 main.js 里面配置 3. 在其他组件内使用 二.不借助 vue-cli 1. 注册 toast 组件 2. 注册 toast 插件 3. 在其他组件内使用 总结 前言 最近体验了下Vue,Toast都是前端常用组件,本文详细介绍了Vue封装全局toast组件的过程,下面话不多说了,来一起看看详细的介绍吧 一. 借助 vue-cli 1. 定义 Toast 组件 // components/Toast <temp

  • Vue的事件响应式进度条组件实例详解

    写在前面 找了很多vue进度条组件,都不包含拖拽和点击事件,input range倒是原生包含input和change事件,但是直接基于input range做进度条的话,样式部分需要做大量调整和兼容性处理.即使做好了,将来需要修改外观,又是一番折腾. 基于以上两个原因,做了一个可以响应input和change事件(即一个是拖动进度条到某处,一个是在进度条某位置点击使其值变为该位置)的div实现的Vue组件,这样既满足了对进度条事件的需求,也带来了如有需求变动,样式修改很方便的好处. 效果图 以

  • Vue 全局loading组件实例详解

    上图不上种,菊花万人捅: loading.js: import './loading.css' let Loading = {} // 避免重复install,设立flag Loading.installed = false Loading.install = function (Vue) { if (Loading.installed) return Vue.prototype.$loading = {} Vue.prototype.$loading.show = () => { // 如果页

  • vue自定义指令的创建和使用方法实例分析

    本文实例讲述了vue自定义指令的创建和使用方法.分享给大家供大家参考,具体如下: 一.自定义指令的创建和使用 Vue自带的指令很多,v-for/v-if/v-else/v-else-if/v-model/v-bind/v-on/v-show/v-html/v-text... 但是这些指令都是比较偏向于工具化,有些时候在实现具体的业务逻辑的时候,发现不够用,如何来自定义指令. 1.自定义指令 ① 创建 new Vue({ directives:{ change:{ bind:function(){

  • 基于vue与element实现创建试卷相关功能(实例代码)

    由于最近在一个项目中需要实现创建试卷与预览试卷的功能,所以就自己动手写了一个,效果还不错,目前项目已经交付使用,今天就先和大家分享一下创建试卷. 创建试卷 先放一下效果图 首先是试卷的相关设置 考试对象是通过接口返回的数据 <span class="content-label">选择考试对象</span> <el-form-item prop="roleList"> <el-select v-model="form

  • Angularjs 创建可复用组件实例代码

    AngularJS框架可以用Service和Directive降低开发复杂性.这个特性非常适合用于分离代码,创建可测试组件,然后将它们变成可重用组件. Directive是一组独立的JavaScript.HTML和CSS,它们封装了一个特定的行为,它将成为将来创建的Web组件的组成部分,我们可以在各种应用中重用这些组件.在创建之后,我们可以直接通过一个HTML标签.自定义属性或CSS类.甚至可以是HTML注释,来执行一个Directive. 这一篇教程将介绍如何创建一个'自定义步长选择' Dir

  • vue.js实现仿原生ios时间选择组件实例代码

    前言 最近几个月一直在看VUE,然后试着只用原生js+vue实现某些组件. PC端时间选择组件 这是最开始实现的pc上的时间选择,平时移动端也在做,所以就想实现一下移动端的时间选择器,下面分享一下我实现移动端滚轮特效时间选择器的思路和过程.整个组件是基于vue-cli来进行构建的 功能 1.时间选择[ A.年月日选择 B.年月日小时分钟选择 C.小时分钟选择 D.分钟选择] 2.滚轮效果[ A.构成一个圆环首尾相连 B.不构成首尾相连] 3.时间选择范围设置(所选时间超过范围将弹窗提示),分钟间

  • 解决vant的Toast组件时提示not defined的问题

    按照官方文档引入全局Toast组件,在methods里面定义函数执行函数时产生了报错: //定义的函数 handleClick(){ Toast('点击提示') } 报错信息 [Vue warn]: Error in v-on handler: "ReferenceError: Toast is not defined" 解决方法: handleClick(){ this.$toast('点击提示') } 补充知识:vue+vant移动端遇到的那些问题 1.项目引用了lib-flexi

  • Vue 实现创建全局组件,并且使用Vue.use() 载入方式

    自定义vue组件,一般是局部引用的方式载入,使用的时候,在应用的组件中使用 import moduleName from 'module' 导入,在components中注册 <template> <div class="app-NewsInfo"> <h3>{{info.title}}</h3> <!-- 新闻评论子组件. --> <comment :id="id"></comment&

随机推荐