Heim >Web-Frontend >js-Tutorial >Vue-Übungszusammenfassung MVVM-Lernen

Vue-Übungszusammenfassung MVVM-Lernen

小云云
小云云Original
2018-03-12 16:37:141323Durchsuche

MVVM ist die Abkürzung für Model-View-ViewModel. Microsofts WPF bringt ein neues Technologieerlebnis. In diesem Artikel wird hauptsächlich eine Zusammenfassung der Vue-Praxis und des MVVM-Lernens mit Ihnen geteilt, in der Hoffnung, allen zu helfen.

1 MVVM-Lernen

1.1 Implementierungsprinzip

Das Implementierungsprinzip des MVVM-Klassenframeworks ist nicht kompliziert, ungefähr wie folgt:

  • Vorlagenanalyse Erhalten Sie abhängige Attribute

  • Überwachen Sie diese abhängigen Attribute durch eine Änderungsüberwachungsmethode

  • Wenn sich Attribute ändern, lösen Sie die entsprechende Anweisung aus. Verarbeiten Sie einfach die Logik

Tatsächlich besteht die Verarbeitungslogik der Direktive nicht unbedingt darin, die Ansicht zu bedienen, beispielsweise die Berichterstattung. Unter der Idee von mv wird jedoch empfohlen, alle Operationen an Ansichten in Anweisungen zu konzentrieren

Aus der Kernperspektive ist die Idee von mv nur eine Spezifische Erweiterung des Beobachtermusters.

1.2 Technische Kernpunkte

1.2.1 Vorlagenanalyse

Die Vorlagenanalyse ist relativ einfach Grundsätzlich handelt es sich um Vorlagen. Der entscheidende Punkt hier ist die Frage der Vorlagenquelle. Tatsächlich sollte es sich um eine beliebige Zeichenfolge handeln.

