Heim  >  Artikel  >  Web-Frontend  >  vuejs-Methode zum Aufrufen von Komponenten

vuejs-Methode zum Aufrufen von Komponenten

藏色散人
藏色散人Original
2021-11-01 11:16:583371Durchsuche

So rufen Sie Komponenten in VueJS auf: 1. Steuern Sie die Anzeige und das Ausblenden von Komponenten explizit über V-Model oder .sync. 2. Rufen Sie über JS-Code auf. 3. Rufen Sie über Vue-Anweisungen auf.

vuejs-Methode zum Aufrufen von Komponenten

Die Betriebsumgebung dieses Artikels: Windows 7-System, Vue-Version 2.9.6, DELL G3-Computer.

Drei Möglichkeiten, Vue-Komponenten aufzurufen

Kürzlich bin ich beim Schreiben von fj-service-system auf einige Probleme gestoßen. Das heißt, sollte ich für einige meiner Komponenten, wie z. B. Dialog und Message, Komponentenbibliotheken von Drittanbietern einführen, wie z. B. element-ui, oder sollte ich selbst eine implementieren? Obwohl sie die Funktion haben, bei Bedarf vorzustellen, passt der Gesamtstil nicht zu meinem Gesamtsystem. Sie können also erwägen, diese einfachen Komponenten selbst manuell zu implementieren.

Wenn wir einige Artikel über Vue lesen, handelt es sich normalerweise bei dem, was wir sehen, um Entwicklungsseiten für Vue-Einzeldateikomponenten. Es gibt relativ wenige Artikel zur Einzelkomponentenentwicklung. Als ich am fj-service-system-Projekt arbeitete, stellte ich fest, dass auch die Einzelkomponentenentwicklung sehr interessant ist. Sie können es aufschreiben und aufzeichnen. Da es sich bei dem, was ich geschrieben habe, nicht um ein UI-Framework handelt, sondern nur um einen Datensatz. Es gibt kein Github-Repository. Schauen wir uns also den Code an.

  • v-model oder .sync steuert explizit das Anzeigen und Ausblenden von Komponenten
  • Aufruf über js-Code
  • Aufruf über Vue-Anweisungen

Beim Schreiben von Komponenten kommen viele Schreibmethoden und Inspirationen von Element-UI, vielen Dank.

Dialog

Ich bin es gewohnt, dieses Ding als Dialogfeld zu bezeichnen. Tatsächlich wird es auch als modale Komponente (Popup-Fenster) bezeichnet. Tatsächlich wird auf der Seite ein kleines Fenster angezeigt, und der Inhalt dieses kleinen Fensters kann angepasst werden. Es kann normalerweise als Dialogfeld für Anmeldefunktionen verwendet werden.

Diese Art von Komponente eignet sich sehr gut zur expliziten Steuerung des Erscheinens und Verschwindens über V-Modell oder .sync. Es kann direkt auf die Seite geschrieben und dann über Daten gesteuert werden – dies ist auch die Komponente, die den Designideen von Vue am besten entspricht.

Dafür können wir eine Komponente namens Dialog.vue schreiben

