Heim >Web-Frontend >js-Tutorial >Vue-Übungszusammenfassung MVVM-Lernen
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
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.
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
-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.
1.2.2 Änderungsüberwachung
In vielen MVVM-Klassen-Frameworks gibt es 3 Implementierungen der Änderungsüberwachung Typ:
1 2
|
<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">"'hello, '+name"</span>>hello</p> <img v-attr=<span class="string">"src: imgSrc"</span> /> |
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
Vue-Einführung ist nicht erforderlich, es gibt zu viele Ressourcen. Hier sind einige Vorteile aus der Praxis von Vue
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 |
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继承问题的产物
对于首屏的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">"'hello, '+name"</span>>hello</p> <img v-attr=<span class="string">"src: imgSrc"</span> />
|
{{}} 只是一个语法糖,不建议使用
对于非首屏的组件,使用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实现组件的主要核心也就这些,更方便的组件写法也只是对这些进行封装
在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">'.z-scroller'</span>) || window).addEventListener(<span class="string">'scroll'</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">'data-defaultsrc'</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">'data-isload'</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.
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
1
|
bab3af9ae2dde742872a340986362533if54bdf357c58b8a65c66d7c19c8e4d114=fab9ab63db7b134c286b50796f2abfe1"hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx39528cedfa926ea0c01e69ef5b2ea9b08ba1e8f7e7defbb91c00de417897dfe5if54bdf357c58b8a65c66d7c19c8e4d114=fab9ab63db7b134c286b50796f2abfe1"!hasTitle"54bdf357c58b8a65c66d7c19c8e4d114>xxx94b3e26ee717c64999d7867364b1b4a3 |
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]); |
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!