摘要:知識點總結一實現頁面的緩存二移動端固定定位的解決方案三表單校驗表單驗證中文文檔橫向滑動的選項卡,以及輸入法定位相關的插件網當第一個輸入框自動獲得光標的時候,彈出的輸入法會把布局頂上去問題可以左右滑動的將項目中引入框架和插件當第一個輸
======================知識點總結===========================
一、keep-alive(實現頁面的緩存) 二、 移動端固定定位的解決方案 三、 Vue表單校驗[https://www.zhihu.com/questio...
99220](https://www.zhihu.com/questio... "Vue表單驗證")
https://github.com/aweiu/vue-verify-pop
vue-validator中文文檔
https://github.com/kazupon/vu...
橫向滑動的tab選項卡,以及輸入法定位相關的JQ插件網http://jq22.com
當第一個輸入框自動獲得光標的時候,彈出的輸入法會把布局頂上去
問題1:可以左右滑動的tab將項目中引入Jq框架和tab插件
當第一個輸入框自動獲得光標的時候,彈出的輸入法會把布局頂上去?
給最外層盒子加上絕對定位,并且設置固定高度
.reg-layer { width: 100%; height: 360px; background: #ffffff; position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
再給登錄框設置固定
.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 解決開發環境的跨域問題http://blog.csdn.net/hsany330...
https://segmentfault.com/q/10...
使用localStorage解決vuex在頁面刷新后數據被清除的問題http://www.cnblogs.com/limeng...
如何在vue中實現路由跳轉判斷用戶權限功能?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多頁應用架構系列https://segmentfault.com/a/11...
Vue-Cli配置文件分析http://blog.csdn.net/hongchh/...
http://blog.csdn.net/s8460049...
下拉刷新獲取VueScroller實例:this.$refs.my_scroller
顯示沒有更多數據了,在那個infinate()方法中調用done(true)就OK了
http://www.cnblogs.com/liangx...
http://m.codes51.com/article/...
Vue-Cli打包發布http://www.cnblogs.com/libin-...
http://www.tuicool.com/articl...
移動端-webkit-user-select:none導致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的內容 在進行文件(pdf、word)等的上傳中,怎么區分?http://blog.csdn.net/shenshen...
article/details/21626315
accept="application/msexcel" ----對應上傳excel
accept="application/msword" ----對應上傳word
accept="application/pdf" ----對應上傳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); } }); }, /** * 設置title標題 * @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防止頁面出現閃爍的情況
v-cloak指令
http://cn.vuejs.org/v2/api/#v...
處理TextArea自動隨文本高度自適應高度https://github.com/jackmoore/...
PC端與移動端中option的寬度問題 搜索布局的問題----子組件去解決路由切換(tab切換)實現不同的布局
VueJs NextTick的妙用https://segmentfault.com/a/11...
回到原來的滾動位置以及回到頂部(待完善)當路處于離開狀態的時候,存儲滾動的位置
當路由處于進入狀態的時候,取出滾動位置進行判斷,來顯示或隱藏“返回頂部”的按鈕
VueJs自動化測試https://segmentfault.com/a/11...
https://github.com/ccforward/...
Web App中一行文字顯示不下,左邊用...表示https://segmentfault.com/q/10...
刷新當前頁面this.$router.go(0);
VueJs打包優化https://www.zhihu.com/questio...
WebPack中靜態資源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的區別與聯系https://segmentfault.com/q/10...
VueJs富文本框(發帖功能)移動端:https://github.com/surmon-chi...
https://github.com/PeakTai/vu...
div設置了contentEditable屬性。android上正常,IOS上出現問題使用div來模擬input或者textarea來進行內容輸入的操作,實現富文本框的功能
遇到問題
加入style="-webkit-user-select: auto"就能出現光標和編輯了
Vuejs-Cordova-Framework-Webapphttp://blog.gxxsite.com/vuejs...
vue-cordova
Css-Scroller(效果圖,暫時不用在項目中)https://github.com/xiaoluobod...
Scroll開源庫實現列表滾動動畫https://github.com/hakimel/st...
H5控制禁止橫屏http://www.jianshu.com/p/9c32...
文件上傳(do not)https://github.com/marchFanta...
window.open被攔截問題(完成)通過借用a標簽并產生隨機的target去實現
`
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); // 防止反復添加 if(!document.getElementById(id)) { document.body.appendChild(a); } a.click(); },
`
調用
this.newWin(localStorage.getItem("url"),"dow","csa"+this.JsGuid());
log工具類(便于在開發過程中進行調試打印),在上線后將所有log信息隱藏
code
/**
Created by THINK on 2017/7/3.
日志工具類:開發階段將flag設置為true(可以看見log),上線后將flag設置為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修復上拉刷新,下拉加載
vue-scroller(自動地去進行了加載更多(bug))
對項目進行優化性的操作代碼復用
資源的處理
安卓模擬器測試安裝問題:進入Bios系統設置硬件虛擬化
虛擬化技術的可以在BIOS中開啟,開啟方法如下:
1、進入BIOS。開機時按F2或F12或DEL或ESC等鍵(各電腦有所不同)。 2、進入BIOS后,找到Configuration選項,選擇Intel Virtual Technology并回車,將光標移至Enabled,然后再回車,最后按F10保存并退出。 如果找不到Configuration選項,可以試試下面的方法: (1)某些HP(惠普)電腦進入BIOS后,需要選擇SystemConfiguration(系統配置)菜單,然后選擇Device Configuration(設備配置),找到Virtualization Technology,設置為Enabled。 (2)某些聯想Thinkpad電腦進入BIOS后,需要選擇Security菜單,然后選擇Virtualization,設置為Enabled。 (3)某些DELL(戴爾)電腦進入BIOS后,需要選擇Processor Settings菜單,然后選擇VirtualizationTechnology,設置為Enabled。 虛擬化在1960年為了描述虛擬機(實驗性的IBM M44/44X系統)這個概念被第一次提出。對虛擬機的架設和管理被稱為平臺虛擬化,現在也被稱為服務器虛擬化。將業務邏輯代碼與三方代碼分開進行打包
在entry入口中配置,如分離jQuery
使用vue-cli打包后默認生產三個js文件
app.43fcdsfcafds.js:項目中你編寫的業務邏輯的代碼
vender.20deewdew32eed.js:通過npm install下載依賴的js,css代碼(node_modules目錄下)
manifest.4cbcd0f5d52237fb29b0.js:緩存檢測文件,每次打包,通過該文件進行版本的檢測
將生產環境與開發環境中的資源打包使用
vender:3.34m app:1.26m,怎么去減少它們的體積
vender.xsaxsxx.js.map文件的作用
source map文件是js文件壓縮后,文件的變量名替換對應、變量所在位置等元信息數據文件,一般這種文件和min.js主文件放在同一個目錄下。 比如壓縮后原變量是map,壓縮后通過變量替換規則可能會被替換成a,這時source map文件會記錄下這個mapping的信息,這樣的好處就是說,在調試的時候,如果有一些JS報錯,那么瀏覽器會通過解析這個map文件來重新merge壓縮后的js,使開發者可以用未壓縮前的代碼來調試,這樣會給我們帶來很大的方便!
文件的按需加載(搞定)---項目優化的一大步
根據vue的路由去按需加載組件
http://www.cnblogs.com/Nutrie...
vue組件的按需加載:解決了打包過后app.xscs3243rcds.js文件過大的缺點
進一步優化(三方不太動的js文件,通過cdn去加載)
引用相同的模塊,打包后出現重復的資源,將三方的多帶帶進行打包
WebPack代碼分割https://zhuanlan.zhihu.com/p/...
WebPack中文網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)
微信網頁授權
https://mp.weixin.qq.com/wiki...
Vue-Cli中引入weixin-js-sdkhttps://www.npmjs.com/package...
蘋果手機上設置分享的title的問題
https://www.deboy.cn/set-wech...
微信分享
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
問題1:判斷是否是微信瀏覽器打開應用,是,需要動態去設置帖子詳情頁的分享界面
isWeiXin(){ //判斷是否是微信瀏覽器 let ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) === "micromessenger") { return true; } else { return false; } },
分享實現流程
①安裝微信sdk npm install weixin-js-sdk --save-dev
②通過import或者require的方式將其引入到需要的組件中
③獲取簽名相關的信息
④通過config接口注入權限驗證配置
wx.config({ debug: true, appId: "", // 必填,公眾號的唯一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: "", // 必填,生成簽名的隨機串 signature: "",// 必填,簽名,見附錄1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2 });
⑤通過ready接口處理成功驗證
wx.ready(function(){ // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。 //進行分享的操作 //分享到朋友圈 wx.onMenuShareTimeline({ title: "測試信息", // 分享標題 link: "", // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: "", // 分享圖標 success: function (res) { // 用戶確認分享后執行的回調函數 logUtil.printLog("分享到朋友圈成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執行的回調函數 logUtil.printLog("取消分享到朋友圈返回的信息為:",res); } }); //分享給朋友 wx.onMenuShareAppMessage({ title: "", // 分享標題 desc: "", // 分享描述 link: "", // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: "", // 分享圖標 type: "", // 分享類型,music、video或link,不填默認為link dataUrl: "", // 如果type是music或video,則要提供數據鏈接,默認為空 success: function (res) { // 用戶確認分享后執行的回調函數 logUtil.printLog("分享給朋友成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執行的回調函數 logUtil.printLog("取消分享給朋友返回的信息為:",res); } }); //分享到QQ wx.onMenuShareQQ({ title: "", // 分享標題 desc: "", // 分享描述 link: "", // 分享鏈接 imgUrl: "", // 分享圖標 success: function (res) { // 用戶確認分享后執行的回調函數 logUtil.printLog("分享到QQ好友成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執行的回調函數 logUtil.printLog("取消分享給QQ好友返回的信息為:",res); } }); //分享到QQ空間 wx.onMenuShareQZone({ title: "", // 分享標題 desc: "", // 分享描述 link: "", // 分享鏈接 imgUrl: "", // 分享圖標 success: function (res) { // 用戶確認分享后執行的回調函數 logUtil.printLog("分享到QQ空間成功返回的信息為:",res); }, cancel: function (res) { // 用戶取消分享后執行的回調函數 logUtil.printLog("取消分享到QQ空間返回的信息為:",res); } }); });
⑥通過error接口處理失敗驗證
wx.error(function(res){
// config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數中查看,對于SPA可以在這里更新簽名。 });
簽名由:noncestr(簽名隨機字符串,隨便寫)、jsapi_ticket(票據)、timestamp(時間戳)、url(必須全部小寫)等組成
獲取access_token
請求接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret 請求方法: get 返回結果: access_token (有效期7200秒,必須在服務端緩存)
獲取票據jsapi_ticket
請求接口:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=上一步中獲取的access_token&type=jsapi 請求方法: get, type: JSON, 返回結果: jsapi_ticket (有效期7200秒,必須在服務端緩存)
生成時間戳(timestamp)
// 時間戳產生函數 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; // 返回到前端,提供接口由前端請求 }
接下來就返回給前端使用(在獲取簽名的時候需要傳遞url:用于簽名的(需要四個參數來實現簽名:時間戳、ticket、前端傳遞的動態的url、nonceStr) url(動態的)給后端)]
微信分享
微信分享問題總結:
http://blog.csdn.net/u011743396/article/details/62427452
ngork
https://www.zhihu.com/question/25456655
問題描述
微信 jssdk 需要簽名,簽名的 URL 和將要分享的 URL 必須要一致才會簽名通過
url必須是當前網頁的url不包含#及其后面部分(http://blog.sina.com.cn/s/blo...
ip地址查詢:http://site.ip138.com
python sha1簽名
http://blog.csdn.net/u014368609/article/details/50679818
js獲取當前時間、時間戳
http://www.cnblogs.com/Man-Dream-Necessary/p/6369469.html
Vue路由按需加載
http://www.jb51.net/article/1...
注意事項
需要在配置文件webpack.base.conf.js中加入
output:{ pathinfo: true }
Vue服務端渲染
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生成圖片轉換為File對象兼容處理涉及點:Base64轉換為file對象
/** * 將Base64轉換為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}); },
發現ios低版本出現了兼容問題,最終發現問題出在new File()這里。那么就得想其他解決辦法了,可以先將Base64進行二進制轉換操作,最終將二進制轉換為File對象就可以解決。
/** * 將base64先轉換為二進制對象 * */ 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 }); }, /** * 最后再將二進制轉換為file對象 * */ blobToFile(theBlob, fileName){ theBlob.lastModifiedDate = new Date(); theBlob.name = fileName; return theBlob; },
it is done!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/83997.html
摘要:寫在前面經過最近的初步閱讀,明白了的整體框架和部分源碼。的源碼很龐大,很多代碼看過之后很容易就會忘記,所以很有必要寫一份閱讀筆記。而且我也會努力寫好這份文檔,最終把整個的源碼讀完并寫一份全面的文檔出來。 寫在前面 經過最近的初步閱讀,明白了Vuejs的整體框架和部分源碼。Vuejs的源碼很龐大,很多代碼看過之后很容易就會忘記,所以很有必要寫一份閱讀筆記。這份筆記會是逐步更新的,隨著我閱...
摘要:主顯示區我們在中先引用另外兩個組件并且修改路由配置組件姓名屬性性別種類身高體重捕獲成功請填入完整精靈信息通過方法派發一個事件,用來保存新捕獲的精靈對于需添加并且設置名字與種類未填寫時無法提交。 花了兩周,看了許久的文檔和案例,還是要實踐一下,于是做了這個demo,設計就這樣看吧,我的設計水平真心不好T^T,一周目的demo是靜態的,二周目再搭建數據層。 項目倉庫:https://git...
摘要:中文官網英文官網組織發出一個問題之后,不要暫時的離開電腦,如果沒有把握先不要提問。珍惜每一次提問,感恩每一次反饋,每個人工作還是業余之外抽出的時間有限,充分準備好應有的資源之后再發問,有利于問題能夠高效質量地得到解決。 Vue.js資源分享 更多資源請Star:https://github.com/maidishike... 文章轉自:https://github.com/maid...
摘要:觸發行為與相當于。是具體改變狀態的行為,每次的可能被捕捉。而是通過發起執行操作。因此異步行為放在。通過與具體的組件進行綁定。但是,它規定了一些需要遵守的規則應用層級的狀態應該集中到單個對象中。提交是更改狀態的唯一方法,并且這個過程是同步的。 VUEX 概念 store / module state / getters mutations / actions payload: co...
閱讀 1710·2021-10-09 09:44
閱讀 3271·2021-09-27 13:36
閱讀 1531·2021-09-22 15:33
閱讀 1283·2021-09-22 15:23
閱讀 1168·2021-09-06 15:02
閱讀 1708·2019-08-29 16:14
閱讀 2914·2019-08-29 15:26
閱讀 2416·2019-08-28 18:08