<template>
  <div class="dialog">
    <div class="dialog__wrapper" v-if="visble" @clcik="closeModal">
      <div class="dialog">
        <div class="dialog__header">
          <div class="dialog__title">{{ title }}</div>
        </div>
        <div class="dialog__body">
          <slot></slot>
        </div>
        <div class="dialog__footer">
          <slot name="footer"></slot>
        </div>
      </div>
    </div>
    <div class="modal" v-show="visible"></div>
  </div></template><script>
  export default {    name: &#39;dialog&#39;,    props: {      title: String,      visible: {        type: Boolean,        default: false
      }
    },    methods: {      close() {        this.$emit(&#39;update:visible&#39;, false) // 传递关闭事件
      },      closeModal(e) {        if (this.visible) {          document.querySelector(&#39;.dialog&#39;).contains(e.target) ? &#39;&#39; : this.close(); // 判断点击的落点在不在dialog对话框内,如果在对话框外就调用this.close()方法关闭对话框
        }
      }
    }
  }</script>

Wir werden kein CSS oder irgendetwas anderes schreiben, es hat wenig mit der Komponente selbst zu tun. Es ist jedoch zu beachten, dass die obige dialog__wrapper-Klasse auch im Vollbildmodus und transparent ist. Sie wird hauptsächlich zum Abrufen von Klickereignissen und zum Sperren der Klickposition verwendet. Sie verwendet die Node.contains()-Methode des DOM, um zu bestimmen, ob der Klick erfolgt Position ist der Dialog selbst. Wenn Sie außerhalb des Dialogs klicken, z. B. auf eine durchscheinende modale Ebene, wird ein Schließereignis ausgelöst, um den Dialog zu schließen.

Wenn wir es extern aufrufen möchten, können wir es wie folgt aufrufen:

<template>
  <div class="xxx">
    <dialog :visible.sync="visible"></dialog> 
    <button @click="openDialog"></button>
  </div></template><script>
  import Dialog from &#39;Dialog&#39;
  export default {    components: {
      Dialog
    },    data() {      return {        visible: false
      }
    },    methods: {      openDialog() {        this.visible = true // 通过data显式控制dialog
      }
    }
  }</script>

Um das Öffnen und Schließen des Dialogs attraktiver zu gestalten, können Sie versuchen, die Komponente 300ff3b250bc578ac201dd5fb34a00046087faffb1c3f26530d25a6b190c2f81 hinzuzufügen Der Übergangseffekt, einfach Eine kleine Übergangsanimation würde auch toll aussehen.

Hinweis

Diese Komponente ähnelt der Nachricht (Nachrichtenaufforderung) von element-ui. Was mich am meisten fasziniert, ist, dass der Aufruf nicht durch explizites Schreiben der HTML-Struktur der Komponente in der Seite über das V-Modell erfolgt, sondern durch die Verwendung von Methoden wie this.$message() in js. Obwohl diese Methode dem datengesteuerten Denken von Vue widerspricht. Aber ich muss sagen, dass es in manchen Situationen wirklich praktisch ist.

Für Komponenten wie „Hinweis“ müssen Sie jeweils nur ein paar Wörter eingeben, um den Benutzern eine einfache Nachrichtenaufforderung zu geben. Die abgefragten Informationen können unterschiedlich sein und es können sogar überlagerte Aufforderungen vorhanden sein. Wenn Sie es über die erste Methode aufrufen, müssen Sie die HTML-Struktur im Voraus schreiben. Dies ist zweifellos ein mühsamer Ansatz und es ist unmöglich vorherzusagen, wie viele Meldungsfelder vorhanden sein werden. Wenn Sie es über die js-Methode aufrufen, müssen Sie nur die unterschiedlichen Texte und Typen berücksichtigen, die in verschiedenen Situationen aufgerufen werden.

Der vorherige Ansatz bestand darin, eine Vue-Datei zu schreiben, dann die Seite über das Komponentenattribut einzuführen und den Tag-Aufruf explizit zu schreiben. Wie rufe ich die Komponente über die js-Methode auf?

Der Schlüssel hier ist die Extend-Methode von Vue.

Das Dokument enthält keine Einzelheiten darüber, wie Extend auf diese Weise verwendet werden kann. Es wird lediglich erläutert, dass es sich um einen Vue-Komponentenkonstruktor handelt, der manuell gemountet werden muss.

Anhand des Quellcodes von element-ui können wir verstehen, wie die oben genannten Funktionen implementiert werden.

Der erste Schritt besteht darin, eine Notice.vue-Datei zu erstellen

<template>
  <div class="notice">
    <div class="content">
      {{ content }}    </div>
  </div></template><script>
  export default {    name: &#39;notice&#39;,
    data () {      return {        visible: false,        content: &#39;&#39;,        duration: 3000
      }
    },    methods: {      setTimer() {        setTimeout(() => {          this.close() // 3000ms之后调用关闭方法
        }, this.duration)
      },      close() {        this.visible = false
        setTimeout(() => {          this.$destroy(true)          this.$el.parentNode.removeChild(this.$el) // 从DOM里将这个组件移除
        }, 500)
      }
    },    mounted() {      this.setTimer() // 挂载的时候就开始计时,3000ms后消失
    }
  }</script>

Was oben geschrieben wurde, unterscheidet sich nicht wesentlich von einer gewöhnlichen Einzeldatei-Vue-Komponente. Der Unterschied besteht jedoch darin, dass es keine Requisiten gibt. Wie kann man also die Sichtbarkeit dieser Komponente von außen steuern?

Es wird also eine js-Datei benötigt, um diese Komponente zu übernehmen und die Extend-Methode aufzurufen. Sie können im selben Verzeichnis eine index.js-Datei erstellen.

import Vue from &#39;vue&#39;const NoticeConstructor = Vue.extend(require(&#39;./Notice.vue&#39;)) // 直接将Vue组件作为Vue.extend的参数let nId = 1const Notice = (content) => {  let id = &#39;notice-&#39; + nId++  const NoticeInstance = new NoticeConstructor({    data: {      content: content
    }
  }) // 实例化一个带有content内容的Notice

  NoticeInstance.id = id
  NoticeInstance.vm = NoticeInstance.$mount() // 挂载但是并未插入dom,是一个完整的Vue实例
  NoticeInstance.vm.visible = true
  NoticeInstance.dom = NoticeInstance.vm.$el  document.body.appendChild(NoticeInstance.dom) // 将dom插入body
  NoticeInstance.dom.style.zIndex = nId + 1001 // 后插入的Notice组件z-index加一,保证能盖在之前的上面
  return NoticeInstance.vm
}export default {  install: Vue => {
    Vue.prototype.$notice = Notice // 将Notice组件暴露出去,并挂载在Vue的prototype上
  }
}

