一、本地vue項目配置IP地址訪問,可以讓同局域網內的同事預覽
解決:在package.json文件中 dev中配置 --host 本機IP
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 10.10.50.73",
"start": "npm run dev",
"build": "node build/build.js"
},
二、Vue使用axios請求數據,默認post請求傳參是json格式,但后台需要formData格式
1、 FormData格式
2、qs解決
解決:使用node的qs模塊 qs是一個npm倉庫所管理的包,可通過npm install qs
命令進行安裝.
qs.parse()將URL解析成對象的形式
let url = 'method=query_sql_dataset_data&projectId=85&appToken=7d22e38e-5717-11e7-907b-a6006ad3dba0'; qs.parse(url); // { // method:'query_sql_dataset_data', // projectId:85, // appToken:'7d22e38e-5717-11e7-907b-a6006ad3dba0' // }
qs.stringify()將對象 序列化成URL的形式,以&進行拼接
let obj= { method: "query_sql_dataset_data", projectId: "85", appToken: "7d22e38e-5717-11e7-907b-a6006ad3dba0", datasetId: " 12564701" }; qs.stringify(obj); //'method=query_sql_dataset_data&projectId=85&appToken=7d22e38e-5717-11e7-907b-a6006ad3dba0'
import axios from 'axios';
import qs from 'qs';
this.$axios({
method: 'post',
url: url,
data: qs.stringify(data)
}).then(res => {})
三、過濾器(簡單)
filters: {
visitedFilters(value) {
let set = {0: "未到訪", 1: "已到訪"};
return set.hasOwnProperty(value) ? set[value] : value
},
},
四、在H5中使用qrcodejs2生成二維碼
npm i qrcodejs2
import QRCode from 'qrcodejs2'
this.$nextTick(() => {
document.getElementById('qrcode').innerHTML = '';
this.qrCode = new QRCode('qrcode', {
width: 200, // 設置寬度,單位像素
height: 200, // 設置高度,單位像素
text: this.urlData.urlValue // 設置二維碼內容或跳轉地址
});
})
五、深拷貝,淺拷貝問題
在做el-select 下拉數據過多時,region_code ,region_name 以分頁形式顯示(顯示前15條,之后可進行搜索),但是在數據回顯時,發現在15條數據之后,因為沒有數據,回顯失敗,
進行數據回顯時(region_code和region_name互換值),在不進行更改時,保存提交時時(region_code和region_name再轉換回來)時發現
問題:
當用obj1復制了一個對象obj2, 更改obj1內的屬性時,obj2內的會同步更改,
原因:
因為 = 復制為淺拷貝,只拷貝了它的棧內存中的"引用路徑",所以當更改obj1時,更改了堆內存中的值,obj2的指向也是它,所以會同步修改
解決:
運用深拷貝,復制時不僅要拷貝棧內存中的引用路徑,堆內存中的值也要同步復制
方法1:
首推的方法簡單有效,JSON.stringfy()和JSON.parse()即可搞定。但是這種簡單粗暴的方法有其局限性。當值為undefined、function、symbol 會在轉換過程中被忽略。。。所以,對象值有這三種的話用這種方法會導致屬性丟失。
var person = {
name :'tino',
say: function(){
console.log('hi');
},
ok: syb,
un: undefined
}
var copy = JSON.parse(JSON.stringify(person))
方法2:
寫個函數遞歸復制
function deepCopy(obj) {
var result = Array.isArray(obj) ? [] : {}; //Array.isArray(object) 檢測是否為數組 傳進來的object是數組,返回true,如果不是數組,則返回false
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object' && obj[key]!==null) {
result[key] = deepCopy(obj[key]); //遞歸復制
} else {
result[key] = obj[key];
}
}
}
return result;
}
六、https使用iframe嵌入http資源的問題(了解,未使用)
目前現象:
https 網站 使用iframe嵌入http資源網站的內容,會彈出“是否加載不安全的內容”的提示,點擊“加載”按鈕后顯示正常。
對用戶來說顯示不友好。
問題原因:
https中使用http的資源時,瀏覽器會認為可能會不安全, 會自動彈出“是否加載不安全的內容”的提示。
該提示由瀏覽器自動彈出,不能通過修改代碼的方式解決。
https中使用https資源時,如果https資源不安全,同樣會報錯。
嘗試解決方案:
1) 使用自定義ssl證書,將http資源模擬成為https
使用nginx或者apache服務器,將http協議的資源包裝為https協議的資源使用,前提條件是nginx或者apache服務器可以同時訪問到http的資源和https的資源,將http鏈接地址從原網站改為nginx或apache包裝的https的地址即可。
否則會報錯“ 因為沒有使用有效的安全證書進行簽名,該內容已被屏蔽”的新錯誤提示。
2)使用第三方簽名的ssl證書,將http資源轉換成為https
和方案1相同,但是使用第三方簽名CA證書,網站可以正常訪問。
但是第三方的CA簽名的ssl證書是需要按年付費的, 價格 從每年幾百到每年幾千元均有。
3) 要求http網站資源提供https的格式內容,且使用的ssl證書為第三方CA簽名證書。
七、當在 element ui 使用 resetFields()重置表單后,表單無法輸入的問題
this.$refs[formName].resetFields(); 使用后部分表單無法輸入
解決:
resetFields 是對整個表單進行重置,講所有字段值重置為"初始值",並移除校驗結果.
所以給表單默認一個初始值就可以解決
八、vue中子組件的created、mounted鈎子中獲取不到props中的值問題
當props中接受的值是動態獲取的,這種情況下,鈎子中是取不到值的,或者取到的一直是默認值。
原因:
出現這種情況的原因, 因為父組件中的要就要傳遞的 props 屬性 是通過 發生ajax請求回來的,
請求的這個過程是需要時間的,但是“子組件的渲染要快於ajax請求過程”,所以此時 created 、 mounted 這樣的只會執行一次的生命周期鈎子,已經執行了,但是 props 還沒有流進來(子組件),所以只能拿到默認值。
解決:
使用watch處理,監聽 傳入的值,當它由空轉變時就會觸發,這時候就能取到了,created、mounted,中依舊拿不到值,拿到值后要做的處理方法也需要在 watch 里面執行。
九、在vue的dialog中嵌套dialog,彈出里層的dialog時,發現被dialog的遮罩層擋住了
解決:
對於確實需要嵌套 Dialog 的場景,提供了append-to-body屬性。將內層 Dialog 的該屬性設置為 true,它就會插入至 body 元素上,從而保證內外層 Dialog 和遮罩層級關系的正確。
十、對接七陌外呼系統
引入插件:
import md5 from 'js-md5'; //md5加密
let Base64 = require("js-base64").Base64; //轉化base64 https://www.javascriptcn.com/read-41473.html
import moment from "moment"; //用於獲取時間戳 http://momentjs.cn/docs/
//外呼接入函數(依據七陌接口文檔 https://developer.7moor.com/v2docs/dialout/)
callOut(val) { const exten = "8003"; //坐席工號 const ACCOUNTID = "N00000037833"; //賬戶編號(ACCOUNTID) const APISecret = "1e86bcb0-fbc0-11e9-833b-1f632fa2b92c"; //帳號APISecret const timestamp = moment().format("YYYYMMDDHHmmss");//獲取當前時間的時間戳 const sig = md5(`${ACCOUNTID}${APISecret}${timestamp}`).toUpperCase(); //url參數sig的值為 32位大寫MD5加密 (帳號Id + 帳號APISecret +時間戳) const auth = Base64.encode(`${ACCOUNTID}:${timestamp}`); //Authorization是包頭驗證信息 Authorization的值為 Base64編碼(賬戶Id +冒號+時間戳) this.$axios({ method: 'POST', url: `/7moor/v20160818/call/dialout/${ACCOUNTID}?sig=` + sig, data: { FromExten: exten, //坐席工號 Exten: val.customer_mobile, //外呼的電話號碼 ExtenType: "sip" //座機方式 }, headers: { "Content-Type": "application/json;charset=utf-8", 'Authorization': auth } }).then((res) => { console.log(res) }) },
跨域問題詳解: https://www.jianshu.com/p/a0dd1e712c3a
請求會出現跨域的問題:config/index.js 配置本地跨域代理,上線時需要配置nginx代理
proxyTable: { '/7moor': { target: 'https://apis.7moor.com', changeOrigin: true, pathRewrite: { '^/7moor': '/' //實際請求去掉 /7moor 以 / 代替 } } },
配置表
dev: { // 靜態資源文件夾 assetsSubDirectory: 'static', // 發布路徑 assetsPublicPath: '/', // 代理配置表,在這里可以配置特定的請求代理到對應的API接口 // 例如將'localhost:8080/api/xxx'代理到'www.example.com/api/xxx' // 使用方法:https://vuejs-templates.github.io/webpack/proxy.html proxyTable: { '/api/cms': { target: 'http://localhost:31001', pathRewrite: { '^/api': ' ' //實際請求去掉/api以空字符串代替 } } },
十一、用postcss-px2rem插件,樣式中px強制不自動轉換為rem的方法
#box { height: 44px width: 100% font-size: 24px;/*no*/ //如果不想用插件轉換可以用/*no*/標識符 }
問題:當打包編譯過 之后 /*no*/這個標簽會被當成注釋給去掉,
解決:把px改成PX大寫,瀏覽器一樣識別,px2rem不會轉換它。
十二、vue中在data中引入圖片的路徑方法
---錯誤的引入方式: export default { data () { return{ imgUrl_homePage:'@/assets/img/homePage_active.png' } } } ---import在外部引入 import img_url from '@/assets/img/homePage_active.png' export default { data () { return{ imgUrl_homePage:img_url } } } ---require內部引入 export default { data () { return{ imgUrl_homePage:require('@/assets/img/homePage_active.png') } } }
十三、使用vant中van-list插件時為什么 List 初始化后會立即觸發 load 事件?
List 初始化后會觸發一次 load 事件,用於加載第一屏的數據,這個特性可以通過immediate-check屬性關閉。
loading 的設置也會影響到load事件的觸發
十四、依據一個對象屬性的值,判斷這個數組是否含有這個對象,有的話刪除,沒有的話增加
const ind = this.chooseSelectedPrice.findIndex( item => item.value === priceWen ); if (ind !== -1) { this.chooseSelectedPrice.splice(ind, 1); } else { if (this.qieNum2 === 0) { this.chooseSelectedPrice.push({ value: priceWen, start: item.start, end: item.end, type: 0 }); } else { this.chooseSelectedPrice.push({ value: priceWen, start: item.start, end: item.end, type: 1 }); } }
十五、數組的切割中arr.splice(n,1)
使用時不可let arr2 = arr.splice(n,1) 因為它是改變原數組的,不會有返回值
十六、localStorage本地存儲時,key值不能為變量,可以通過以下方法變通
obj[phone] = JSON.stringify(celPhone); this.$tool.setStorage(obj);//集成的方法 delete celPhone[buildingId];
十七、關鍵字搜索高亮
pushHTML(text, str) { let arr = str.split(text); let newText = arr.join('<span style="color:#00A4FF">' + text + "</span>"); return newText; },
十八、router-link 綁定事件不生效
加 .native 修飾符就可以執行事件了。
<router-link to="/date" @click.native="nav_click">最新</router-link>
原因:
1: 因為它是自定義標簽,根本就沒有事件和方法,所以不觸發,加個native 就是告訴vue 這個標簽現在有主了 它是H5標簽 可以加事件了。
2:父組件要想在子組件監聽自己的click事件就得加native,router-link是標簽啊。哪里有父組件????
router-link 其實就是一個封裝好的 .vue 組件,所以需要 加.native修飾符才能綁定事件
十九、vue跳轉當面頁面(頁面路徑不變化,攜帶參數改變)頁面不刷新問題
解決1、router-view 中加一個 key
<router-view :key="$route.fullPath" />
解決2、路由改變時刷新當前頁
this.$router.go(0);
vue 框架this.$router.go(0) safari 瀏覽器不刷新
用原生 window.location.reload()
二十、(粗心)當用組件,時,用到v-model,或者動態綁定的值,無效時,要看清當前組件需要綁定的值得類型,好多次,number類型的綁定成了string,死活不出效果,調試很久,謹記。
字符串定義 未賦值時不能使用,否則會報undefined
二十一、本地存儲封裝
/* 獲取瀏覽器存儲里key為item的值 @param item 要獲取的數據的索引值 Usage: helper.get('token') */ function getStorage(item) { var value; value = window.localStorage.getItem(item) return (value ? decrypt(value) : '') } /* 將數據存儲在瀏覽器存儲里 @param obj 要存儲的數據對象 Usage: j.set({ token: 'as23q1sdf212swsxx', uname: 'jacket' }) */ function setStorage(obj) { for (var key in obj) { if (obj.hasOwnProperty(key)) { window.localStorage.setItem(key, encrypt(String(obj[key]))); } } }
二十二、jquery獲取參數
detail.html?order_id=10 <Script language="javascript"> function GetRequest() { var url = location.search; //獲取url中"?"符后的字串 var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); for(var i = 0; i < strs.length; i ++) { theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]); } } return theRequest; } </script> detail.html?order_id=10&uid=3 function GetRequest() { var url = location.search; //獲取url中"?"符后的字串 var theRequest = new Object(); if (url.indexOf("?") != -1) { var str = url.substr(1); strs = str.split("&"); console.log(strs) for (var i = 0; i < strs.length; i++) { theRequest[strs[i].split("=")[0]] = decodeURIComponent(strs[i].split("=")[1]); } } return theRequest; }
二十三、jquery給元素增加一個父元素
let d = $("table").clone(); //clone(includeEvents) 方法生成被選元素的副本,包含子節點、文本和屬性。 includeEvents 可選。布爾值。規定是否復制元素的所有事件處理。 默認地,副本中不包含事件處理器。 let f = $("table").parent(); console.log(d,f) $("table").remove(); $(f).append("<div class='kg'><div>"); $(".kg").html(d)
以上為沙雕做法而且有bug
$('table').wrap("<div class='kg'></div>");一句搞定它不香么
二十四、整行字體漸變色
//默認值。替換內容拉伸填滿整個content box, 不保證保持原有的比例。 object-fit: fill; //保持原有尺寸比例。保證替換內容尺寸一定可以在容器里面放得下。因此,此參數可能會在容器內留下空白。 object-fit: contain; //保持原有尺寸比例。保證替換內容尺寸一定大於容器尺寸,寬度和高度至少有一個和容器一致。 //因此,此參數可能會讓替換內容(如圖片)部分區域不可見 object-fit: cover; //保持原有尺寸比例。同時保持替換內容原始尺寸大小。 object-fit: none; //最終呈現的是尺寸比較小的那個,類似於依次設置none或contain。 object-fit: scale-down;
htmljs錨點滾動
function scrollDom() { allHeights = []; $(".activity_main_li").each((index, item) => { let top = '', s = $("." + $(item).attr("currentname")); allHeights.push(s.offset().top) }) $(window).scroll(function() { scrollTopDom() }) }; function scrollTopDom() { // 獲取當前滾動的高度 var top = document.body.scrollTop + document.documentElement.scrollTop; top = top + 90; if (review) { review = false; scrollHeight = document.body.scrollHeight; } let index = 0; if (top >= allHeights[allHeights.length - 1]) { index = allHeights.length - 1 } else { $(allHeights).each((i, res) => { if (top < res && top > allHeights[i - 1]) return index = i - 1 }) } if (currentPoint != index && !currentGun) { currentPoint = index; $(".activity_main_li").removeClass("active"); $($(".activity_main_li")[index]).addClass("active") scrollX(index) } // 滾動條距離頂部的距離 大於 200px時 if (top >= 500 && flag) { flag = false; $(".activity_main_title").css({ "position": "fixed", "top": "0", "z-index": "9", "background-color": "#0E0E0E" }); } else if (top < 500) { flag = true; $(".activity_main_title").css({ position: 'relative', backgroundColor: 'transparent' }); } }
&&&&&&&&&&&&&&&&&&&《項目中的知識點》&&&&&&&&&&&&&&&&&&&&&&&&
1、hasOwnProperty:
hasOwnProperty()方法返回一個布爾值,判斷對象是否包含特定的自身(非繼承)屬性。
function Person(name, age) {
this.name = 'Tom';
this.age = 11;
};
Person.prototype = {
job:'資深前端開發工程師',
};
console.log(Person.hasOwnProperty('name'))//true
console.log(Person.hasOwnProperty('job'))//false
2、JSON.stringify()
JSON 通常用於與服務端交換數據。
在向服務器發送數據時一般是字符串。
我們可以使用 JSON.stringify() 方法將 JavaScript 對象轉換為字符串。
JSON.parse()
JSON 通常用於與服務端交換數據。
在接收服務器數據時一般是字符串。
我們可以使用 JSON.parse() 方法將數據轉換為 JavaScript 對象。
3、localStorage
localStorage 可以在瀏覽器中存儲鍵值對的數據,能長期儲存
localStorage中的鍵值對總是以字符串的形式存儲,並且只能訪問當前域名下的數據,不能跨域名訪問
可以通過setItem方法增加了一個鍵值對數據,如果該鍵已存在,那么該鍵對應的值將被覆蓋
localStorage.setItem("name","xiaozhong")
可以用getItem方法讀取對應鍵的值數據
localStorage.getItem("name")
可以用removeItem方法移除對應鍵
localStorage.removeItem("name")
可以用clear方法移除當前域名下所有的鍵值對數據
localStorage.clear()