======================知識點總結===========================css
vue-validator中文文檔html
給最外層盒子加上絕對定位,而且設置固定高度前端
.reg-layer { width: 100%; height: 360px; background: #ffffff; position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
再給登陸框設置固定vue
.login-main { width: 100%; height: 4rem; background-color: #ffffff; padding-top: 0.4rem; }
VUe-Scrollerhtml5
_this.$router.go(0);
{ test: /vue-scroller.src.*?js$/, loader: 'babel-loader' }
this.$refs.my_scroller.finishInfinite(true);python
it must be contain a canvas tagreact
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); }); },
PDFViewer.vueandroid
<template> <div class="pdf-view-layout"> <header> <h1 id="title"></h1> </header> <div id="viewerContainer"> <div id="viewer" class="pdfViewer"></div> </div> <div id="loadingBar"> <div class="progress"></div> <div class="glimmer"></div> </div> <div id="errorWrapper" hidden="true"> <div id="errorMessageLeft"> <span id="errorMessage"></span> <button id="errorShowMore"> More Information </button> <button id="errorShowLess"> Less Information </button> </div> <div id="errorMessageRight"> <button id="errorClose"> Close </button> </div> <div class="clearBoth"></div> <textarea id="errorMoreInfo" hidden="true" readonly="readonly"></textarea> </div> <footer> <button class="toolbarButton pageUp" title="Previous Page" id="previous" @click="goNextPage()"></button> <button class="toolbarButton pageDown" title="Next Page" id="next"></button> <input type="number" id="pageNumber" class="toolbarField pageNumber" size="4" min="1" > <button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut"></button> <button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn"></button> </footer> </div> </template> <script> //加載PDFJS import pdf from '../../../node_modules/pdfjs-dist/build/pdf.js'; import pdfViewer from '../../../node_modules/pdfjs-dist/web/pdf_viewer.js'; import Viewer from '../../assets/js/viewer'; export default{ data(){ return{ myPage:1, } }, mounted(){ const url = 'http://192.168.0.200:8080/media/avatar/fluent-python.pdf'; Viewer.animationStartedPromise.then(function () { Viewer.open({ url: url }); }); }, methods:{ goNextPage(){ console.log('下一頁的數據'); } }, watch:{ myPage(newV,oldV){ console.log("==================:",$('#pageNumber').val()); } }, } </script> <style scoped> @import "../../assets/css/viewer.css"; </style>
viewer.jswebpack
/* 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\n' + ' `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('\n'); }); }, 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;
v-cloak指令
加入style="-webkit-user-select: auto"就能出現光標和編輯了
`
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());
code
/**
*/ let logUtil = { flag:true, printLog(...items){ if(this.flag){ console.log(items); } } } export default logUtil
虛擬化技術的能夠在BIOS中開啓,開啓方法以下:
一、進入BIOS。開機時按F2或F12或DEL或ESC等鍵(各電腦有所不一樣)。 二、進入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系統)這個概念被第一次提出。對虛擬機的架設和管理被稱爲平臺虛擬化,如今也被稱爲服務器虛擬化。
使用vue-cli打包後默認生產三個js文件
vender:3.34m app:1.26m,怎麼去減小它們的體積
source map文件是js文件壓縮後,文件的變量名替換對應、變量所在位置等元信息數據文件,通常這種文件和min.js主文件放在同一個目錄下。 好比壓縮後原變量是map,壓縮後經過變量替換規則可能會被替換成a,這時source map文件會記錄下這個mapping的信息,這樣的好處就是說,在調試的時候,若是有一些JS報錯,那麼瀏覽器會經過解析這個map文件來從新merge壓縮後的js,使開發者能夠用未壓縮前的代碼來調試,這樣會給咱們帶來很大的方便!
根據vue的路由去按需加載組件
微信網頁受權
蘋果手機上設置分享的title的問題
微信分享
isWeiXin(){ //判斷是不是微信瀏覽器 let ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) === 'micromessenger') { return true; } else { return false; } },
分享實現流程
④經過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接口處理失敗驗證
// config信息驗證失敗會執行error函數,如簽名過時致使驗證失敗,具體錯誤信息能夠打開config的debug模式查看,也能夠在返回的res參數中查看,對於SPA能夠在這裏更新簽名。 });
獲取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) + ''; };
好比:
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; // 返回到前端,提供接口由前端請求 }
微信分享問題總結:
ngork
問題描述
python sha1簽名
js獲取當前時間、時間戳
Vue路由按需加載
注意事項
須要在配置文件webpack.base.conf.js中加入
output:{ pathinfo: true }
Vue服務端渲染
後臺管理
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); }); }
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); }); }
涉及點: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!