Heim > Artikel > WeChat-Applet > Verstehen Sie schnell die Verwendung von WeChat-Miniprogrammen, einer Todos-App, die auf Basis des Miniprogramm-Frameworks entwickelt wurde
WeChat hat die offizielle Dokumentation und die Entwicklertools für WeChat-Miniprogramme offiziell geöffnet. In den letzten zwei Tagen habe ich relevante Nachrichten gelesen, um zu verstehen, wie man kleine Programme entwickelt. Nachdem in den letzten zwei Tagen die offiziellen Dokumente veröffentlicht wurden, habe ich einen kurzen Blick darauf geworfen und mich auf die beiden Teile des Dokuments konzentriert: Framework und Komponenten , und dann basierend auf einem einfachen Tutorial, um eine normale Aufgaben-App zu erstellen. Diese App basiert auf der WeChat-Applet-Plattform und implementiert die regulären Funktionen der Todo-App. Um sie näher an das tatsächliche Arbeitsszenario heranzuführen, werden gleichzeitig auch die Lade- und Toastkomponenten verwendet, um die Interaktion und das Feedback zu vervollständigen einiger Operationen. Mein intuitives Gefühl bei dieser Plattform ist, dass sie auf technischer Ebene Vue ähnelt, aber weitaus weniger leistungsfähig als Vue ist; die Entwicklungsideen ähneln nicht denen von Vue, sondern eher dem Rückgrat. Daher wird es Personen, die MVC- und MVVM-Frameworks wie Backbone und Vue verwendet haben, leicht fallen, mit dieser Plattform zu beginnen. In diesem Artikel werden hauptsächlich einige wichtige Punkte der Implementierung dieser Aufgaben-App vorgestellt.
Fügen Sie zunächst die Informationen zu diesem Artikel hinzu:
Offizielles Dokument: https://mp.weixin.qq.com/debug/wxadoc/dev/index.html
Offizieller Download des Entwicklertools: https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html
Funktionsdemonstration der ToDo-App in diesem Artikel:
Hinweis: Sie müssen lange auf den Aufgabentext drücken, um ihn direkt zu bearbeiten. Da es sich um ein Mobiltelefon handelt, können Sie das Doppelklick-Ereignis nicht zum Bearbeiten verwenden und es in ein Langdruck-Ereignis ändern. Die Miniprogramm-Plattform sieht auch keine Bindung für Double-Click-Events vor.
Zugehöriger Quellcode: https://github.com/liuyunzhuge/blog/tree/master/todos/wx
Wenn Sie dieses Projekt lokal ausführen möchten, müssen Sie den Entwickler installieren Erstellen Sie zunächst gemäß der Beschreibung des einfachen Tutorials ein Projekt.
Nachdem die Konstruktion abgeschlossen ist, öffnet das Entwicklertool den Ordner des erstellten Projekts Festplatte, kopieren Sie den gesamten Inhalt und fügen Sie alle Dateien in den Quellcode-Ordner oben ein.
Öffnen Sie dann die Entwicklertools erneut, rufen Sie zuerst die Registerkarte „Bearbeiten“ auf und klicken Sie dann auf die Schaltfläche „Kompilieren“. Sie gelangen direkt zur Debugging-Oberfläche So zeigen Sie die App-Funktion an:
4. Keine bidirektionale Bindung. In Vue ist eine Vue-Instanz ein Ansichtsmodell. Aktualisierungen der Daten in der Ansichtsebene werden in Echtzeit an das Modell zurückgegeben. Im Miniprogramm gibt es keine bidirektionale Bindung und die Aktualisierung der Ansicht wird nicht direkt mit dem Modell synchronisiert. Sie müssen die Daten direkt aus der Ansichtsebene im entsprechenden Ereignisrückruf abrufen und dann das Modell aktualisieren über setData. Das Miniprogramm verwendet dann intern setData. Für ein einzelnes Aufgabenelement lautet die Umschaltoperation beispielsweise:
toggleTodo: function( e ) { var id = this.getTodoId( e, 'todo-item-chk-' ); var value = e.detail.value[ 0 ]; var complete = !!value; var todo = this.getTodo( id ); todo.complete = complete; this.updateData( true ); this.updateStorage(); },
Im obigen Code wird der Wert des Kontrollkästchens in einem einzelnen Aufgabenelement über e.detail abgerufen .value[0], und dieser Wert wird verwendet, um den vollständigen Status von todo zu bestimmen. Schließlich wird innerhalb von updateData der Inhalt des Modells über die setData-Methode aktualisiert. Nur so werden die Statistiken am unteren Rand der App nach dem Umschaltvorgang aktualisiert.
5. Bei der Ereignisbindung können keine Parameter übergeben werden, sondern nur ein Ereignis. Im obigen Umschaltvorgang wollte ich beispielsweise eigentlich die ID der aktuellen Aufgabe an den Rückruf übergeben, konnte dies jedoch nicht auf jede erdenkliche Weise tun. Am Ende konnte ich es nur über die ID-Methode handhaben: Bindung Fügen Sie in der Komponente des Ereignisses eine ID hinzu. Diese ID kann nicht auf der gesamten Seite wiederholt werden. Daher muss der ID ein Präfix vorangestellt werden. Fügen Sie dann den Todo-ID-Wert am Ende der ID hinzu , kann über e.currentTarget.id abgerufen werden. Entfernen Sie für die ID der Komponente das entsprechende ID-Präfix, um den ID-Wert der Aufgabe zu erhalten. Dies ist eine derzeit verwendete Methode, die meiner Meinung nach nicht sehr elegant ist. Ich hoffe, dass ich später einen besseren Weg finden kann, sie umzusetzen.
6. Der Ladeeffekt wird in der App berücksichtigt, was durch die Verwendung des Ladeattributs der Schaltflächenkomponente erreicht werden muss. Beim Laden handelt es sich jedoch nur um ein Stilsteuerelement. Es steuert nicht, ob die Schaltfläche wiederholt angeklickt werden kann. Daher müssen wir auch das Attribut „disabled“ der Schaltfläche verwenden, um wiederholte Klicks zu verhindern.
Die restlichen Implementierungsdetails finden Sie im Quellcode der folgenden beiden Dateien. Gerne können Sie auf die Probleme hinweisen.
Quellcode von index.wxml:
<!--list.wxml--><view class="container"> <view class="app-hd"> <view class="fx1"> <input class="new-todo-input" value="{{newTodoText}}" auto-focus bindinput="newTodoTextInput"/> </view> <button type="primary" size="mini" bindtap="addOne" loading="{{addOneLoading}}" disabled="{{addOneLoading}}"> + Add </button> </view> <view class="todos-list" > <view class="todo-item {{index == 0 ? '' : 'todo-item-not-first'}} {{todo.complete ? 'todo-item-complete' : ''}}" wx:for="{{todos}}" wx:for-item="todo"> <view wx-if="{{!todo.editing}}"> <checkbox-group id="todo-item-chk-{{todo.id}}" bindchange="toggleTodo"> <label class="checkbox"> <checkbox value="1" checked="{{todo.complete}}"/> </label> </checkbox-group> </view> <view id="todo-item-txt-{{todo.id}}" class="todo-text" wx-if="{{!todo.editing}}" bindlongtap="startEdit"> <text>{{todo.text}}</text> </view> <view wx-if="{{!todo.editing}}"> <button id="btn-del-item-{{todo.id}}" bindtap="clearSingle" type="warn" size="mini" loading="{{todo.loading}}" disabled="{{todo.loading}}"> Clear </button> </view> <input id="todo-item-edit-{{todo.id}}" class="todo-text-input" value="{{todo.text}}" auto-focus bindblur="endEditTodo" wx-if="{{todo.editing}}"/> </view> </view> <view class="app-ft" wx:if="{{todos.length > 0}}"> <view class="fx1"> <checkbox-group bindchange="toggleAll"> <label class="checkbox"> <checkbox value="1" checked="{{todosOfUncomplted.length == 0}}"/> </label> </checkbox-group> <text>{{todosOfUncomplted.length}} left.</text> </view> <view wx:if="{{todosOfComplted.length > 0}}"> <button type="warn" size="mini" bindtap="clearAll" loading="{{clearAllLoading}}" disabled="{{clearAllLoading}}"> Clear {{todosOfComplted.length}} of done. </button> </view> </view> <loading hidden="{{loadingHidden}}" bindchange="loadingChange"> {{loadingText}} </loading> <toast hidden="{{toastHidden}}" bindchange="toastChange"> {{toastText}} </toast></view>
Quellcode von index.js:
var app = getApp(); Page( { data: { todos: [], todosOfUncomplted: [], todosOfComplted: [], newTodoText: '', addOneLoading: false, loadingHidden: true, loadingText: '', toastHidden: true, toastText: '', clearAllLoading: false }, updateData: function( resetTodos ) { var data = {}; if( resetTodos ) { data.todos = this.data.todos; } data.todosOfUncomplted = this.data.todos.filter( function( t ) { return !t.complete; }); data.todosOfComplted = this.data.todos.filter( function( t ) { return t.complete; }); this.setData( data ); }, updateStorage: function() { var storage = []; this.data.todos.forEach( function( t ) { storage.push( { id: t.id, text: t.text, complete: t.complete }) }); wx.setStorageSync( 'todos', storage ); }, onLoad: function() { this.setData( { todos: wx.getStorageSync( 'todos' ) || [] }); this.updateData( false ); }, getTodo: function( id ) { return this.data.todos.filter( function( t ) { return id == t.id; })[ 0 ]; }, getTodoId: function( e, prefix ) { return e.currentTarget.id.substring( prefix.length ); }, toggleTodo: function( e ) { var id = this.getTodoId( e, 'todo-item-chk-' ); var value = e.detail.value[ 0 ]; var complete = !!value; var todo = this.getTodo( id ); todo.complete = complete; this.updateData( true ); this.updateStorage(); }, toggleAll: function( e ) { var value = e.detail.value[ 0 ]; var complete = !!value; this.data.todos.forEach( function( t ) { t.complete = complete; }); this.updateData( true ); this.updateStorage(); }, clearTodo: function( id ) { var targetIndex; this.data.todos.forEach( function( t, i ) { if( targetIndex !== undefined ) return; if( t.id == id ) { targetIndex = i; } }); this.data.todos.splice( targetIndex, 1 ); }, clearSingle: function( e ) { var id = this.getTodoId( e, 'btn-del-item-' ); var todo = this.getTodo( id ); todo.loading = true; this.updateData( true ); var that = this; setTimeout( function() { that.clearTodo( id ); that.updateData( true ); that.updateStorage(); }, 500 ); }, clearAll: function() { this.setData( { clearAllLoading: true }); var that = this; setTimeout( function() { that.data.todosOfComplted.forEach( function( t ) { that.clearTodo( t.id ); }); that.setData( { clearAllLoading: false }); that.updateData( true ); that.updateStorage(); that.setData( { toastHidden: false, toastText: 'Success' }); }, 500 ); }, startEdit: function( e ) { var id = this.getTodoId( e, 'todo-item-txt-' ); var todo = this.getTodo( id ); todo.editing = true; this.updateData( true ); this.updateStorage(); }, newTodoTextInput: function( e ) { this.setData( { newTodoText: e.detail.value }); }, endEditTodo: function( e ) { var id = this.getTodoId( e, 'todo-item-edit-' ); var todo = this.getTodo( id ); todo.editing = false; todo.text = e.detail.value; this.updateData( true ); this.updateStorage(); }, addOne: function( e ) { if( !this.data.newTodoText ) return; this.setData( { addOneLoading: true }); //open loading this.setData( { loadingHidden: false, loadingText: 'Waiting...' }); var that = this; setTimeout( function() { //close loading and toggle button loading status that.setData( { loadingHidden: true, addOneLoading: false, loadingText: '' }); that.data.todos.push( { id: app.getId(), text: that.data.newTodoText, compelte: false }); that.setData( { newTodoText: '' }); that.updateData( true ); that.updateStorage(); }, 500 ); }, loadingChange: function() { this.setData( { loadingHidden: true, loadingText: '' }); }, toastChange: function() { this.setData( { toastHidden: true, toastText: '' }); } });
Endlich benötigt Darüber hinaus wurde diese App innerhalb einer begrenzten Zeit auf der Grundlage der offiziellen Dokumente von WeChat entwickelt, sodass ich nicht weiß, ob die Implementierungsmethode angemessen ist. Ich verwende diese App nur, um die Nutzung der Mini-Programmplattform zu verstehen. Ich hoffe, dass die WeChat-Beamten einige umfassendere, vorzugsweise projektbasierte Demos starten können, um uns Entwicklern eine Best-Practice-Spezifikation auf Codeebene zu bieten. Freunde, die andere Entwicklungsideen haben, können mir gerne dabei helfen, die Probleme in meiner obigen Implementierung aufzuzeigen.
Um schnell mehr über die Verwendung von WeChat-Miniprogrammen zu erfahren, schauen Sie bitte auf der chinesischen PHP-Website nach verwandten Artikeln über eine Todos-App, die auf Basis des Miniprogramm-Frameworks entwickelt wurde!