摘要:知識點(diǎn)總結(jié)一實(shí)現(xiàn)頁面的緩存二移動端固定定位的解決方案三表單校驗(yàn)表單驗(yàn)證中文文檔橫向滑動的選項(xiàng)卡,以及輸入法定位相關(guān)的插件網(wǎng)當(dāng)?shù)谝粋€(gè)輸入框自動獲得光標(biāo)的時(shí)候,彈出的輸入法會把布局頂上去問題可以左右滑動的將項(xiàng)目中引入框架和插件當(dāng)?shù)谝粋€(gè)輸
======================知識點(diǎn)總結(jié)===========================
一、keep-alive(實(shí)現(xiàn)頁面的緩存) 二、 移動端固定定位的解決方案 三、 Vue表單校驗(yàn)[https://www.zhihu.com/questio...
99220](https://www.zhihu.com/questio... "Vue表單驗(yàn)證")
https://github.com/aweiu/vue-verify-pop
vue-validator中文文檔
https://github.com/kazupon/vu...
橫向滑動的tab選項(xiàng)卡,以及輸入法定位相關(guān)的JQ插件網(wǎng)http://jq22.com
當(dāng)?shù)谝粋€(gè)輸入框自動獲得光標(biāo)的時(shí)候,彈出的輸入法會把布局頂上去
問題1:可以左右滑動的tab將項(xiàng)目中引入Jq框架和tab插件
當(dāng)?shù)谝粋€(gè)輸入框自動獲得光標(biāo)的時(shí)候,彈出的輸入法會把布局頂上去?
給最外層盒子加上絕對定位,并且設(shè)置固定高度
.reg-layer { width: 100%; height: 360px; background: #ffffff; position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
再給登錄框設(shè)置固定
.login-main { width: 100%; height: 4rem; background-color: #ffffff; padding-top: 0.4rem; }怎么去加載一倍圖,二倍圖,三倍圖等
使用Retina.js
上拉刷新、下拉加載更多
VUe-Scroller
https://github.com/wangdahoo/...
登錄注冊VueJs保存token
判斷token失效
VueJs保存tokenhttp://blog.csdn.net/generon/...
https://segmentfault.com/q/10...
http://www.jb51.net/article/1...
http://shequ.jb51.net/q_1599....
Vue-cli proxyTable 解決開發(fā)環(huán)境的跨域問題http://blog.csdn.net/hsany330...
https://segmentfault.com/q/10...
使用localStorage解決vuex在頁面刷新后數(shù)據(jù)被清除的問題http://www.cnblogs.com/limeng...
如何在vue中實(shí)現(xiàn)路由跳轉(zhuǎn)判斷用戶權(quán)限功能?https://segmentfault.com/q/10...
Axioshttp://www.cnblogs.com/libin-...
Ju Network Status By JShttps://github.com/HubSpot/of...
https://segmentfault.com/a/11...
https://segmentfault.com/q/10...
http://wicg.github.io/netinfo/
Web App Noteshttp://blog.csdn.net/zhangxin...
Axios WebSite Addresshttp://www.kancloud.cn/yunye/...
No NetWork SPAhttps://github.com/NekR/offli...
VueJS Communication among brothershttp://www.cnblogs.com/zsongs...
webpack多頁應(yīng)用架構(gòu)系列https://segmentfault.com/a/11...
Vue-Cli配置文件分析http://blog.csdn.net/hongchh/...
http://blog.csdn.net/s8460049...
下拉刷新獲取VueScroller實(shí)例:this.$refs.my_scroller
顯示沒有更多數(shù)據(jù)了,在那個(gè)infinate()方法中調(diào)用done(true)就OK了
http://www.cnblogs.com/liangx...
http://m.codes51.com/article/...
Vue-Cli打包發(fā)布http://www.cnblogs.com/libin-...
http://www.tuicool.com/articl...
移動端-webkit-user-select:none導(dǎo)致input/textarea輸入框無法輸入http://www.qdfuns.com/notes/1...
http://www.jianshu.com/p/4108...
VueJs判斷Token過期http://www.tuicool.com/articl...
Axios中的delete請求https://github.com/pagekit/vu...
VueJs移動端圖片壓縮上傳https://my.oschina.net/myrain...
圖片壓縮插件
https://github.com/think2011/...
React Notehttp://www.runoob.com/react/r...
Refresh Current Page_this.$router.go(0);How I can config https in Vue-Cli
https://segmentfault.com/q/10...
use Vue-Scroller{ test: /vue-scroller.src.*?js$/, loader: "babel-loader" }
It can invoked inflate() method automatically when vue component is mounted,there is a way to solve this problem
this.$refs.my_scroller.finishInfinite(true);
Wechat share in VueJs Projectshttp://www.cnblogs.com/mingxi...
https://segmentfault.com/q/10...
微信公眾號https://mp.weixin.qq.com/cgi-...
UpLoad File In VueJshttps://github.com/marchFanta...
https://github.com/lian-yue/v...
https://github.com/mozilla/pd...
Show PDF In BroswerUsing Pdf.js
https://segmentfault.com/q/10...
https://github.com/mozilla/pd...
https://stackoverflow.com/que...
Show PDF In Broswer Codehttp://localhost:63342/pdf.js-gh-pages/examples/index.html?_ijt=s4h3uipnnk8bec8b1ddn82mqnn
it must be contain a canvas tag
import PDFJS from "pdfjs-dist"; showPDF(){ let pdfPath = "/static/compressed.tracemonkey-pldi-09.pdf"; let loadingTask = PDFJS.getDocument(pdfPath); loadingTask.promise.then(function (pdfDocument) { // Request a first page return pdfDocument.getPage(1).then(function (pdfPage) { console.log("pdfPage is :",pdfPage); // Display page on the existing canvas with 100% scale. let scale = 1.5; let viewport = pdfPage.getViewport(scale); let canvas = document.getElementsByClassName("theCanvas"); canvas.width = viewport.width; canvas.height = viewport.height; let ctx = canvas.getContext("2d"); let renderTask = pdfPage.render({ canvasContext: ctx, viewport: viewport }); return renderTask.promise; }); }).catch(function (reason) { console.error("Error: " + reason); }); },DownLoad files
https://www.npmjs.com/package...
PDF.js怎么一次性的加載完所有的pdf的內(nèi)容 在進(jìn)行文件(pdf、word)等的上傳中,怎么區(qū)分?http://blog.csdn.net/shenshen...
article/details/21626315
accept="application/msexcel" ----對應(yīng)上傳excel
accept="application/msword" ----對應(yīng)上傳word
accept="application/pdf" ----對應(yīng)上傳pdf
PDF.js Examplehttps://github.com/mozilla/pd...
PDF.js Frequently Asked Questionshttps://github.com/mozilla/pd...
PDFViewer.vue
viewer.js
/* Copyright 2016 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* globals PDFJS */ "use strict"; if (!PDFJS.PDFViewer || !PDFJS.getDocument) { alert("Please build the pdfjs-dist library using " + " `gulp dist-install`"); } PDFJS.useOnlyCssZoom = true; PDFJS.disableTextLayer = true; PDFJS.maxImageSize = 1024 * 1024; PDFJS.workerSrc = "../../../node_modules/pdfjs-dist/build/pdf.worker.js"; PDFJS.cMapUrl = "../../../node_modules/pdfjs-dist/cmaps/"; PDFJS.cMapPacked = true; //需要加載的pdf的文件 // var DEFAULT_URL = "https://cdn.rawgit.com/mozilla/pdf.js/c6e8ca86/test/pdfs/calrgb.pdf"; // var DEFAULT_URL = "http://192.168.0.200:8080/media/avatar/fluent-python.pdf"; var DEFAULT_SCALE_DELTA = 1.0; var MIN_SCALE = 0.25; var MAX_SCALE = 100.0; var DEFAULT_SCALE_VALUE = "auto"; var PDFViewerApplication = { pdfLoadingTask: null, pdfDocument: null, pdfViewer: null, pdfHistory: null, pdfLinkService: null, /** * Opens PDF document specified by URL. * @returns {Promise} - Returns the promise, which is resolved when document * is opened. */ open: function (params) { if (this.pdfLoadingTask) { // We need to destroy already opened document return this.close().then(function () { // ... and repeat the open() call. return this.open(params); }.bind(this)); } var url = params.url; var self = this; this.setTitleUsingUrl(url); // Loading document. var loadingTask = PDFJS.getDocument(url); this.pdfLoadingTask = loadingTask; loadingTask.onProgress = function (progressData) { self.progress(progressData.loaded / progressData.total); }; return loadingTask.promise.then(function (pdfDocument) { // Document loaded, specifying document for the viewer. self.pdfDocument = pdfDocument; self.pdfViewer.setDocument(pdfDocument); self.pdfLinkService.setDocument(pdfDocument); self.pdfHistory.initialize(pdfDocument.fingerprint); self.loadingBar.hide(); self.setTitleUsingMetadata(pdfDocument); }, function (exception) { var message = exception && exception.message; var l10n = self.l10n; var loadingErrorMessage; if (exception instanceof PDFJS.InvalidPDFException) { // change error message also for other builds loadingErrorMessage = l10n.get("invalid_file_error", null, "Invalid or corrupted PDF file."); } else if (exception instanceof PDFJS.MissingPDFException) { // special message for missing PDFs loadingErrorMessage = l10n.get("missing_file_error", null, "Missing PDF file."); } else if (exception instanceof PDFJS.UnexpectedResponseException) { loadingErrorMessage = l10n.get("unexpected_response_error", null, "Unexpected server response."); } else { loadingErrorMessage = l10n.get("loading_error", null, "An error occurred while loading the PDF."); } loadingErrorMessage.then(function (msg) { self.error(msg, {message: message}); }); self.loadingBar.hide(); }); }, /** * Closes opened PDF document. * @returns {Promise} - Returns the promise, which is resolved when all * destruction is completed. */ close: function () { var errorWrapper = document.getElementById("errorWrapper"); errorWrapper.setAttribute("hidden", "true"); if (!this.pdfLoadingTask) { return Promise.resolve(); } var promise = this.pdfLoadingTask.destroy(); this.pdfLoadingTask = null; if (this.pdfDocument) { this.pdfDocument = null; this.pdfViewer.setDocument(null); this.pdfLinkService.setDocument(null, null); } return promise; }, get loadingBar() { var bar = new PDFJS.ProgressBar("#loadingBar", {}); return PDFJS.shadow(this, "loadingBar", bar); }, setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) { this.url = url; var title = PDFJS.getFilenameFromUrl(url) || url; try { title = decodeURIComponent(title); } catch (e) { // decodeURIComponent may throw URIError, // fall back to using the unprocessed url in that case } this.setTitle(title); }, setTitleUsingMetadata: function (pdfDocument) { var self = this; pdfDocument.getMetadata().then(function(data) { var info = data.info, metadata = data.metadata; self.documentInfo = info; self.metadata = metadata; // Provides some basic debug information console.log("PDF " + pdfDocument.fingerprint + " [" + info.PDFFormatVersion + " " + (info.Producer || "-").trim() + " / " + (info.Creator || "-").trim() + "]" + " (PDF.js: " + (PDFJS.version || "-") + (!PDFJS.disableWebGL ? " [WebGL]" : "") + ")"); var pdfTitle; if (metadata && metadata.has("dc:title")) { var title = metadata.get("dc:title"); // Ghostscript sometimes returns "Untitled", so prevent setting the // title to "Untitled. if (title !== "Untitled") { pdfTitle = title; } } if (!pdfTitle && info && info["Title"]) { pdfTitle = info["Title"]; } if (pdfTitle) { self.setTitle(pdfTitle + " - " + document.title); } }); }, /** * 設(shè)置title標(biāo)題 * @param title */ setTitle: function pdfViewSetTitle(title) { document.title = title; console.log("document.title:",document.title,document,document.getElementById("title").textContent); if(document.getElementById("title").textContent!==""){ document.getElementById("title").textContent = title; } }, error: function pdfViewError(message, moreInfo) { var l10n = this.l10n; var moreInfoText = [l10n.get("error_version_info", {version: PDFJS.version || "?", build: PDFJS.build || "?"}, "PDF.js v{{version}} (build: {{build}})")]; if (moreInfo) { moreInfoText.push( l10n.get("error_message", {message: moreInfo.message}, "Message: {{message}}")); if (moreInfo.stack) { moreInfoText.push( l10n.get("error_stack", {stack: moreInfo.stack}, "Stack: {{stack}}")); } else { if (moreInfo.filename) { moreInfoText.push( l10n.get("error_file", {file: moreInfo.filename}, "File: {{file}}")); } if (moreInfo.lineNumber) { moreInfoText.push( l10n.get("error_line", {line: moreInfo.lineNumber}, "Line: {{line}}")); } } } var errorWrapper = document.getElementById("errorWrapper"); errorWrapper.removeAttribute("hidden"); var errorMessage = document.getElementById("errorMessage"); errorMessage.textContent = message; var closeButton = document.getElementById("errorClose"); closeButton.onclick = function() { errorWrapper.setAttribute("hidden", "true"); }; var errorMoreInfo = document.getElementById("errorMoreInfo"); var moreInfoButton = document.getElementById("errorShowMore"); var lessInfoButton = document.getElementById("errorShowLess"); moreInfoButton.onclick = function() { errorMoreInfo.removeAttribute("hidden"); moreInfoButton.setAttribute("hidden", "true"); lessInfoButton.removeAttribute("hidden"); errorMoreInfo.style.height = errorMoreInfo.scrollHeight + "px"; }; lessInfoButton.onclick = function() { errorMoreInfo.setAttribute("hidden", "true"); moreInfoButton.removeAttribute("hidden"); lessInfoButton.setAttribute("hidden", "true"); }; moreInfoButton.removeAttribute("hidden"); lessInfoButton.setAttribute("hidden", "true"); Promise.all(moreInfoText).then(function (parts) { errorMoreInfo.value = parts.join(" "); }); }, progress: function pdfViewProgress(level) { var percent = Math.round(level * 100); // Updating the bar if value increases. if (percent > this.loadingBar.percent || isNaN(percent)) { this.loadingBar.percent = percent; } }, get pagesCount() { return this.pdfDocument.numPages; }, set page(val) { this.pdfViewer.currentPageNumber = val; }, get page() { return this.pdfViewer.currentPageNumber; }, zoomIn: function pdfViewZoomIn(ticks) { var newScale = this.pdfViewer.currentScale; do { newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2); newScale = Math.ceil(newScale * 10) / 10; newScale = Math.min(MAX_SCALE, newScale); } while (--ticks && newScale < MAX_SCALE); this.pdfViewer.currentScaleValue = newScale; }, zoomOut: function pdfViewZoomOut(ticks) { var newScale = this.pdfViewer.currentScale; do { newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2); newScale = Math.floor(newScale * 10) / 10; newScale = Math.max(MIN_SCALE, newScale); } while (--ticks && newScale > MIN_SCALE); this.pdfViewer.currentScaleValue = newScale; }, initUI: function pdfViewInitUI() { var linkService = new PDFJS.PDFLinkService(); this.pdfLinkService = linkService; this.l10n = PDFJS.NullL10n; var container = document.getElementById("viewerContainer"); var pdfViewer = new PDFJS.PDFViewer({ container: container, linkService: linkService, l10n: this.l10n, }); this.pdfViewer = pdfViewer; linkService.setViewer(pdfViewer); this.pdfHistory = new PDFJS.PDFHistory({ linkService: linkService }); linkService.setHistory(this.pdfHistory); document.getElementById("previous").addEventListener("click", function() { PDFViewerApplication.page--; }); document.getElementById("next").addEventListener("click", function() { PDFViewerApplication.page++; }); document.getElementById("zoomIn").addEventListener("click", function() { PDFViewerApplication.zoomIn(); }); document.getElementById("zoomOut").addEventListener("click", function() { PDFViewerApplication.zoomOut(); }); document.getElementById("pageNumber").addEventListener("click", function() { this.select(); }); document.getElementById("pageNumber").addEventListener("change", function() { PDFViewerApplication.page = (this.value | 0); // Ensure that the page number input displays the correct value, even if the // value entered by the user was invalid (e.g. a floating point number). if (this.value !== PDFViewerApplication.page.toString()) { this.value = PDFViewerApplication.page; } }); container.addEventListener("pagesinit", function () { // We can use pdfViewer now, e.g. let"s change default scale. pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE; }); container.addEventListener("pagechange", function (evt) { var page = evt.pageNumber; var numPages = PDFViewerApplication.pagesCount; document.getElementById("pageNumber").value = page; document.getElementById("previous").disabled = (page <= 1); document.getElementById("next").disabled = (page >= numPages); }, true); } }; document.addEventListener("DOMContentLoaded", function () { PDFViewerApplication.initUI(); }, true); (function animationStartedClosure() { // The offsetParent is not set until the PDF.js iframe or object is visible. // Waiting for first animation. PDFViewerApplication.animationStartedPromise = new Promise( function (resolve) { window.requestAnimationFrame(resolve); }); })(); /*// We need to delay opening until all HTML is loaded. PDFViewerApplication.animationStartedPromise.then(function () { PDFViewerApplication.open({ url: DEFAULT_URL }); });*/ export default PDFViewerApplication;VueJs防止頁面出現(xiàn)閃爍的情況
v-cloak指令
http://cn.vuejs.org/v2/api/#v...
處理TextArea自動隨文本高度自適應(yīng)高度https://github.com/jackmoore/...
PC端與移動端中option的寬度問題 搜索布局的問題----子組件去解決路由切換(tab切換)實(shí)現(xiàn)不同的布局
VueJs NextTick的妙用https://segmentfault.com/a/11...
回到原來的滾動位置以及回到頂部(待完善)當(dāng)路處于離開狀態(tài)的時(shí)候,存儲滾動的位置
當(dāng)路由處于進(jìn)入狀態(tài)的時(shí)候,取出滾動位置進(jìn)行判斷,來顯示或隱藏“返回頂部”的按鈕
VueJs自動化測試https://segmentfault.com/a/11...
https://github.com/ccforward/...
Web App中一行文字顯示不下,左邊用...表示https://segmentfault.com/q/10...
刷新當(dāng)前頁面this.$router.go(0);
VueJs打包優(yōu)化https://www.zhihu.com/questio...
WebPack中靜態(tài)資源url的配置http://www.cnblogs.com/chengd...
Vue-Cli webpack配置http://www.tuicool.com/articl...
移動端富文本框的集成https://quilljs.com/playground/
vue-html5-editor
Vue-Router中push與replace的區(qū)別與聯(lián)系https://segmentfault.com/q/10...
VueJs富文本框(發(fā)帖功能)移動端:https://github.com/surmon-chi...
https://github.com/PeakTai/vu...
div設(shè)置了contentEditable屬性。android上正常,IOS上出現(xiàn)問題使用div來模擬input或者textarea來進(jìn)行內(nèi)容輸入的操作,實(shí)現(xiàn)富文本框的功能
遇到問題
加入style="-webkit-user-select: auto"就能出現(xiàn)光標(biāo)和編輯了
Vuejs-Cordova-Framework-Webapphttp://blog.gxxsite.com/vuejs...
vue-cordova
Css-Scroller(效果圖,暫時(shí)不用在項(xiàng)目中)https://github.com/xiaoluobod...
Scroll開源庫實(shí)現(xiàn)列表滾動動畫https://github.com/hakimel/st...
H5控制禁止橫屏http://www.jianshu.com/p/9c32...
文件上傳(do not)https://github.com/marchFanta...
window.open被攔截問題(完成)通過借用a標(biāo)簽并產(chǎn)生隨機(jī)的target去實(shí)現(xiàn)
`
s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); }, JsGuid() { return this.s4() + this.s4() + "-" + this.s4() + "-" + this.s4() + "-" + this.s4() + "-" + this.s4() + this.s4() + this.s4(); }, newWin(url, id,target) { let a = document.createElement("a"); a.setAttribute("href", url); a.setAttribute("target", target); a.setAttribute("id", id); // 防止反復(fù)添加 if(!document.getElementById(id)) { document.body.appendChild(a); } a.click(); },
`
調(diào)用
this.newWin(localStorage.getItem("url"),"dow","csa"+this.JsGuid());
log工具類(便于在開發(fā)過程中進(jìn)行調(diào)試打印),在上線后將所有l(wèi)og信息隱藏
code
/**
Created by THINK on 2017/7/3.
日志工具類:開發(fā)階段將flag設(shè)置為true(可以看見log),上線后將flag設(shè)置為false(看不見log)
@author:darkCode
@description:it is a logcat tool,you can use it see all logs you want to see conveniently when developing,and you can hide all logs by set the value of flag is false in this instance when producting
*/ let logUtil = { flag:true, printLog(...items){ if(this.flag){ console.log(items); } } } export default logUtil修復(fù)上拉刷新,下拉加載
vue-scroller(自動地去進(jìn)行了加載更多(bug))
對項(xiàng)目進(jìn)行優(yōu)化性的操作代碼復(fù)用
資源的處理
安卓模擬器測試安裝問題:進(jìn)入Bios系統(tǒng)設(shè)置硬件虛擬化
虛擬化技術(shù)的可以在BIOS中開啟,開啟方法如下:
1、進(jìn)入BIOS。開機(jī)時(shí)按F2或F12或DEL或ESC等鍵(各電腦有所不同)。 2、進(jìn)入BIOS后,找到Configuration選項(xiàng),選擇Intel Virtual Technology并回車,將光標(biāo)移至Enabled,然后再回車,最后按F10保存并退出。 如果找不到Configuration選項(xiàng),可以試試下面的方法: (1)某些HP(惠普)電腦進(jìn)入BIOS后,需要選擇SystemConfiguration(系統(tǒng)配置)菜單,然后選擇Device Configuration(設(shè)備配置),找到Virtualization Technology,設(shè)置為Enabled。 (2)某些聯(lián)想Thinkpad電腦進(jìn)入BIOS后,需要選擇Security菜單,然后選擇Virtualization,設(shè)置為Enabled。 (3)某些DELL(戴爾)電腦進(jìn)入BIOS后,需要選擇Processor Settings菜單,然后選擇VirtualizationTechnology,設(shè)置為Enabled。 虛擬化在1960年為了描述虛擬機(jī)(實(shí)驗(yàn)性的IBM M44/44X系統(tǒng))這個(gè)概念被第一次提出。對虛擬機(jī)的架設(shè)和管理被稱為平臺虛擬化,現(xiàn)在也被稱為服務(wù)器虛擬化。將業(yè)務(wù)邏輯代碼與三方代碼分開進(jìn)行打包
在entry入口中配置,如分離jQuery
使用vue-cli打包后默認(rèn)生產(chǎn)三個(gè)js文件
app.43fcdsfcafds.js:項(xiàng)目中你編寫的業(yè)務(wù)邏輯的代碼
vender.20deewdew32eed.js:通過npm install下載依賴的js,css代碼(node_modules目錄下)
manifest.4cbcd0f5d52237fb29b0.js:緩存檢測文件,每次打包,通過該文件進(jìn)行版本的檢測
將生產(chǎn)環(huán)境與開發(fā)環(huán)境中的資源打包使用
vender:3.34m app:1.26m,怎么去減少它們的體積
vender.xsaxsxx.js.map文件的作用
source map文件是js文件壓縮后,文件的變量名替換對應(yīng)、變量所在位置等元信息數(shù)據(jù)文件,一般這種文件和min.js主文件放在同一個(gè)目錄下。 比如壓縮后原變量是map,壓縮后通過變量替換規(guī)則可能會被替換成a,這時(shí)source map文件會記錄下這個(gè)mapping的信息,這樣的好處就是說,在調(diào)試的時(shí)候,如果有一些JS報(bào)錯(cuò),那么瀏覽器會通過解析這個(gè)map文件來重新merge壓縮后的js,使開發(fā)者可以用未壓縮前的代碼來調(diào)試,這樣會給我們帶來很大的方便!
文件的按需加載(搞定)---項(xiàng)目優(yōu)化的一大步
根據(jù)vue的路由去按需加載組件
http://www.cnblogs.com/Nutrie...
vue組件的按需加載:解決了打包過后app.xscs3243rcds.js文件過大的缺點(diǎn)
進(jìn)一步優(yōu)化(三方不太動的js文件,通過cdn去加載)
引用相同的模塊,打包后出現(xiàn)重復(fù)的資源,將三方的多帶帶進(jìn)行打包
WebPack代碼分割https://zhuanlan.zhihu.com/p/...
WebPack中文網(wǎng)https://doc.webpack-china.org...
VueJs Seo(Nuxt.js)https://segmentfault.com/a/11...
https://segmentfault.com/q/10...
WeChat微信分享http://blog.csdn.net/rj0902/a...
http://blog.csdn.net/kexiuyi/...
http://blog.csdn.net/u0132921...
http://www.jb51.net/article/1...
http://www.cnblogs.com/mingxi... cool)
微信網(wǎng)頁授權(quán)
https://mp.weixin.qq.com/wiki...
Vue-Cli中引入weixin-js-sdkhttps://www.npmjs.com/package...
蘋果手機(jī)上設(shè)置分享的title的問題
https://www.deboy.cn/set-wech...
微信分享
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
問題1:判斷是否是微信瀏覽器打開應(yīng)用,是,需要動態(tài)去設(shè)置帖子詳情頁的分享界面
isWeiXin(){ //判斷是否是微信瀏覽器 let ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) === "micromessenger") { return true; } else { return false; } },
分享實(shí)現(xiàn)流程
①安裝微信sdk npm install weixin-js-sdk --save-dev
②通過import或者require的方式將其引入到需要的組件中
③獲取簽名相關(guān)的信息
④通過config接口注入權(quán)限驗(yàn)證配置
wx.config({ debug: true, appId: "", // 必填,公眾號的唯一標(biāo)識 timestamp: , // 必填,生成簽名的時(shí)間戳 nonceStr: "", // 必填,生成簽名的隨機(jī)串 signature: "",// 必填,簽名,見附錄1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 });
⑤通過ready接口處理成功驗(yàn)證
wx.ready(function(){ // config信息驗(yàn)證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個(gè)客戶端的異步操作,所以如果需要在頁面加載時(shí)就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對于用戶觸發(fā)時(shí)才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。 //進(jìn)行分享的操作 //分享到朋友圈 wx.onMenuShareTimeline({ title: "測試信息", // 分享標(biāo)題 link: "", // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致 imgUrl: "", // 分享圖標(biāo) success: function (res) { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("分享到朋友圈成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("取消分享到朋友圈返回的信息為:",res); } }); //分享給朋友 wx.onMenuShareAppMessage({ title: "", // 分享標(biāo)題 desc: "", // 分享描述 link: "", // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致 imgUrl: "", // 分享圖標(biāo) type: "", // 分享類型,music、video或link,不填默認(rèn)為link dataUrl: "", // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認(rèn)為空 success: function (res) { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("分享給朋友成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("取消分享給朋友返回的信息為:",res); } }); //分享到QQ wx.onMenuShareQQ({ title: "", // 分享標(biāo)題 desc: "", // 分享描述 link: "", // 分享鏈接 imgUrl: "", // 分享圖標(biāo) success: function (res) { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("分享到QQ好友成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("取消分享給QQ好友返回的信息為:",res); } }); //分享到QQ空間 wx.onMenuShareQZone({ title: "", // 分享標(biāo)題 desc: "", // 分享描述 link: "", // 分享鏈接 imgUrl: "", // 分享圖標(biāo) success: function (res) { // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("分享到QQ空間成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執(zhí)行的回調(diào)函數(shù) logUtil.printLog("取消分享到QQ空間返回的信息為:",res); } }); });
⑥通過error接口處理失敗驗(yàn)證
wx.error(function(res){
// config信息驗(yàn)證失敗會執(zhí)行error函數(shù),如簽名過期導(dǎo)致驗(yàn)證失敗,具體錯(cuò)誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名。 });
簽名由:noncestr(簽名隨機(jī)字符串,隨便寫)、jsapi_ticket(票據(jù))、timestamp(時(shí)間戳)、url(必須全部小寫)等組成
獲取access_token
請求接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret 請求方法: get 返回結(jié)果: access_token (有效期7200秒,必須在服務(wù)端緩存)
獲取票據(jù)jsapi_ticket
請求接口:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=上一步中獲取的access_token&type=jsapi 請求方法: get, type: JSON, 返回結(jié)果: jsapi_ticket (有效期7200秒,必須在服務(wù)端緩存)
生成時(shí)間戳(timestamp)
// 時(shí)間戳產(chǎn)生函數(shù) var timeStamp = function () { return parseInt(new Date().getTime() / 1000) + ""; };
簽名算法(可以參考官方給出的demo:https://github.com/arronf2e/j...)
比如:
var calcSignature =function(ticket,nonceStr,timeStamp,url) { var result = { jsapi_ticket: ticket, nonceStr: nonceStr, timestamp: timeStamp, url: url, } var str = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timeStamp + "&url=" + url; // 對str使用sha1簽名,得到signature,這里使用jsSHA模塊,需install shaObj = new jsSHA(str, "TEXT"); result.signature = shaObj.getHash("SHA-1", "HEX"); return result; // 返回到前端,提供接口由前端請求 }
接下來就返回給前端使用(在獲取簽名的時(shí)候需要傳遞url:用于簽名的(需要四個(gè)參數(shù)來實(shí)現(xiàn)簽名:時(shí)間戳、ticket、前端傳遞的動態(tài)的url、nonceStr) url(動態(tài)的)給后端)]
微信分享
微信分享問題總結(jié):
http://blog.csdn.net/u011743396/article/details/62427452
ngork
https://www.zhihu.com/question/25456655
問題描述
微信 jssdk 需要簽名,簽名的 URL 和將要分享的 URL 必須要一致才會簽名通過
url必須是當(dāng)前網(wǎng)頁的url不包含#及其后面部分(http://blog.sina.com.cn/s/blo...
ip地址查詢:http://site.ip138.com
python sha1簽名
http://blog.csdn.net/u014368609/article/details/50679818
js獲取當(dāng)前時(shí)間、時(shí)間戳
http://www.cnblogs.com/Man-Dream-Necessary/p/6369469.html
Vue路由按需加載
http://www.jb51.net/article/1...
注意事項(xiàng)
需要在配置文件webpack.base.conf.js中加入
output:{ pathinfo: true }
Vue服務(wù)端渲染
http://www.cnblogs.com/wangsh...
后臺管理
https://github.com/almasaeed2...
Axios下的接口封裝get操作,如:
import axios from "axios"; /** * 獲取積分信息 * @param url * @returns {*} */ export function getJiFenDetailInfo(url) { return axios.get(url).then((res)=>{ return Promise.resolve(res); },(err)=>{ return Promise.reject(err); }); }
post操作,如:
import axios from "axios"; /** * 處理登錄 * @param url * @param mobile * @param password * @returns {*} */ export function dealLogin(url,mobile,password) { return axios.post(url,{ mobile:mobile, password:password }).then((res)=>{ return Promise.resolve(res); },(err)=>{ return Promise.reject(err); }); }基于VueJs的后臺管理
https://github.com/PanJiaChen...
https://github.com/vue-bulma/...
https://github.com/taylorchen...
移動端html2canvas生成圖片轉(zhuǎn)換為File對象兼容處理涉及點(diǎn):Base64轉(zhuǎn)換為file對象
/** * 將Base64轉(zhuǎn)換為file對象 * @param dataurl:文件的base64表示 * @param filename:文件名 * @return {File}:返回的file對象 */ dataURLtoFile(dataurl, filename) { var arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, {type:mime}); },
發(fā)現(xiàn)ios低版本出現(xiàn)了兼容問題,最終發(fā)現(xiàn)問題出在new File()這里。那么就得想其他解決辦法了,可以先將Base64進(jìn)行二進(jìn)制轉(zhuǎn)換操作,最終將二進(jìn)制轉(zhuǎn)換為File對象就可以解決。
/** * 將base64先轉(zhuǎn)換為二進(jìn)制對象 * */ dataURLtoBlob(dataurl) { var arr = dataurl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }, /** * 最后再將二進(jìn)制轉(zhuǎn)換為file對象 * */ blobToFile(theBlob, fileName){ theBlob.lastModifiedDate = new Date(); theBlob.name = fileName; return theBlob; },
it is done!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/83997.html
摘要:寫在前面經(jīng)過最近的初步閱讀,明白了的整體框架和部分源碼。的源碼很龐大,很多代碼看過之后很容易就會忘記,所以很有必要寫一份閱讀筆記。而且我也會努力寫好這份文檔,最終把整個(gè)的源碼讀完并寫一份全面的文檔出來。 寫在前面 經(jīng)過最近的初步閱讀,明白了Vuejs的整體框架和部分源碼。Vuejs的源碼很龐大,很多代碼看過之后很容易就會忘記,所以很有必要寫一份閱讀筆記。這份筆記會是逐步更新的,隨著我閱...
摘要:主顯示區(qū)我們在中先引用另外兩個(gè)組件并且修改路由配置組件姓名屬性性別種類身高體重捕獲成功請?zhí)钊胪暾`信息通過方法派發(fā)一個(gè)事件,用來保存新捕獲的精靈對于需添加并且設(shè)置名字與種類未填寫時(shí)無法提交。 花了兩周,看了許久的文檔和案例,還是要實(shí)踐一下,于是做了這個(gè)demo,設(shè)計(jì)就這樣看吧,我的設(shè)計(jì)水平真心不好T^T,一周目的demo是靜態(tài)的,二周目再搭建數(shù)據(jù)層。 項(xiàng)目倉庫:https://git...
摘要:中文官網(wǎng)英文官網(wǎng)組織發(fā)出一個(gè)問題之后,不要暫時(shí)的離開電腦,如果沒有把握先不要提問。珍惜每一次提問,感恩每一次反饋,每個(gè)人工作還是業(yè)余之外抽出的時(shí)間有限,充分準(zhǔn)備好應(yīng)有的資源之后再發(fā)問,有利于問題能夠高效質(zhì)量地得到解決。 Vue.js資源分享 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/maid...
摘要:觸發(fā)行為與相當(dāng)于。是具體改變狀態(tài)的行為,每次的可能被捕捉。而是通過發(fā)起執(zhí)行操作。因此異步行為放在。通過與具體的組件進(jìn)行綁定。但是,它規(guī)定了一些需要遵守的規(guī)則應(yīng)用層級的狀態(tài)應(yīng)該集中到單個(gè)對象中。提交是更改狀態(tài)的唯一方法,并且這個(gè)過程是同步的。 VUEX 概念 store / module state / getters mutations / actions payload: co...
閱讀 1697·2021-10-09 09:44
閱讀 3263·2021-09-27 13:36
閱讀 1520·2021-09-22 15:33
閱讀 1274·2021-09-22 15:23
閱讀 1159·2021-09-06 15:02
閱讀 1695·2019-08-29 16:14
閱讀 2901·2019-08-29 15:26
閱讀 2408·2019-08-28 18:08