In dieser Datei können wir sehen, dass wir über NoticeConstructor verschiedene Eigenschaften einer Komponente über js steuern können. Schließlich registrieren wir es im Vue-Prototyp, damit wir die Methode this.$notice() innerhalb der Seite verwenden und diese Komponente einfach aufrufen können, um einen einfachen Benachrichtigungseffekt zu schreiben.

Vergessen Sie natürlich nicht, dass dies einem Vue-Plug-In entspricht. Sie müssen also die Methode Vue.use() im Haupt-JS aufrufen:

// main.js

// ...
import Notice from 'notice/index.js'

Vue.use(Notice)

// ...

Loading

在看element-ui的时候,我也发现了一个很有意思的组件,是Loading,用于给一些需要加载数据等待的组件套上一层加载中的样式的。这个loading的调用方式,最方便的就是通过v-loading这个指令,通过赋值的true/false来控制Loading层的显隐。这样的调用方法当然也是很方便的。而且可以选择整个页面Loading或者某个组件Loading。这样的开发体验自然是很好的。

其实跟Notice的思路差不多,不过因为涉及到directive,所以在逻辑上会相对复杂一点。

平时如果不涉及Vue的directive的开发,可能是不会接触到modifiers、binding等概念。参考文档

简单说下,形如:v-loading.fullscreen="true"这句话,v-loading就是directive,fullscreen就是它的modifier,true就是binding的value值。所以,就是通过这样简单的一句话实现全屏的loading效果,并且当没有fullscreen修饰符的时候就是对拥有该指令的元素进行loading效果。组件通过binding的value值来控制loading的开启和关闭。(类似于v-model的效果)

其实loading也是一个实际的DOM节点,只不过要把它做成一个方便的指令还不是特别容易。

首先我们需要写一下loading的Vue组件。新建一个Loading.vue文件