Dies bedeutet, dass das Framework einen Vorlagenparser benötigt, unabhängig davon, ob es sich um einen Parser handelt Ob komplex oder einfach, es ist ein Muster: [Eingabe–> Template Engine–> >Eingabe: jedes Zeichen, das den Regeln entspricht. Zeichenfolge

    Ausgabe: data.attr, Direktive, Filter, die überwacht werden müssen
  • Wann Entwerfen eines Frameworks, wenn Sie eine bessere Skalierbarkeit wünschen, sollte die
  • -Eingabe flexibel genug sein. In Bezug auf die Quelle kann die Vorlage someDomHere.html() oder eine dynamische Eingabe sein, die besser anwendbar ist Inhaltlich: Wenn die Engine eine höhere Syntax erkennen kann, ist sie funktionaler.

  • Die Ausgabe sollte konvergent genug sein. Konvergenz bedeutet, dass die endgültige Ausgabe begrenzt und regelmäßig ist Filter. Die spezifische Verarbeitung konzentriert sich auf diese beiden Konzepte. Durch die Erweiterung nur dieser beiden Konzepte kann das System erweitert werden

1.2.2 Änderungsüberwachung

In vielen MVVM-Klassen-Frameworks gibt es 3 Implementierungen der Änderungsüberwachung Typ:

Fassadenmethode Setter, Getter: wie Knockout, Q. Begrenzen Sie die Eingänge, die geändert werden können, und lassen Sie den Benutzer entscheiden, wie er den Eingang nutzt.

    Verwenden Sie defineProperty: z. B. vue, avalon. Im Wesentlichen ist es auch ein Setter und Getter, aber es überlässt dem Benutzer nicht das Recht, den Eingang zu verwenden, um zu entscheiden.
  1. Dirty Check: z. B. eckig. Es gibt genügend Forschung zu Angular, daher werde ich hier nicht näher darauf eingehen.
  2. 1
  3. 2

  4. 3

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    <span class="comment">//方式1 vs. 方式2</span>
    <span class="comment">//方式1:</span>
    vm.<span class="variable">$set</span>(aaa, <span class="number">1</span>);    <span class="comment">//会触发变动逻辑</span>
    vm._data.aaa = <span class="number">2</span>;   <span class="comment">//不会触发变动逻辑,不过这不是框架希望的操作,可以被hack</span>
    vm.<span class="variable">$get</span>(aaa);       <span class="comment">//2</span>
    <span class="comment">//方式2:</span>
    vm.aaa = <span class="number">1</span>;         <span class="comment">//一定会触发变动逻辑</span>
    vm._data.aaa = <span class="number">2</span>;   <span class="comment">//也可以找到内部的data进行修改,但是没用</span>
    vm.aaa;             <span class="comment">//1</span>


    4567891011
    <p>hello, {{name}}</p>      <!--初始化前,页面会直接展示hello, {{name}}-->
    <img src=<span class="s
    tring">"{{imgSrc}}"</span> />    <!--初始化前,会报错,can not find http:<span class="comment">//xxx.com/{{imgSrc}}--></span>
     
    <!--正确的写法:-->
    <p v-text=<span class="string">"&#39;hello, &#39;+name"</span>>hello</p>
    <img v-attr=<span class="string">"src: imgSrc"</span> />

    1.2.3 Zusammenfassung und Erweiterung

    Analyse, Entkopplung und Abstraktion einer Art komplexer und allgemeiner Probleme und Erlangung breiter Anerkennung in der Praxis. Anschließend wird ein Modell, mvvm, gebildet. Es ist auch ein Modus Es wird nicht unbedingt als MVVM-Modus bezeichnet, und darüber kann der Autor nicht entscheiden.

    Was den Kern dieses Modus betrifft, versteht der Autor Folgendes: Das System erhält bestimmte Verarbeitungsregeln für bestimmte Datenquellen basierend auf dem Konfiguration: Wenn sich die Datenquelle ändert, werden entsprechende Verarbeitungsregeln ausgelöst. Die Erweiterung des Schemas erfolgt bidirektional, was durch die Systemimplementierung bestimmt wird. Wenn bestimmte Regeln erfüllt sind, kann die Datenquelle aktualisiert werden.

    Wir lösen uns vom Konzept der Ansicht und Lenovo implementiert ein Überwachungssystem. Tatsächlich eignet sich dieses Modell sehr gut für den Einsatz in Überwachungssystemen.

    Die Verarbeitungslogik des allgemeinen Überwachungssystems lautet: Die Erfassungsquelle sammelt und organisiert die Überwachungsdaten und speichert sie dann in der Datenbank. Das Überwachungssystem überwacht die Datenquelle in Echtzeit und zeichnet Echtzeitdiagramme (Feedback). Wenn in der Datenquelle Änderungen auftreten, die bestimmten Regeln entsprechen, werden entsprechende Aktionen ausgelöst, beispielsweise eine Alarmierung.

    Wie implementiert man dieses System und macht es skalierbarer? Bezogen auf den MVVM-Modus kann es so aussehen:

    Das Sammelsystem ist unabhängig vom Überwachungssystem und anders, also machen wir uns darüber vorerst keine Sorgen. Das Überwachungssystem erhält über bestimmte Konfigurationsdateien die zu überwachenden Datenquellen und die entsprechenden Verarbeitungslogikregeln und löst bei Änderungen der Datenquellen eine entsprechende Verarbeitung aus.

    Folgen Sie dem MVVM-Muster und machen Sie einige Abstraktionen.

    • Die Datenquelle ist nicht unbedingt auf die Datenbank beschränkt, sie kann überall sein, solange das System sie über bestimmte konfigurierbare Regeln erhalten kann

    • Die Verarbeitungsregeln sind abstrahiert, um sie einfacher erweitern zu können, z. B. das Senden von E-Mails, Textnachrichten, WeChat, QQ-Nachrichten usw.

    entspricht dem Front-End-MVVM-Framework. und die Vorlage ist die Konfigurationsdatei, die Direktive ist die Verarbeitungsregel und die Daten entsprechen der Datenquelle.

    • Wenn das System eine neue Datenquelle hinzufügen muss, müssen Sie nur die Konfigurationsdatei aktualisieren und sie vom System lesen lassen, um die Datenüberwachung zu starten

    • Wenn Sie eine neue Verarbeitungsregel hinzufügen müssen, können Sie eine neue Verarbeitungsregel über ein Hot-Swap-fähiges Verarbeitungsregel-Plug-in-System erweitern und dann die Konfigurationsdatei aktualisieren, und das System kann die neue Verarbeitungsregel akzeptieren

    2 Vue-Übungen

    Vue-Einführung ist nicht erforderlich, es gibt zu viele Ressourcen. Hier sind einige Vorteile aus der Praxis von Vue

    2.1 Organisationsstruktur

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    + src

    + - - gemeinsam

    +- Filter

    - vue.js

    ext.js

                     +-- index.js

                     +-- vue.ext.js

                     +-- xxx.mixin.js

    2.2 Vue扩展

    vue的扩展非常方便,与vue相关的资源都放置在src/common/vue/下面,比如coms(组件),directive,filter

    src/common/vue/vue.ext.js是对vue进行全局公共的扩展,对于所有页面共有的扩展放在这个文件下面,内容如下:

    可以看到,扩展vue库本身有4个扩展点:

    • 扩展Vue库的全局方法/属性,方式:Vue.xxx = …

    • 扩展Vue实例的方法/属性,方式:Vue.prototype = …

    • 扩展directive,方式:Vue.directive(‘directiveName’, options);

    • 扩展filter,方式:Vue.filter(‘filterName’, function(){});

    对于页面单独需要的扩展,集中在src/pages/pageName/vue.ext.js里面,形式与全局的vue.ext.js一样

    在实例化Vue的过程中也有许多可以扩展与优化的地方,在实践过程中只是应用了mixin功能,其他的可以慢慢深入

    mixin的作用是在实例化Vue的时候混入一些功能,它可以混入许多特性,格式与实例化Vue时用到的option格式一样,比如index页面的mixin.js的内容如下:

    这个mixin混入了两个方法,多个Vue实例共享的options可以放置到mixin中,从而避免了代码重,比如在实例化Vue的时候这样使用mixin:

    可以看到mixin是个数组,因此可以同时使用多个mixin

    实际上这里的mixin主要不是为了避免代码重复(实践的时候只是这样用),mixin是一种模式,一个mixin内聚了实现一项功能的方法/属性集合,在定义/生成实例的时候,通过混入mixin就可以让该实例拥有某项功能,归根结底是组合vs继承问题的产物

    2.3 vue组件插入问题

    2.3.1 首屏

    对于首屏的vue组件,直接把模板放在主页面中即可,初始化的时候只需要把el参数传入,Vue就会用el的html作为模板来初始化Vue实例:

    这里需要注意的是在模板中不能使用{{}},否则在还没初始化之前,页面会显示奇怪的东西,比如:

    1

    2

    3

    4

    5

    6

    7

    <p>hello, {{name}}</p>      <!--初始化前,页面会直接展示hello, {{name}}-->
    <img src=<span class="s
    tring">"{{imgSrc}}"</span> />    <!--初始化前,会报错,can not find http:<span class="comment">//xxx.com/{{imgSrc}}--></span>
     
    <!--正确的写法:-->
    <p v-text=<span class="string">"&#39;hello, &#39;+name"</span>>hello</p>
    <img v-attr=<span class="string">"src: imgSrc"</span> />

     

    {{}} 只是一个语法糖,不建议使用

    2.3.2 非首屏

    对于非首屏的组件,使用vue的方式和原始方式差不多,先生成节点,然后append,譬如:

    el参数可以接收query string,也可以直接是一个dom节点,如果是dom节点则直接编译dom的内容。如果dom节点不在文档树中,则利用vueObj.$appendTo方法将vue实例的根节点插入到文档树中

    上面这种方式是在页面中没有组件的【坑】的情况下使用的,如果页面为组件留了【坑】,比如:

    1

    2

    0510d38451755f656b967a56ae76d68aclass54bdf357c58b8a65c66d7c19c8e4d114=e7b5d65d577098ec09191daa17885c87"hotRecord"54bdf357c58b8a65c66d7c19c8e4d114 id=e7b5d65d577098ec09191daa17885c87"js-hotRecord"54bdf357c58b8a65c66d7c19c8e4d114>4d7ab0de9a42de71c682b0860bad1410

     

    那么,我们可以这样初始化vue实例:

    利用template参数传入模板,并指定el,那么vue实例在初始化之后就会自动把内容插入到el中

    通过vue实现组件的主要核心也就这些,更方便的组件写法也只是对这些进行封装

    2.4 自定义 directive

    在vue中自定义directive是非常简单明了的,要自定义一个directive,可以注册3个钩子函数:

    • bind:仅调用一次,当指令第一次绑定元素的时候。

    • update:第一次调用是在 bind之后,用的是初始值;以后每当绑定的值发生变化就会被调用,新值与旧值作为参数。

    • unbind:仅调用一次,当指令解绑元素的时候。

    下面简单介绍一个自定义directive——lazyload:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    <span class="keyword">function</span> addSrc(){}
    <span class="keyword">function</span> load(){}
     
    module.exports = {
        bind: <span class="keyword">function</span>() {
            <span class="keyword">if</span> (!hasBind) { <span class="comment">//全局事件只绑定一次</span>
                hasBind = <span class="keyword">true</span>;
                (document.querySelector(<span class="string">&#39;.z-scroller&#39;</span>) || window).addEventListener(<span class="string">&#39;scroll&#39;</span>, T.debounce(load, <span class="number">100</span>), <span class="keyword">false</span>);
            }
            <span class="comment">//这里也可以使用data属性来获取</span>
            <span class="keyword">var</span> defaultSrc = <span class="keyword">this</span>.el.getAttribute(<span class="string">&#39;data-defaultsrc&#39;</span>);
            <span class="keyword">if</span> (defaultSrc) addSrc(<span class="keyword">this</span>.el, defaultSrc);    <span class="comment">//先使用默认图片</span>
        },
        update: <span class="keyword">function</span>(src) {
            <span class="comment">//directive初始化时,会调用一次bind和update,bind没有传入src,只有update才会传入src</span>
            <span class="comment">//因此只能在update这里拿到需要lazyload的src</span>
            <span class="comment">//lazyload不允许修改src,这里限制只会执行一次update,防止src被修改造成的影响</span>
            <span class="comment">//注:接受src改变可以实现,只是需要一些复杂的处理,这里为了简单起见不让src改变</span>
            <span class="keyword">if</span> (<span class="keyword">this</span>.init) <span class="keyword">return</span>;  
            <span class="keyword">this</span>.init = <span class="keyword">true</span>;
     
            <span class="comment">//如果图片已经加载了,就不需要注册了,这里也可以使用data属性来区分</span>
            <span class="keyword">var</span> isLoad = parseInt(<span class="keyword">this</span>.el.getAttribute(<span class="string">&#39;data-isload&#39;</span>));
            <span class="keyword">if</span> (isLoad) <span class="keyword">return</span>;
     
            <span class="comment">//注册需要lazyload的图片</span>
            <span class="keyword">list</span>[index++] = <span class="keyword">this</span>;
            <span class="keyword">list</span>[index++] = src;
        }
        <span class="comment">//这里有一个最大的问题:由于有local的存在,会创建两个一模一样的lazyload directive</span>
        <span class="comment">//按理说应该定义一个unbind,但是在unbind中找到并除掉local创建出来的lazyload directive会比较麻烦</span>
        <span class="comment">//因此在load函数里面做了一个处理:如果发现需要lazyload的节点不在文档树中,则剔除掉这个lazyload</span>
        <span class="comment">//通过这个直接省掉了unbind函数</span>
    };

     

    Das Anpassen des Filters ist auch sehr einfach. Ich werde ihn hier nicht vorstellen.

    2.5.1 Kein Ereignis Proxy

    Ich bin es gewohnt, Ereignis-Proxys zu verwenden, und es wird etwas unangenehm sein, sie plötzlich zu verlieren. Aber ist der Ereignis-Proxy im Nachhinein wirklich wichtig? Oder sind wir nur an Event-Proxys gewöhnt?

    Die Registrierung derselben Veranstaltung über vue ist mühelos. Ein weiteres Problem besteht darin, dass, solange es nicht viele Ereignisse gibt, nicht mehr als 50 oder 100, nicht viel Speicher verbraucht wird, sodass manchmal wirklich kein Ereignisagent erforderlich ist. Wenn Sie es wirklich brauchen, implementieren Sie einfach eine Contain-Methode

    2.5.2 Das Seltsame, kein if-else zu haben

    Wenn Sie den folgenden Code zum ersten Mal sehen, wird er wirklich seltsam sein

    1

    1

    2

    3

    af5c2ece8ea7a096914f90670424bcf6if54bdf357c58b8a65c66d7c19c8e4d114=e7b5d65d577098ec09191daa17885c87"hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx39528cedfa926ea0c01e69ef5b2ea9b0

    06a275819bf51ee1d38350f8e7d3f19aif54bdf357c58b8a65c66d7c19c8e4d114=e7b5d65d577098ec09191daa17885c87"!hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx94b3e26ee717c64999d7867364b1b4a3

     

    2

    3

    bab3af9ae2dde742872a340986362533if54bdf357c58b8a65c66d7c19c8e4d114=fab9ab63db7b134c286b50796f2abfe1"hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx39528cedfa926ea0c01e69ef5b2ea9b0

    8ba1e8f7e7defbb91c00de417897dfe5if54bdf357c58b8a65c66d7c19c8e4d114=fab9ab63db7b134c286b50796f2abfe1"!hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx94b3e26ee717c64999d7867364b1b4a3

    2.5.3 Einzelwert
    • Obwohl Vue über einen Syntaxparser verfügt, können Sie Ausdrücke im Wert der Direktive verwenden, aber wenn a Komplexe Ausdrücke verunreinigen die Vorlage und machen den Code weniger lesbar, oder der Ausdruck kann die Aufgabe nicht abschließen.

      Daher habe ich während der Praxis von mvvm tiefgreifend festgestellt, dass die Verwendung eines einzelnen Werts (höchstens nur eines ?:-Ausdrucks) zum Schreiben von Vorlagen den Code klarer und lesbarer macht und die Wartbarkeit des Codes erhöht Dies entspricht eher der Kernidee von mvvm: f(state) = view
    • Einige Bibliotheken haben nicht einmal einen Grammatikparser, wie z. B. q, aber sie können sehr gut funktionieren.

      Wohin also mit den komplexen Vorgängen?

    Für Werte, die sich nicht ändern, also Konstanten, muss die Verarbeitung vor der Initialisierung abgeschlossen sein

    Für Werte, die Wird sich ändern, können komplexe Vorgänge nicht nur im Filter ausgeführt, sondern auch gleichzeitig auf andere Felder angewendet werden. Dies entspricht nicht vollständig dem berechneten Attribut.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    e63d03b1fe1ef417bff512a2da2d7305//common/vue/vue.ext.js 回头看前面对该文件的介绍可以看到这句54bdf357c58b8a65c66d7c19c8e4d114

    Vue.noopVue = 9b8f193a100df443bb5f942579a9d04cnew54bdf357c58b8a65c66d7c19c8e4d114 Vue({});

     

    e63d03b1fe1ef417bff512a2da2d7305//a.js54bdf357c58b8a65c66d7c19c8e4d114

    Vue.noopVue.5a4944fb39e8a6d067595fa969ab7502$on54bdf357c58b8a65c66d7c19c8e4d114(e7b5d65d577098ec09191daa17885c87'someEvent'54bdf357c58b8a65c66d7c19c8e4d114, 9b8f193a100df443bb5f942579a9d04cfunction54bdf357c58b8a65c66d7c19c8e4d114() {});

     

    e63d03b1fe1ef417bff512a2da2d7305//b.js54bdf357c58b8a65c66d7c19c8e4d114

    Vue.noopVue.5a4944fb39e8a6d067595fa969ab7502$emit54bdf357c58b8a65c66d7c19c8e4d114(e7b5d65d577098ec09191daa17885c87'someEvent'54bdf357c58b8a65c66d7c19c8e4d114, [opts]);

    2.5.4 Alternative $(document).onBei der Verwendung von jquery/zepto bin ich es gewohnt, $(document).on als globalen Ereignis-Proxy zu verwenden. Bei der Verwendung von vue benötige ich Um Zepto aufzugeben, muss ich dieses Problem lösen. Da die Vue-Instanz selbst über die Ereignisfunktion verfügt, besteht die Lösung hier darin, ein globales leeres Vue-Objekt zu erstellen und es als globalen Ereignis-Proxy zu verwenden: table>


    3 Zusammenfassung

    Obwohl wir am Ende die Vue-Transformation bestehender Projekte im Hinblick auf den Kompromiss zwischen Kosten und Leistung aufgegeben haben, hindert uns dies nicht daran, das mvvm-Klassen-Framework zu studieren

    Das MVVM-Modell ist immer noch eine eingehende Untersuchung wert, und in der Praxis können wir auch viel lernen

    Die Erfahrung, mit einer anderen Art des Denkens und Denkens zu entwickeln, wird uns auch zum Schauen bringen Probleme angehen und bewältigen. Unterwegs ist etwas gewonnen.

    Verwandte Empfehlungen:

    Wie implementiert AngularJS Tabs im MVVM-Stil? Fall + Code

    JS-Implementierung eines einfachen MVVM-Frameworks, Beispielfreigabe

    Was ist MVVM-Architektur und Datenbindung?

    12345 67 89 Vue.noopVue = daa3a4daf9b6bfdd92c6cd9ec533075enew54bdf357c58b8a65c66d7c19c8e4d114 Vue({ }); 89e7ad2b99889e4d86b051f40860f447//a.js54bdf357c58b8a65c66d7c19c8e4d114Vue.noopVue.d9df1c7814ea394f861c6a0ed66fe7ab$on54bdf357c58b8a65c66d7c19c8e4d114(fab9ab63db7b134c286b50796f2abfe1'someEvent'54bdf357c58b8a65c66d7c19c8e4d114, b4d03f3152244853cc41318ec689fb29function54bdf357c58b8a65c66d7c19c8e4d114() {}) ; 89e7ad2b99889e4d86b051f40860f447//b.js54bdf357c58b8a65c66d7c19c8e4d114 Vue.noopVue.88104d7fcb1def03eec3820362570296$emit54bdf357c58b8a65c66d7c19c8e4d114(fab9ab63db7b134c286b50796f2abfe1'someEvent'54bdf357c58b8a65c66d7c19c8e4d114, [opts]); td>

Das obige ist der detaillierte Inhalt vonVue-Übungszusammenfassung MVVM-Lernen. 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