Im WeChat-Applet-Projekt umfasst das Entwicklungsmodul die Funktion für handschriftliche Signaturen, und das WeChat-Applet-Canvas feiert sein Debüt Vorwort WeChat-Applet-Canvas implementiert Signaturfunktion Einführung in die Kerninhalte: (1) Signaturimplementierung, Start, Bewegung, Ende (2) Umschreiben (3) Vervollständigung (4) Hochladen 1. WeChat-Applet-Canvas implementiert SignaturfunktionWirkungsdemonstration: (1) Signaturimplementierung (2) Umschreiben (3) Vervollständigung Nach Abschluss das Bild an der entsprechenden Position anzeigen (4) Je nach Geschäftsbedarf können Sie Bilder in den Hintergrund hochladen und bei Bedarf anzeigen. 2. Code1. Alle Demos wxml <!--pages/canvas-test/canvas-test.wxml--> <Ansichtsklasse="handCenter"> <canvas class="handWriting" disable-scroll="true" bindtouchstart="uploadScaleStart" bindtouchmove="uploadScaleMove" bindtouchend="uploadScaleEnd" bindtap="mouseDown" canvas-id="handWriting"> </Leinwand> </Ansicht> <Ansichtsklasse="handBtn"> <button catchtap="retDraw" class="delBtn">Umschreiben</button> <button catchtap="subCanvas" class="subBtn">Fertig</button> </Ansicht> <Klasse anzeigen="Vorschau"> <Bild wx:if="{{tmpPath}}" Stil="Breite:100%;Höhe:100%;" src="{{tmpPath}}"></Bild> </Ansicht> js const app = getApp() const api = require('../../utils/request.js'); //relativer Pfad const apiEev = require('../../config/config'); Seite({ Daten: { Canvasname: 'Handschrift', ctx: '', Leinwandbreite: 0, Leinwandhöhe: 0, transparent: 1, // Transparenz selectColor: 'schwarz', lineColor: '#1A1A1A', // Farbe lineSize: 1.5, // mehrere beachten lineMin: 0.5, // minimaler Strichradius lineMax: 4, // maximaler Strichradius pressure: 1, // Standarddruck smoothness: 60, // Glätte, 60 % Distanz zur Berechnung der Geschwindigkeit verwenden currentPoint: {}, currentLine: [], // Aktuelle Zeile firstTouch: true, // Erster Trigger radius: 1, // Radius des Kreises cutArea: { top: 0, right: 0, bottom: 0, left: 0 }, // Schnittbereich bethelPoint: [], // Speichert die von allen Zeilen erzeugten Bézierpunkte; letzterPunkt: 0, chirography: [], //HandschriftcurrentChirography: {}, //aktuelle HandschriftlinePrack: [], //Linienbahn, tatsächlicher Punkt der generierten LinietmpPath:'' }, // Handschrift start uploadScaleStart (e) { wenn (e.Typ != 'touchstart') false zurückgibt; lass ctx = diese.Daten.ctx; ctx.setFillStyle(this.data.lineColor); // Anfängliche Linienfarbeinstellung ctx.setGlobalAlpha(this.data.transparent); // Transparenz festlegen let currentPoint = { x: e.berührt[0].x, y: e.berührt[0].y } lass aktuelleLinie = diese.Daten.aktuelleLinie; currentLine.unshift({ Zeit: neues Date().getTime(), Anzahl: 0, x: aktuellerPunkt.x, y: aktuellerPunkt.y }) dies.setData({ aktueller Punkt, // aktuelle Zeile }) wenn (diese.Daten.firstTouch) { dies.setData({ Schnittbereich: { oben: currentPoint.y, rechts: currentPoint.x, unten: currentPoint.y, links: currentPoint.x }, firstTouch: falsch }) } dies.pointToLine(aktuelleLinie); }, // Handschriftbewegung uploadScaleMove (e) { wenn (e.Typ != 'touchmove') false zurückgibt; wenn (z. B. stornierbar) { // Prüfen, ob das Standardverhalten deaktiviert wurde if (!e.defaultPrevented) { e.preventDefault(); } } lass Punkt = { x: e.berührt[0].x, y: e.berührt[0].y } //Schneiden testen if (point.y < this.data.cutArea.top) { this.data.cutArea.top = Punkt.y; } wenn (Punkt.y < 0) this.data.cutArea.top = 0; wenn (Punkt.x > diese.Daten.Schnittfläche.rechts) { this.data.cutArea.right = Punkt.x; } wenn (this.data.canvasWidth - point.x <= 0) { diese.data.cutArea.right = diese.data.canvasWidth; } wenn (Punkt.y > diese.Daten.Schnittfläche.unten) { this.data.cutArea.bottom = Punkt.y; } wenn (this.data.canvasHeight - point.y <= 0) { diese.Daten.cutArea.bottom = diese.Daten.canvasHeight; } wenn (Punkt.x < diese.Daten.Schnittfläche.links) { this.data.cutArea.left = Punkt.x; } wenn (Punkt.x < 0) this.data.cutArea.left = 0; dies.setData({ letzterPunkt: diese.Daten.aktuellerPunkt, aktuellerPunkt: Punkt }) let currentLine = diese.Daten.currentLine currentLine.unshift({ Zeit: neues Date().getTime(), dis: diese.Entfernung(diese.Daten.aktuellerPunkt, diese.Daten.letzterPunkt), x: Punkt.x, y: Punkt.y }) // dies.setData({ // aktuelle Zeile // }) dies.pointToLine(aktuelleLinie); }, // Die Handschrift endet uploadScaleEnd (e) { wenn (e.Typ != 'touchend') 0 zurückgibt; lass Punkt = { x: e.changedTouches[0].x, y: e.changedTouches[0].y } dies.setData({ letzterPunkt: diese.Daten.aktuellerPunkt, aktuellerPunkt: Punkt }) let currentLine = diese.Daten.currentLine currentLine.unshift({ Zeit: neues Date().getTime(), dis: diese.Entfernung(diese.Daten.aktuellerPunkt, diese.Daten.letzterPunkt), x: Punkt.x, y: Punkt.y }) // dies.setData({ // aktuelle Zeile // }) wenn (aktuelleZeilenlänge > 2) { var info = (aktuelleZeile[0].Zeit - aktuelleZeile[aktuelleZeile.Länge - 1].Zeit) / aktuelleZeile.Länge; //$("#info").text(info.toFixed(2)); } //Nachdem ein Strich abgeschlossen ist, speichere die Koordinatenpunkte der Handschrift, lösche sie und füge eine Prüfung hinzu, um festzustellen, ob sich die aktuelle Handschrift im Handschriftbereich befindet. dies.pointToLine(aktuelleLinie); var aktuelleChirographie = { Zeilengröße: this.data.lineSize, Linienfarbe: this.data.lineColor }; var chirography = diese.Daten.chirography chirography.unshift(aktuelleChirographie); dies.setData({ Chirographie }) var linePrack = diese.Daten.linePrack linePrack.unshift(diese.Daten.aktuelleZeile); dies.setData({ LiniePrack, aktuelleZeile: [] }) }, beim Laden () { let canvasName = this.data.canvasName let ctx = wx.createCanvasContext(Leinwandname) dies.setData({ ctx: ctx }) var query = wx.createSelectorQuery(); Abfrage.Select('.handCenter').boundingClientRect(rect => { dies.setData({ Leinwandbreite: rechteckige Breite, Leinwandhöhe: rechteckige Höhe }) }).exec(); }, unterLeinwand(){ // Füge mein let hinzu = dies lass ctx = diese.Daten.ctx; ctx.draw(true,setTimeout(function(){ //Mein neuer Timer und Rückruf wx.canvasToTempFilePath({ x: 0, y: 0, Breite: 375, Höhe: 152, CanvasId: "Handschrift", Dateityp: "png", Erfolg: Funktion (Res) { dass.setData({ tmpPfad:res.tempFilePath }) console.log(that.data.tmpPath,'sehen, was es ist') das.upImgs(das.data.tmpPath,0) } }, ctx) },1000)) }, // Füge den Pfad zum Hochladen des gespeicherten Bildes auf den Dateiserver hinzu upImgs: function (imgurl, index) { console.log(imgurl,'siehe den Pfad') var das = dies; wx.uploadDatei({ url: apiEev.api + 'xxxx', //Hintergrund-Upload-Pfad filePath: imgurl, Name: "Datei", Kopfzeile: { „Inhaltstyp“: „multipart/Formulardaten“ }, formData: null, Erfolg: Funktion (res) { console.log(res) //Schnittstelle gibt Netzwerkpfad zurück var data = JSON.parse(res.data) console.log(data,'sehen, was Daten sind') wenn (data.code == "erfolg") { console.log('Erfolg') } } }) }, retDraw() { diese.Daten.ctx.clearRect(0, 0, 700, 730) diese.Daten.ctx.draw() dies.setData({ tmpPfad:'' }) }, //Zeichnen Sie eine Linie zwischen zwei Punkten. Der Parameter lautet: Linie, wodurch die beiden nächstgelegenen Startpunkte gezeichnet werden. pointToLine (Linie) { this.calcBethelLine(Zeile); zurückkehren; }, //Berechnen Sie die Interpolationsmethode; calcBethelLine (Zeile) { if (Zeilenlänge <= 1) { Zeile[0].r = diese.Daten.Radius; zurückkehren; } sei x0, x1, x2, y0, y1, y2, r0, r1, r2, Länge, letzterRadius, dis = 0, Zeit = 0, Kurvenwert = 0,5; if (Zeilenlänge <= 2) { x0 = Zeile[1].x y0 = Zeile[1].y x2 = Zeile[1].x + (Zeile[0].x - Zeile[1].x) * Kurvenwert; y2 = Linie[1].y + (Linie[0].y - Linie[1].y) * Kurvenwert; //x2 = Zeile[1].x; //y2 = zeile[1].y; x1 = x0 + (x2 - x0) * Kurvenwert; y1 = y0 + (y2 - y0) * Kurvenwert;; } anders { x0 = Zeile[2].x + (Zeile[1].x - Zeile[2].x) * Kurvenwert; y0 = Linie[2].y + (Linie[1].y - Linie[2].y) * Kurvenwert; x1 = Zeile[1].x; y1 = Zeile[1].y; x2 = x1 + (Linie[0].x - x1) * Kurvenwert; y2 = y1 + (Linie[0].y - y1) * Kurvenwert; } //Aus der Berechnungsformel ergeben sich die drei Punkte (x0, y0), (x1, y1), (x2, y2); (x1, y1) ist der Kontrollpunkt, der nicht auf die Kurve fällt. Tatsächlich ist dieser Punkt auch der tatsächlich durch Handschrift erhaltene Punkt, aber er fällt auf die Kurve len = this.distance({ x: x2, y: y2 }, { x: x0, y: y0 }); letzterRadius = dieser.Datenradius; für (let n = 0; n < Zeilenlänge - 1; n++) { dis += Zeile[n].dis; Zeit += Zeile[n].Zeit - Zeile[n + 1].Zeit; wenn (dis > diese.Daten.Glattheit) abbrechen; } dies.setData({ Radius: Math.min(Zeit / Länge * dieser.Datendruck + dieses.Datenzeilenmin, dieses.Datenzeilenmax) * diese.Datenzeilengröße }); Zeile[0].r = diese.Daten.Radius; //Berechnen Sie den Handschriftradius; if (Zeilenlänge <= 2) { r0 = (letzterRadius + dieser.Datenradius) / 2; r1 = r0; r2 = r1; //zurückkehren; } anders { r0 = (Zeile[2].r + Zeile[1].r) / 2; r1 = Zeile[1].r; r2 = (Zeile[1].r + Zeile[0].r) / 2; } sei n = 5; lass Punkt = []; für (sei i = 0; i < n; i++) { sei t = i / (n – 1); sei x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2; sei y = (1 – t) * (1 – t) * y0 + 2 * t * (1 – t) * y1 + t * t * y2; sei r = letzterRadius + (this.data.radius - letzterRadius) / n * i; Punkt.drücken({ x: x, y: y, r: r }); wenn (Punkt.Länge == 3) { sei a = this.ctaCalc(Punkt[0].x, Punkt[0].y, Punkt[0].r, Punkt[1].x, Punkt[1].y, Punkt[1].r, Punkt[2].x, Punkt[2].y, Punkt[2].r); a[0].color = diese.Daten.Zeilenfarbe; // lass bethelPoint = diese.Daten.bethelPoint; // konsole.log(a) // Konsole.log(diese.Daten.bethelPoint) // bethelPoint = bethelPoint.push(a); dies.bethelDraw(a, 1); Punkt = [{ x: x, y: y, r: r }]; } } dies.setData({ currentLine: Zeile }) }, // Bestimme den Abstand zwischen zwei Punkten distance (a, b) { sei x = bx - ax; sei y = by - ay; gibt Math.sqrt(x * x + y * y) zurück; }, ctaCalc (x0, y0, r0, x1, y1, r1, x2, y2, r2) { sei a = [], vx01, vy01, Norm, n_x0, n_y0, vx21, vy21, n_x2, n_y2; vx01 = x1 - x0; vy01 = y1 - y0; Norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0,0001) * 2; vx01 = vx01 / Norm * r0; vy01 = vy01 / Norm * r0; n_x0 = vy01; n_y0 = -vx01; vx21 = x1 - x2; vy21 = y1 - y2; Norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0,0001) * 2; vx21 = vx21 / Norm * r2; vy21 = vy21 / Norm * r2; n_x2 = -vy21; n_y2 = vx21; a.push({ mx: x0 + n_x0, my: y0 + n_y0, Farbe: "#1A1A1A" }); a.push({ c1x: x1 + n_x0, c1y: y1 + n_y0, c2x: x1 + n_x2, c2y: y1 + n_y2, zB: x2 + n_x2, ey: y2 + n_y2 }); a.push({ c1x: x2 + n_x2 - vx21, c1y: y2 + n_y2 - vy21, c2x: x2 - n_x2 - vx21, c2y: y2 - n_y2 - vy21, Beispiel: x2 - n_x2, ey: y2 - n_y2 }); a.push({ c1x: x1 - n_x2, c1y: y1 - n_y2, c2x: x1 - n_x0, c2y: y1 - n_y0, zB: x0 - n_x0, ey: y0 - n_y0 }); a.push({ c1x: x0 - n_x0 - vx01, c1y: y0 - n_y0 - vy01, c2x: x0 + n_x0 - vx01, c2y: y0 + n_y0 - vy01, Beispiel: x0 + n_x0, ey: y0 + n_y0 }); a[0].mx = a[0].mx.toFixed(1); a[0].mx = parseFloat(a[0].mx); a[0].my = a[0].my.toFixed(1); a[0].mein = parseFloat(a[0].mein); für (sei i = 1; i < a.Länge; i++) { a[i].c1x = a[i].c1x.toFixed(1); a[i].c1x = parseFloat(a[i].c1x); a[i].c1y = a[i].c1y.toFixed(1); a[i].c1y = parseFloat(a[i].c1y); a[i].c2x = a[i].c2x.toFixed(1); a[i].c2x = parseFloat(a[i].c2x); a[i].c2y = a[i].c2y.toFixed(1); a[i].c2y = parseFloat(a[i].c2y); a[i].ex = a[i].ex.toFixed(1); a[i].ex = parseFloat(a[i].ex); a[i].ey = a[i].ey.toFixed(1); a[i].ey = parseFloat(a[i].ey); } gib a zurück; }, bethelDraw (Punkt, ist_Füllung, Farbe) { // Füge mein let hinzu = dies lass ctx = diese.Daten.ctx; ctx.beginPath(); ctx.moveTo(Punkt[0].mx, Punkt[0].my); if (undefiniert != Farbe) { ctx.setFillStyle(Farbe); ctx.setStrokeStyle(Farbe); } anders { ctx.setFillStyle(Punkt[0].Farbe); ctx.setStrokeStyle(Punkt[0].Farbe); } für (lass i = 1; i < Punkt.Länge; i++) { ctx.bezierCurveTo(Punkt[i].c1x, Punkt[i].c1y, Punkt[i].c2x, Punkt[i].c2y, Punkt[i].ex, Punkt[i].ey); } ctx.stroke(); if (undefiniert != is_fill) { ctx.fill(); //Grafiken füllen (die später gezeichneten Grafiken überdecken die vorherigen Grafiken, achte beim Zeichnen auf die Reihenfolge) } ctx.draw(wahr) }, selectColorEvent (Ereignis) { console.log(Ereignis) var Farbe = Ereignis.aktuellesTarget.dataset.colorValue; var colorSelected = event.currentTarget.dataset.color; dies.setData({ Farbe auswählen: FarbeAusgewählt, Linienfarbe: Farbe }) } }) /* Seiten/Canvas-Test2/Canvas-Test2.wxss */ .canvasId { Position: absolut; links: 50%; oben: 0; transformieren: übersetzen (-50 %); Z-Index: 1; Rand: 2px gestrichelt #ccc; Rahmenradius: 8px; Rand unten: 66px; } .handCenter { Rand: 1px durchgehend rot; } .handWriting { Breite: 100 %; } .Vorschau { Breite: 375px; Höhe: 152px; } 2. Analyse der Schlüsselteile (1) Grundlegende Implementierung von Signatur, Start, Verschiebung und Ende // Handschrift start uploadScaleStart (e) { wenn (e.Typ != 'touchstart') false zurückgibt; lass ctx = diese.Daten.ctx; ctx.setFillStyle(this.data.lineColor); // Anfängliche Linienfarbeinstellung ctx.setGlobalAlpha(this.data.transparent); // Transparenz festlegen let currentPoint = { x: e.berührt[0].x, y: e.berührt[0].y } lass aktuelleLinie = diese.Daten.aktuelleLinie; currentLine.unshift({ Zeit: neues Date().getTime(), Anzahl: 0, x: aktuellerPunkt.x, y: aktuellerPunkt.y }) dies.setData({ aktueller Punkt, // aktuelle Zeile }) wenn (diese.Daten.firstTouch) { dies.setData({ Schnittbereich: { oben: currentPoint.y, rechts: currentPoint.x, unten: currentPoint.y, links: currentPoint.x }, firstTouch: falsch }) } dies.pointToLine(aktuelleLinie); }, // Handschriftbewegung uploadScaleMove (e) { wenn (e.Typ != 'touchmove') false zurückgibt; wenn (z. B. stornierbar) { // Prüfen, ob das Standardverhalten deaktiviert wurde if (!e.defaultPrevented) { e.preventDefault(); } } lass Punkt = { x: e.berührt[0].x, y: e.berührt[0].y } //Schneiden testen if (point.y < this.data.cutArea.top) { this.data.cutArea.top = Punkt.y; } wenn (Punkt.y < 0) this.data.cutArea.top = 0; wenn (Punkt.x > diese.Daten.Schnittfläche.rechts) { this.data.cutArea.right = Punkt.x; } wenn (this.data.canvasWidth - point.x <= 0) { diese.data.cutArea.right = diese.data.canvasWidth; } wenn (Punkt.y > diese.Daten.Schnittfläche.unten) { this.data.cutArea.bottom = Punkt.y; } wenn (this.data.canvasHeight - point.y <= 0) { diese.Daten.cutArea.bottom = diese.Daten.canvasHeight; } wenn (Punkt.x < diese.Daten.Schnittfläche.links) { this.data.cutArea.left = Punkt.x; } wenn (Punkt.x < 0) this.data.cutArea.left = 0; dies.setData({ letzterPunkt: diese.Daten.aktuellerPunkt, aktuellerPunkt: Punkt }) let currentLine = diese.Daten.currentLine currentLine.unshift({ Zeit: neues Date().getTime(), dis: diese.Entfernung(diese.Daten.aktuellerPunkt, diese.Daten.letzterPunkt), x: Punkt.x, y: Punkt.y }) // dies.setData({ // aktuelle Zeile // }) dies.pointToLine(aktuelleLinie); }, // Die Handschrift endet uploadScaleEnd (e) { wenn (e.Typ != 'touchend') 0 zurückgibt; lass Punkt = { x: e.changedTouches[0].x, y: e.changedTouches[0].y } dies.setData({ letzterPunkt: diese.Daten.aktuellerPunkt, aktuellerPunkt: Punkt }) let currentLine = diese.Daten.currentLine currentLine.unshift({ Zeit: neues Date().getTime(), dis: diese.Entfernung(diese.Daten.aktuellerPunkt, diese.Daten.letzterPunkt), x: Punkt.x, y: Punkt.y }) // dies.setData({ // aktuelle Zeile // }) wenn (aktuelleZeilenlänge > 2) { var info = (aktuelleZeile[0].Zeit - aktuelleZeile[aktuelleZeile.Länge - 1].Zeit) / aktuelleZeile.Länge; //$("#info").text(info.toFixed(2)); } //Nachdem ein Strich abgeschlossen ist, speichere die Koordinatenpunkte der Handschrift, lösche sie und füge eine Prüfung hinzu, um festzustellen, ob sich die aktuelle Handschrift im Handschriftbereich befindet. dies.pointToLine(aktuelleLinie); var aktuelleChirographie = { Zeilengröße: this.data.lineSize, Linienfarbe: this.data.lineColor }; var chirography = diese.Daten.chirography chirography.unshift(aktuelleChirographie); dies.setData({ Chirographie }) var linePrack = diese.Daten.linePrack linePrack.unshift(diese.Daten.aktuelleZeile); dies.setData({ LiniePrack, aktuelleZeile: [] }) }, Denken Sie daran, zuerst in Onload zu initialisieren Nimm den Code und verwende ihn direkt (2) Neusignierung Im Klartext bedeutet es, die Leinwand zu leeren. retDraw() { diese.Daten.ctx.clearRect(0, 0, 700, 730) diese.Daten.ctx.draw() dies.setData({ tmpPfad:'' }) }, (3) Unterschrift erfolgt unterLeinwand(){ // Füge mein let hinzu = dies lass ctx = diese.Daten.ctx; ctx.draw(true,setTimeout(function(){ //Mein neuer Timer und Rückruf wx.canvasToTempFilePath({ x: 0, y: 0, Breite: 375, Höhe: 152, CanvasId: "Handschrift", Dateityp: "png", Erfolg: Funktion (Res) { dass.setData({ tmpPfad:res.tempFilePath }) console.log(that.data.tmpPath,'sehen, was es ist') das.upImgs(das.data.tmpPath,0) } }, ctx) },1000)) }, Wichtiger ist der darin enthaltene Rückruf:
(4) Je nach Geschäftsbedarf können Sie Bilder in den Hintergrund hochladen und bei Bedarf anzeigen. Der entscheidende Punkt ist, wie in den Hintergrund hochgeladen wird // Füge den Pfad zum Hochladen des gespeicherten Bildes auf den Dateiserver hinzu upImgs: function (imgurl, index) { console.log(imgurl,'siehe den Pfad') var das = dies; wx.uploadDatei({ url: apiEev.api + 'xxxx', //Hintergrunddatei-Uploadpfad Schnittstelle filePath: imgurl, Name: "Datei", Kopfzeile: { „Inhaltstyp“: „multipart/Formulardaten“ }, formData: null, Erfolg: Funktion (res) { console.log(res) //Schnittstelle gibt Netzwerkpfad zurück var data = JSON.parse(res.data) console.log(data,'sehen, was Daten sind') wenn (data.code == "erfolg") { console.log('Erfolg') } } }) }, Zusammenfassen Die WeChat-Miniprogramm-Canvas implementiert die Signaturfunktion. Besonderer Hinweis: Beim Debuggen und der Erfahrungsversion auf der realen Maschine kann es zu Verzögerungen kommen. Wenn möglich, veröffentlichen Sie es in der Vorabversion, um zu sehen, ob es die Leistung beeinträchtigt. Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird. Das könnte Sie auch interessieren:
|
<<: Eine kurze Diskussion über den magischen Schrägstrich im Nginx Reverse Proxy
>>: Tutorial zum Anmelden bei MySQL nach der Installation von Mysql 5.7.17
1. Hintergrund Wenn der Docker-Dienst gestartet w...
Erstellen Sie in MySQL eine neue Tabelle mit drei...
Port 80 ist ebenfalls konfiguriert. Geben Sie zun...
Inhaltsverzeichnis Herkunft Umweltinformationen F...
1. Erstellen Sie ein SpringBoot-Projekt und packe...
Vorwort Crond ist ein Tool zur geplanten Ausführu...
Viele Organisationen müssen Dateiserver sichern u...
1.Dies deutet auf 1. Wer ruft wen an? Beispiel: F...
In diesem Artikelbeispiel wird der spezifische Co...
1. Einleitung Die EXPLAIN-Anweisung liefert Infor...
Überblick Der grundlegende Unterschied zwischen a...
In diesem Artikelbeispiel wird der spezifische Co...
In diesem Artikelbeispiel wird der spezifische Co...
Ich habe vor Kurzem angefangen, das NestJs-Framew...
IIS7 Laden Sie das HTTP Rewrite-Modul von der off...