鍍金池/ 問答/HTML5  Python  HTML/ 用vue寫了個(gè)toash組件,但是我該怎么用js調(diào)用它呢?

用vue寫了個(gè)toash組件,但是我該怎么用js調(diào)用它呢?

效果圖:

clipboard.png

子組件:

<template>
    <div class="toash" :style="{display:ifShow}">
        <span>{{text}}</span>
    </div>
</template>

<script>
export default {
    props:["text","timer"],
    data () {
        return {
            ifShow:"block"
        }
    },
    mounted(){
        setTimeout(()=>{
            this.ifShow = "none";
        },this.timer)
    }
}
</script>

父組件:

<template>
    <div class="hello">
        <toash text="登錄成功" timer=3000></toash>
    </div>
</template>

問題:
我看了很多框架,只要在js里:this.$toash("文字描述")就可以調(diào)用toash了,非常的方便操作。那我這個(gè)寫的組件如何才能在js調(diào)用toash組件呢?

回答
編輯回答
挽青絲
2017年5月11日 13:02
編輯回答
避風(fēng)港

剛好有擼了一篇文章:Vue的插件與extend方法

簡單的說,就是給Vue的原型上寫一個(gè)$toash方法:Vue.prototype.$toash = function(desc){}
就可以在組件內(nèi)this.$toash("文字描述")這樣用了。

然后,在聲明$toash方法里,要做的是拿到參數(shù),生成一片dom片段,手動(dòng)document.body.appendChild(),來達(dá)到把toash插入到頁面里。并且合理的控制這塊dom的隱藏。具體邏輯就得看你的需求了。

博文是我自己的筆記,可能寫得不是很詳細(xì)。你可以參(chao)考(xi) element UI 的$message源碼

2018年7月5日 14:04
編輯回答
枕邊人

最近正在抽vue的ui組件,其中有個(gè)message組件,和你這個(gè)差不多。簡單的說這類組件的難點(diǎn)在于:

  1. 使用Vue.extend而不是把組件寫在html里
  2. 需要實(shí)現(xiàn)一個(gè)單例模式

好多框架里面這類組件都有兩個(gè)文件,一個(gè)xxx.vue,一個(gè)xxx.js。
message.vue

<template>
    <div :class="['jn-message','jn-message-'+icon]" :style="{'z-index':ZINDEX++}">
        <i :class="['jn-icon-'+icon,'jn-message-icon']" v-if="icon"></i>
        <div class="jn-message-content">
          <template v-if="htmlEnable">
              <div v-html="$slots.default[0]" class="jn-message-content" >

              </div>
          </template>
          <template v-else>
              <slot>

              </slot>
          </template>
        </div>
        <i v-if="closeButton" class="jn-message-close jn-icon-close" @click="closeMessage"></i>
    </div>
</template>
<script>
import {ZINDEX} from '@/js/utils/const.js'
export default {
  name: "jn-message",
  data(){
    return {
      ZINDEX
    }
  },
  mounted() {
    setTimeout(() => {
      this.close();
    }, this.delay);
  },
  props: {
    delay: {
      type: Number,
      default: 3000
    },
    htmlEnable: {
      type: Boolean,
      default: false
    },
    closeButton:{
      type:Boolean,
      default:false
    },
    callback:{
      type:Object
    },
    icon: {
      type: String,
      default: "info"
    }
  },
  methods: {
    close() {
      this.$el.remove();
      this.$emit("close");
      this.$destroy();
    },
    closeMessage() {
      var beforeClose = this.callback.beforeClose,
          afterClose = this.callback.afterClose
      beforeClose && beforeClose.call(this, this);
      this.close();
      afterClose && afterClose.call(this, this);
    }
  }
};
</script>
<style lang="scss">
@import "../../../css/message.scss";
</style>

message.js

import Vue from 'vue';
import Message from './message.vue';
import {mergeDeep} from '@/js/utils/tools.js'

let MessageConstructor = Vue.extend(Message);

const message = function () {
    var instance = null,
        uid = null
    return function (option) {
        if(typeof option == 'string'){
            option = {
                text: option
            }
        }
        var config = mergeDeep({
            props: {
                htmlEnable: false,
            },
            text: 'default'
        }, option)
        if (!instance || instance._uid != uid) {

            if (!instance) {
                instance = new MessageConstructor({
                    propsData: config.props
                })
                uid = instance._uid
            } else {
                let t = new MessageConstructor({
                    propsData: config.props
                })
                if (t._uid != uid) {
                    instance.closeMessage()
                    instance = t
                    uid = t._uid
                }
            }
            
            instance.$slots.default = [config.text]
            instance.$mount()
            instance.$on('close', function () {
                instance = null
                uid = null
            })

            document.body.appendChild(instance.$el)

        }
        return instance
    }
}

const plugin = {}
plugin.install = function (Vue, options) {
    Vue.prototype.$message = message()
}

export default plugin;
2018年5月24日 04:52