<template>
  <transition
    name="loading"
  	@after-leave="handleAfterLeave">
    <div
      v-show="visible"
      class="loading-mask"
      :class={&#39;fullscreen&#39;: fullscreen}>
      <div class="loading">
        ...      </div>
      <div class="loading-text" v-if="text">
        {{ text }}      </div>
    </div>
  </transition></template><script>export default {  name: &#39;loading&#39;,
  data () {    return {      visible: true,      fullscreen: true,      text: null
    }
  },  methods: {    handleAfterLeave() {      this.$emit(&#39;after-leave&#39;);
    }
  }
}</script><style>.loading-mask{
  position: absolute; // 非全屏模式下,position是absolute
  z-index: 10000;
  background-color: rgba(255,235,215, .8);
  margin: 0;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  transition: opacity .3s;
}
.loading-mask.fullscreen{
  position: fixed; // 全屏模式下,position是fixed
}
// ...</style>

Loading关键是实现两个效果:

    1.全屏loading,此时可以通过插入body下,然后将Loading的position改为fixed,插入body实现。
    2.对所在的元素进行loading,此时需要对当前这个元素的的position修改:如果不是absolute的话,就将其修改为relatvie,并插入当前元素下。此时Loading的position就会相对于当前元素进行绝对定位了。
所以在当前目录下创建一个index.js的文件,用来声明我们的directive的逻辑。

import Vue from &#39;vue&#39;const LoadingConstructor = Vue.extend(require(&#39;./Loading.vue&#39;))export default {  install: Vue => {
    Vue.directive(&#39;loading&#39;, { // 指令的关键
      bind: (el, binding) => {        const loading = new LoadingConstructor({ // 实例化一个loading
          el: document.createElement(&#39;div&#39;),          data: {            text: el.getAttribute(&#39;loading-text&#39;), // 通过loading-text属性获取loading的文字
            fullscreen: !!binding.modifiers.fullscreen 
          }
        })
        el.instance = loading; // el.instance是个Vue实例
        el.loading = loading.$el; // el.loading的DOM元素是loading.$el
        el.loadingStyle = {};
        toggleLoading(el, binding);
      },      update: (el, binding) => {
        el.instance.setText(el.getAttribute(&#39;loading-text&#39;))        if(binding.oldValue !== binding.value) {
          toggleLoading(el, binding)
        }   
      },      unbind: (el, binding) => { // 解绑
        if(el.domInserted) {          if(binding.modifiers.fullscreen) {              document.body.removeChild(el.loading);
          }else {
            el.loading &&
            el.loading.parentNode &&
            el.loading.parentNode.removeChild(el.loading);
          }
        }
      }
    })    const toggleLoading = (el, binding) => { // 用于控制Loading的出现与消失
      if(binding.value) { 
        Vue.nextTick(() => {          if (binding.modifiers.fullscreen) { // 如果是全屏
            el.originalPosition = document.body.style.position;
            el.originalOverflow = document.body.style.overflow;
            insertDom(document.body, el, binding); // 插入dom
          } else {
            el.originalPosition = el.style.position;
            insertDom(el, el, binding); // 如果非全屏,插入元素自身
          }
        })
      } else {        if (el.domVisible) {
          el.instance.$on(&#39;after-leave&#39;, () => {
            el.domVisible = false;            if (binding.modifiers.fullscreen && el.originalOverflow !== &#39;hidden&#39;) {              document.body.style.overflow = el.originalOverflow;
            }            if (binding.modifiers.fullscreen) {              document.body.style.position = el.originalPosition;
            } else {
              el.style.position = el.originalPosition;
            }
          });
          el.instance.visible = false;
        }
      }
    }    const insertDom = (parent, el, binding) => { // 插入dom的逻辑
      if(!el.domVisible) {        Object.keys(el.loadingStyle).forEach(property => {
          el.loading.style[property] = el.loadingStyle[property];
        });        if(el.originalPosition !== &#39;absolute&#39;) {
          parent.style.position = &#39;relative&#39;
        }        if (binding.modifiers.fullscreen) {
          parent.style.overflow = &#39;hidden&#39;
        }
        el.domVisible = true;
        parent.appendChild(el.loading) // 插入的是el.loading而不是el本身
        Vue.nextTick(() => {
          el.instance.visible = true;
        });
        el.domInserted = true;
      }
    }
  }
}

同样,写完整个逻辑,我们需要将其注册到项目里的Vue下:

// main.js

// ...
import Loading from 'loading/index.js'

Vue.use(Loading)

// ...

至此我们已经可以使用形如

adb2c97e42ba7ef7e89c2223cc327580

这样的方式来实现调用一个loading组件了。

总结

在用Vue写我们的项目的时候,不管是写页面还是写形如这样的功能型组件,其实都是一件很有意思的事情。本文介绍的三种调用组件的方式,也是根据实际情况出发而实际操作、实现的。不同的组件通过不同的方式去调用,方便了开发人员,也能更好地对代码进行维护。当然也许还有其他的方式,我并没有了解,也欢迎大家在评论里指出!

最后再次感谢element-ui的源码给予的极大启发。

推荐:《最新的5个vue.js视频教程精选

Das obige ist der detaillierte Inhalt vonvuejs-Methode zum Aufrufen von Komponenten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn