前端日常總結(jié)
推薦:TypeScript趁早學(xué)習(xí)提高職場競爭力
Github來源: | 求星星 ? | 給個??關(guān)注,??點贊,??鼓勵一下作者
希望能夠幫助更多的小伙伴。加我??即可交流問題(不是大佬,互相學(xué)習(xí),創(chuàng)造良好的學(xué)習(xí)環(huán)境)。以下哪些你不懂呢?

1.關(guān)于es5和es6得繼承問題
es5的繼承是 先創(chuàng)建子類的實例對象,然后將父類的方法添加到this上, Parent.apply(this)es6的繼承是 先創(chuàng)建父類的實例對象this,所以先調(diào)用父類的 super()方法,然后再用子類的構(gòu)造函數(shù)修改thises5的繼承是 通過原型或構(gòu)造函數(shù)機制來實現(xiàn) es6通過class關(guān)鍵字定義類,其中有構(gòu)造方法,類之間通過extends關(guān)鍵字來實現(xiàn)繼承 字類必須再 constructor方法中調(diào)用super方法,否則新建實例報錯super關(guān)鍵字表示 父類的實例,即是父類的this對象 在子類構(gòu)造函數(shù)中調(diào)用super后,才可使用this關(guān)鍵字,否則報錯
2.innerHTML和outHTML的區(qū)別
<div id="dadaqianduan">我喜歡你</div>
document.getElementById("dadaqianduan").innerHTML; // 我喜歡你
document.getElementById("dadaqianduan").outerHTML;
// <div id="dadaqianduan">我喜歡你</div>
innerHTML設(shè)置或獲取于對象起始和結(jié)束標簽內(nèi)的HTML outerHTML設(shè)置或獲取對象以及起內(nèi)容的HTML形式
3.塊級綁定

3.1var聲明與變量提升
es6的塊級綁定 變量創(chuàng)建的位置取決于你如何聲明它 var聲明與變量提升 使用var關(guān)鍵字聲明的變量,不管其實際聲明位置在哪個地方,都會被視為聲明于所在函數(shù)的頂部,如果聲明不在任意函數(shù)體內(nèi),則視為是在全局作用域的頂部(變量提升)
示例:
function fun(value) {
if(value) {
var da = "掘金魔王哪吒";
return da;
} esle {
// da 在此處可訪問,值為undefined
return null
}
// da 在此處可訪問,值為undefined
}
你如果以為value的值為true時,變量da才會被創(chuàng)建,那就錯了,實際上da無論如何都會被創(chuàng)建,如下代碼所示:
function fun(value) {
var da;
if(value) {
da = '魔王哪吒';
return da;
} else {
return null;
}
}
da變量的聲明被提升到了頂部,而初始化工作則保留在原處 上述代碼表示else分支內(nèi)da變量也是可訪問的,只不過是它的值會是undefined,因為它并沒有初始化呀
es6引入了塊級作用域,讓變量的聲明周期更加可以控制
3.2塊級聲明
塊級作用域(又稱為詞法作用域) 塊級聲明,就是讓所聲明的變量在指定塊的作用域外無法被訪問
創(chuàng)建:
塊級作用域:
在一個函數(shù)的內(nèi)部 在一個代碼塊內(nèi)部
let聲明
在項目中常用let來代替var進行變量聲明(let聲明會將變量的作用域限制在當前代碼塊中)
如果你不需要讓變量在整個代碼塊內(nèi)部使用,就使用let聲明 如果你使用let聲明并不會被提升到當前代碼塊的頂部,如果你還要動手將let聲明放置到頂部,讓變量在整個代碼塊內(nèi)部使用,你還是使用var聲明吧~
function fun(value) {
if(value) {
let da = "掘金魔王哪吒";
return da;
}else{
// da 在此處不可用
return null;
}
// da 在此處不可用
}
如果value為false時,該變量時永遠都不會被聲明并初始化的哦~
如下:不可以重復(fù)聲明的喲~
如果一個標識符在代碼塊中已經(jīng)被定義了,那么在此代碼塊內(nèi)部使用同一標識符進行l(wèi)et聲明,就會導(dǎo)致錯誤的喲~
var da = '魔王哪吒';
// 語法錯誤
let da = '魔王哪吒好帥';

有圖有真相
記住:let不能在同一作用域內(nèi)重復(fù)聲明一個已有標識符,注意時同一作用域內(nèi),如果時在嵌套的作用域內(nèi)使用let聲明一個同名的新變量,就不會拋出錯誤,我只說同一作用域內(nèi)會報錯,不在同一作用域內(nèi)就不會報錯了喲~
var da = 12;
// 不會拋出錯誤
if (true) {
let da = 123;
}

常量的聲明
使用const聲明的變量會被認為時常量 constant,表示它們的值被設(shè)置完成后就不能再被改變了
所以啊,所有的const聲明的變量都需要(在聲明時)進行初始化:
// 有效的常量
const da = 12;
// 語法錯誤:未進行初始化
const dada;

記住:常量聲明與let聲明是一樣的,都是塊級聲明(上述)見上
示例:
if(value) {
const da = '掘金魔王哪吒'
}
// da 在此處無法訪問
無論是在嚴格模式還是非嚴格模式下:對之前用const聲明的常量進行賦值會拋出錯誤
const da = '掘金:魔王哪吒,好帥'
da = '是很帥的,魔王哪吒' // 拋出錯誤
const聲明常量,如果使用const聲明對象如下描述:
const聲明 會阻止對于 變量綁定 與 變量自身值的修改,這意味著 const 聲明并不會阻止對變量成員的修改。
阻止:變量綁定,變量自身值的修改
不阻止:變量成員的修改
示例:
// dada 在初始化時綁定了帶有一個屬性的對象
const dada = {
string: 'dadaqianduan.cn億萬少女的夢'
};
// 正常
dada.string = '掘金魔王哪吒:億萬少女的夢';
// 拋出錯誤
dada = {
string: '魔王哪吒,你在做夢呢'
};

const阻止的是對于變量綁定的修改 const不會阻止對成員值的修改
暫時性死區(qū)
什么是暫時性死區(qū)呢?就是之前說過,使用let或者是const聲明的變量,在沒有達到聲明處之前是無法訪問的,如果訪問會導(dǎo)致引用錯誤。就算是在安全情況下,也是一樣。
如下:
if(value) {
console.log(typeof da); // 引用錯誤
let da = '達哥好帥';
}

當js引擎檢視代碼塊并發(fā)現(xiàn)變量聲明時,它會在面對 var 的情況下將聲明提升到 函數(shù)或全局作用域的頂部,而面對 let 或 const 時會將聲明放在暫時性死區(qū)內(nèi)。
任何在暫 時性死區(qū)內(nèi)訪問變量的企圖都會導(dǎo)致“運行時”錯誤(runtime error)。只有執(zhí)行到變量的聲明 語句時,該變量才會從暫時性死區(qū)內(nèi)被移除并可以安全使用。
示例:
那么在變量被定義的代碼塊之外對該變量使用typeof,盡管其結(jié)果可能并非預(yù)期:
console.log(typeof da); // 'undefined'
if(true) {
let da = 'dadaqianduan';
}

3.3循環(huán)中的塊級綁定
循環(huán)內(nèi)的函數(shù)
// 因為 var 聲明導(dǎo)致了變量提升。
for (var i = 0; i < 10; i++) {
...
}
// i 在此處仍然可被訪問
console.log(i); // 10
for (let i = 0; i < 10; i++) {
...
}
// i 在此處不可訪問,拋出錯誤
console.log(i);
立即調(diào)用函數(shù)表達式:
for(var i=1;i<=5;i++) {
setTimeout(() => {
console.log(i)
}, i*1000)
}
會打印出6個6,原因:for循環(huán)中用var來申明變量i,此時var存在變量提升問題,并且6次循環(huán)中全都共用一個變量,所以當setTimeout中的延遲函數(shù)開始執(zhí)行時,循環(huán)已經(jīng)結(jié)束,此時i=6,所以會打印出6個6。
變量i在循環(huán)的每次迭代中都被共享了,表示循環(huán)內(nèi)創(chuàng)建的那些函數(shù)都擁有對于同一變量的引用。
利用閉包可以解決這個問題:
for(var i=1;i<=5;i++) {
(function(j){
setTimeout(() => {
console.log(j)
}, j* 1000)
})(i)
}
在循環(huán)內(nèi)使用立即調(diào)用函數(shù)表達式
(IIFEs),以便在每次迭代中 強制創(chuàng)建變量的一個新副本使用 setTimeout 的第三個參數(shù)
for(var i=1;i<=5;i++) {
setTimeout((j) => {
console.log(j)
}, i* 1000, i)
}
使用 let 定義 i
for(let i=1;i<=5;i++) {
setTimeout(() => {
console.log(i)
}, i*1000)
}
循環(huán)內(nèi)的let聲明
在每次迭代中,都會創(chuàng)建一個新的同名變量并對其進行初始化。 在循環(huán)中l(wèi)et聲明每次都創(chuàng)建了一個新的i變量,因此在循環(huán)內(nèi)部創(chuàng)建的函數(shù)獲得了各自的i副本 每個i副本的值都在每次循環(huán)迭代聲明變量的時候被確定
示例:
var arr = [],
object = {
a: 1,
b: 2,
c: 3
};
for(let key in object) {
arr.push(function(){
console.log(key);
});
}
arr.forEach(function(func){
func(); // a,b,c
});

每次循環(huán),一個新的key變量綁定就被創(chuàng)建,每個函數(shù)都能夠擁有它自身的key變量副本,結(jié)果每個函數(shù)都輸出了一個不同的值
循環(huán)內(nèi)的常量聲明
示例:
// 在一次迭代后拋出錯誤
for(const i = 0; i < 10; i++){..}
for-in 或 for-of
var arr = [],
object = {
a: 1,
b: 2,
c: 3
};
// 不會報錯
for(const key in object) {
arr.push(function(){
console.log(key);
});
}
arr.forEach(function(func){
func(); // a,b,c
});

注意:使用const聲明,不能改變值,上述是 循環(huán)為每次迭代創(chuàng)建了一個新的變量綁定,而不是試圖去修改已綁定的變量的值。
3.4全局塊級綁定
使用var,在全局作用域中,它會創(chuàng)建一個新的全局變量,并成為全局對象的一個屬性,可能當你使用var時,需要注意的時,var可能會無意覆蓋一個已有的全局屬性。使用var聲明,定義為全局變量后會立即成為window的一個屬性。
如果你在全局作用域上使用let或者時const,會在全局作用域上創(chuàng)建新的綁定,但不會被添加到全局對象上,不能使用let或const來覆蓋一個全局變量,你只能用來起到屏蔽效果。
描述:
由于塊級綁定存在暫時性死區(qū) ( TDZ ), 試圖在聲明位置之前訪問它就會導(dǎo)致錯誤。let 和 const能夠在 for-in 和 for-of 循環(huán)中,每一次迭代時創(chuàng)建一個新的綁定,表示 在循環(huán)體內(nèi)創(chuàng)建的函數(shù)可以使用 當前迭代所綁定的循環(huán)變量值。 不向使用var 那樣,統(tǒng)一使用循環(huán)結(jié)束時的變量值。 在for循環(huán)中 使用 let 聲明 成立,使用const聲明會導(dǎo)致錯誤哦。
4.innerText和innerContent的區(qū)別
textContent會獲取style="display:none中的文本,而innerText不會textContent會獲取style標簽里面的文本,而innerText不會textContent不會理會html格式,直接輸出不換行的文本innerText會根據(jù)標簽里面的元素獨立一行innerText會根據(jù)標簽里面的元素獨立一行innerText對IE的兼容性較好textContent雖然作為標準方法但是只支持IE8+以上的瀏覽器
5.el.children和el.childNodes的區(qū)別
el.children,返回指定節(jié)點的所有element子節(jié)點,即返回節(jié)點元素el.childNodes,返回指定節(jié)點的所有子節(jié)點,包括節(jié)點元素和文本元素
6.JavaScript語法

方法:將 JavaScript代碼放到文檔<head>標簽中的<script標簽之間方法:在文檔的 <head>部分放一個<script>標簽,并把它的src屬性指向該文件方法:把 <script>標簽放到HTML文檔的最后,</body>標簽之前(這樣能使瀏覽器更快加載頁面)JavaScript變量名允許包含字母,數(shù)字,美元符號和下劃線(但第一個字符不允許是數(shù)字) 通常駝峰格式是函數(shù)名,方法名和對象屬性名命名的首選格式。 JavaScript中幾種數(shù)據(jù)類型:字符串,數(shù)值,布爾值,數(shù)組,對象。 由瀏覽器提供的預(yù)定義對象被稱為宿主對象。 typeof操作符可以告訴我們它的操作數(shù)是一個字符串,數(shù)值,函數(shù),布爾值還是對象。
字符串:字符串由零個或多個字符構(gòu)成。字符包括(但不限于)字母,數(shù)字,標點符號和空格。 如果字符串包含雙引號,就把整個字符串放在單引號里;如果字符串包含單引號,就把整個字符串放在雙引號里。 用對象來代替?zhèn)鹘y(tǒng)數(shù)組的做法意味可以通過元素的名字而不是下標數(shù)字來引用它們。
變量作用域:分全局,局部。
全局變量,可以在腳本中的任何位置被引用。一旦你在某個腳本里聲明了一個全局變量,就可以從這個腳本中的任何位置,包括函數(shù)內(nèi)部,引用它。全局變量的作用域是整個腳本。 局部變量,只存在于聲明它的那個函數(shù)的內(nèi)部,在那個函數(shù)的外部是無法引用它的。局部變量的作用域僅限于某個特定的函數(shù)。
7.DOM
getElementByIdgetElementsByTagNamegetElementsByClassNamegetAttributesetAttribute
JavaScript語言里的對象
用戶定義對象,由程序員自己創(chuàng)建的對象 內(nèi)建對象,內(nèi)建在JavaScript語言里的對象 宿主對象,由瀏覽器提供的對象
window對象,瀏覽器窗口本身,整個對象的屬性和方法通常稱為BOM,瀏覽器對象模型。 節(jié)點:元素節(jié)點,文本節(jié)點,屬性節(jié)點
獲取元素節(jié)點的方法:通過元素ID,通過標簽名,通過類名字
getElementById,這個方法將返回一個與那個給定id屬性值的元素節(jié)點對應(yīng)的對象。document.getElementById(id)getElementsByTagName,這個方法返回一個對象數(shù)組,每個對象分別對應(yīng)著文檔里有著給定標簽的一個元素。element.getElementsByTagName(tag)getElementsByClassName,這個方法能夠通過Class屬性中的類名來訪問元素
獲取和數(shù)值屬性:
getAttribute方法就是用來獲取屬性-object.getAttribute(attribute)setAttribute方法可以用來更改屬性節(jié)點的值-object.setAttribute(attribute,value)
示例:
var node = document.getElementsByTagName("p");
for(let i=0, i<node.length; i++){
console.log(node[i].getAttribute("title"));
}
var node = document.getElementsByTagName("p");
node.setAttribute("title","dadaqianduan.cn");
8.a標簽
target屬性決定_blank在新窗口中打開被鏈接文檔_self默認,在相同的框架中打開被鏈接文檔
9.函數(shù)

帶有參數(shù)默認值的函數(shù):
// es5
function Fun(da, da2) {
da = da || 'dadaqianduan';
da2 = da2 || '1024bibi.com';
}
升級改造,typeof來檢測參數(shù)的類型:
function fun(da) {
da = (typeof da !== 'undefined") ? da : 'dadaqianduan';
}
// es6
funtion da(da='掘金魔王哪吒', callback = function(){}) {
}
參數(shù)默認值如何影響arguments對象
arguments對象會在使用參數(shù)默認值時會有所不同 在非嚴格模式下,arguments對象總是會被更新以反映出具名參數(shù)的變化 es5嚴格模式下,不再反映出具名參數(shù)的變化
如下所示:
function fn(a) {
console.log(a === arguments[0]);
a = '達達前端';
console.log(a === arguments[0]);
}
fn('dadaqianduan');

function fn(a) {
"use strict";
console.log(a === arguments[0]);
a = '達達前端';
console.log(a === arguments[0]);
}
fn('dadaqianduan');

參數(shù)默認值表達式
示例:
function getValue() {
return 1;
}
function add(a, b = getValue()) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(2); // 3
let value = 5;
function getValue() {
return value++;
}
function add(a,b=getValue()) {
return a+b;
}
console.log(add(1,1)); // 2
console.log(add(1)); // 6
console.log(add(1)); // 7
function add(a,b=a) {
return a + b;
}
console.log(add(1,1));
console.log(add(1));
function getValue(value) {
return value + 5;
}
function add(a, b = getValue(a)) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(1)); // 7
function add(a = b, b) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(undefined,1)); // 拋出錯誤
參數(shù)默認值的暫時性死區(qū)
函數(shù)每個參數(shù)都會創(chuàng)建一個新的標識符綁定,它在初始化之前不允許被訪問,否則會拋出錯誤。
es5中的不具名參數(shù)
示例:
function da(object) {
let result = Object.create(null);
for(let i = 1, len = arguments.length; i<len; i++) {
result[arguments[i]] = object[arguments[i]];
}
return result;
}
let book = {
a: '1',
b: '2',
c: '3'
};
let da1 = da(book, 'a', 'b');
console.log(da1.a); // 1
console.log(da2.b); // 2
剩余參數(shù)
剩余參數(shù)由三個點(...)與一個緊跟著的具名參數(shù)指定。
function fn(object, ...keys) {
let result = Object.reate(null);
for(let i = 0, len = keys.length; i<len; i++) {
result[key[i]] = object[keys[i]];
}
return result;
}
剩余參數(shù):函數(shù)只能有一個剩余參數(shù),并且它必須被放在最后。 剩余參數(shù):不能在對象字面量的setter屬性中使用
let object = {
// 語法錯誤:不能在setter中使用剩余參數(shù)
set name(...value) {
// 一些操作
}
};
arguments對象在函數(shù)被調(diào)用時反映了傳入的參數(shù) arguments對象總能正確反映被傳入函數(shù)的參數(shù)
function fn(...args) {
console.log(args.length);
console.log(arguments.length);
console.log(args[0], arguments[0]);
console.log(args[1], arguments[1]);
}
fn("a","b");
// 2
// 2
// a a
// b b
函數(shù)構(gòu)造器的增強能力(es6默認參數(shù)以及剩余參數(shù))
var add = new Function("a", "b", "return a + b");
console.log(add(1,1)); // 2
var da = new Function("a", "b=a", "return a+b");
console.log(da(1,1)); // 2
console.log(da(1)); // 2
擴展運算符
示例:
// es5
let arr = [1,2,3,4,5];
console.log(Math.max.apply(Math, arr)); // 5
// es6
let arr = [1,2,3,4,5];
console.log(Math.max(...values)); // 5
let arr2 = [-2,-3,-4];
console.log(Math.max(...arr2, 0)); // 0
es6函數(shù)名稱屬性
示例:
function da() {}
console.log(da.name); // da
var dada = function() {}
console.log(dada.name); // dada

名稱屬性的特殊情況

明確函數(shù)的雙重用途:當使用new時,函數(shù)內(nèi)部的this是一個新對象,并作為函數(shù)的返回值。
當函數(shù)未使用 new 進行調(diào)用時, call 方法會被執(zhí)行,運行的是代碼中顯示的函數(shù)體。
當函數(shù)使用 new 進行調(diào)用時, Construct 方法則會被執(zhí)行,負責創(chuàng)建一個被稱為新目標的新的對象,并且使用該新目標作為 this 去執(zhí)行函數(shù)體。
es6引入new.target元屬性
function Fun(value) {
if(this instanceof Fun) {
this.value = value;
} else {
throw new Error("dadaqianduan");
}
}
var da = new Fun("dada");
var dadaqianduan = Fun("123"); // 報錯
function Fun(value) {
if(this instanceof Fun) {
this.value = value;
} else {
throw new Error("dadaqianduan");
}
}
var da = new Fun("dada");
var dadaqianduan = Fun.call(da, "dadaqianduan"); // ok
function Fun(value) {
// 是否被定義
if(typeof new.target !== "undefined") {
this.value = value;
}else{
throw new Error("dadaqianduan.cn");
}
}
var da = new Fun("jeskson");
var da2 = Fun.call(da, 'jeskson'); // 報錯
function Fun(value) {
if(new.target === Fun) {
this.value = value;
}else{
throw new Error("dadaqianduan.cn");
}
}
function Da(value) {
Fun.call(this, name);
}
var person = new Fun("dadaqianduan.cn");
var person1 = new Da("dadaqianduan.cn"); // 報錯
10.uni-app與藍牙設(shè)備的傳輸
初始化藍牙模塊 搜索藍牙設(shè)備 連接藍牙設(shè)備 選擇設(shè)備服務(wù) 獲取服務(wù)的特征值 訂閱特征值 發(fā)送數(shù)據(jù) 發(fā)送成功
初 始 化 藍 牙
uni.openBluetoothAdapter(OBJECT)開 始 搜 索 藍 牙 設(shè) 備
uni.startBluetoothDevicesDiscovery(OBJECT)發(fā) 現(xiàn) 外 圍 設(shè) 備
uni.onBluetoothDeviceFound(CALLBACK)停 止 搜 尋 附 近 的 藍 牙 外 圍 設(shè) 備
uni.stopBluetoothDevicesDiscovery(OBJECT)連 接 低 功 耗 藍 牙 設(shè) 備
uni.createBLEConnection(OBJECT)獲 取 藍 牙 設(shè) 備 所 有 服 務(wù)
uni.getBLEDeviceServices(OBJECT)獲 取 藍 牙 特 征
uni.getBLEDeviceCharacteristics(OBJECT)啟用藍牙設(shè)備特征值變化時的
notify功能
uni.notifyBLECharacteristicValueChange(OBJECT)
監(jiān)聽低功耗藍牙設(shè)備的特征值變化
uni.onBLECharacteristicValueChange(CALLBACK)
初始化藍牙(檢測一下手機藍牙是否打開)
uni.openBluetoothAdapter({
success:(res) => {
// 已打開
uni.getBluetoothAdapterState({ // 藍牙的匹配狀態(tài)
success: (res1) => {
console.log(res1, "本機設(shè)備的藍牙已打開")
// 開始搜索藍牙設(shè)備
this.startBluetoothDeviceDiscovery()
},
fail:(error)=>{
uni.showToast({icon:'none',title:'查看手機藍牙是否打開'
}
});
},
fail: (err) => {
// 未打開
uni.showToast({icon:'none',title:'查看手機藍牙是否打開'});
}
})
開始搜索藍牙設(shè)備
startBluetoothDeviceDiscovery() {
uni.startBluetoothDevicesDiscovery({
success:(res) => {
console.log('startBluetoothDevicesDiscovery success', res)
// 發(fā)現(xiàn)設(shè)備
this.onBluetoothDeviceFound()
},
fail:(err) => {
console.log(err, '錯誤信息');
}
})
}
發(fā)現(xiàn)設(shè)備,獲取設(shè)備id
onBluetoothDeviceFound() {
uni.onBluetoothDeviceFound((res) => {
// 搜索到的設(shè)備存儲起來
if(this.list.indexOf(res.devices[0].deviceId) === -1){
this.list.push(res.devices[0].deviceId)
}
})
}
點擊選擇自己需要連接的設(shè)備,連接藍牙設(shè)備
createBLEConnection(deviceId) {
this.deviceId = deviceId
// 連接藍牙
uni.createBLEConnection({
deviceId: this.deviceId,
success:(res) =>{
this.stopBluetoothDeviceDiscovery()
console.log("藍牙連接成功")
},
fail:(res) =>{
console.log('藍牙連接失敗',res)
}
})
}
連接成功后,要停止搜索設(shè)備
stopBluetoothDevicesDiscovery(){
uni.stopBluetoothDevicesDiscovery({
success: e=> {
this.loading = false
console.log('停止搜索藍牙設(shè)備:' + e.errMsg);
},
fail: e=> {
console.log('停止搜索藍牙設(shè)備失敗,錯誤碼:' + e.errCode);
}
});
}
獲取藍牙設(shè)備所有服務(wù),setTimeout等待一秒種再去獲取,直接獲取我們可能出現(xiàn)獲取不到的情況
//獲取藍牙特征
getBLEDeviceCharacteristics(){
console.log("進入特征");
setTimeout(()=>{
uni.getBLEDeviceCharacteristics({
// 這里的 deviceId 需要已經(jīng)通過 createBLEConnection 與對應(yīng)設(shè)備建立鏈接
deviceId:this.deviceId,
// 這里的 serviceId 需要在 getBLEDeviceServices 接口中獲取
serviceId:this.serviceId,
success:(res)=>{
console.log(res,'特征getBLEDeviceCharacteristics')
this.characteristics = res.characteristics
console.log(this.characteristics)
//循環(huán)所有的uuid
res.characteristics.forEach((item)=>{
if(item.uuid.indexOf("LD") != -1){
console.log('characteristicId:', item.uuid)
//利用傳參的形勢傳給下面的notify,這里的uuid如果都需要用到,就不用做判斷了,建議使用setTimeout進行間隔性的調(diào)用此方法
this.notifyBLECharacteristicValueChange(item.uuid)
}
})
},
fail:(res)=>{
console.log(res)
}
})
},1000)
},
啟用藍牙設(shè)備特征值變化時的 notify 功能
啟動notify功能,才能知道我們當前藍牙的讀寫狀態(tài),
“properties”: {
“read”: true, //讀
“write”: true, //寫
“notify”: true, //廣播
“indicate”: false
}
// 啟用 notify 功能
notifyBLECharacteristicValueChange(characteristicId){
console.log(characteristicId,'characteristicId')
uni.notifyBLECharacteristicValueChange({
state: true, // 啟用 notify 功能
deviceId:this.deviceId,
serviceId:this.serviceId,
characteristicId:characteristicId,
success:(res)=> {
console.log(res)
// console.log(this.characteristicId)
console.log('notifyBLECharacteristicValueChange success', res.errMsg)
},
fail:(res)=> {
console.log('notifyBLECharacteristicValueChange success2', res.errMsg)
}
})
},
等待:
//獲取藍牙的所有服務(wù)
getBLEDeviceServices(){
setTimeout(()=>{
uni.getBLEDeviceServices({
deviceId:this.deviceId,
success:(res)=>{
console.log('device services:', res)
res.services.forEach((item)=>{
if(item.uuid.indexOf("LD")!=-1){
// this.serviceId = item.uuid;
//存儲到狀態(tài)
this.$store.commit("upserviceId",item.uuid)
console.log(this.serviceId)
// 這里獲取回調(diào),讀取成功就的值就會在這個地方接收到!!!
uni.onBLECharacteristicValueChange((res)=>{
console.log("監(jiān)聽成功",res)
//res.value是ArrayBuffer類型的,官方給了一個方法轉(zhuǎn)16進制,我們再進行操作
this.shiliu = this.ab2hex(res.value)
})
this.getBLEDeviceCharacteristics()
}
})
}
})
},1000)
}
讀取藍牙設(shè)備
示例:
//在頁面加載時候初始化藍牙適配器
uni.openBluetoothAdapter
// 初始化完畢開始搜索
this.startBluetoothDeviceDiscovery()
console.log("開始搜尋智能設(shè)備");
uni.startBluetoothDevicesDiscovery
success: res => {
self.onBluetoothDeviceFound();
},
onBluetoothDeviceFound
console.log('開始監(jiān)聽尋找到新設(shè)備的事件');
stopBluetoothDevicesDiscovery
uni-app藍牙:
// 代碼
//初始藍牙模塊
this.pDeviceInfo = uni.getStorageSync('deviceInfo');
if(!!this.pDeviceInfo){
this.prevConnected = true;
}
initBluetoothModule(){
//初始藍牙模塊
uni.openBluetoothAdapter({
success:res=> {
this.searchBlueList();
},
fail:err=>{
console.log(err)
}
})
},
searchBlueList(){
//開啟藍牙搜索
uni.startBluetoothDevicesDiscovery({
success:res=> {
setTimeout(()=>{
this.getBlueList();
uni.showToast({
title: '開啟成功',
icon: 'success',
duration: 1000
});
},1000);
},
})
},
getBlueList(){
//獲取搜索列表
uni.getBluetoothDevices({
success:res=> {
let data = res.devices
let tempList=[];
data.map(device=>{
if(!!device.localName){
tempList.push(device)
}
});
this.deviceNum = tempList.length;
this.deviceList=tempList;
this.listenBluetooth();
}
});
},
listenBluetooth(){
let tempList =this.deviceList;
//監(jiān)聽藍牙搜索
uni.onBluetoothDeviceFound((res) => {
let flag = false;
res.devices.forEach(device => {
if(!!device.localName){
tempList.push(device)
flag =true;
}
})
if(flag){
this.deviceList=tempList;
this.deviceNum = this.deviceList.length;
}
})
},
connetBlue(type,index){
let deviceIndex = index;
let deviceInfo = this.deviceList[deviceIndex];
if(this.prevConnected && type == 1){
deviceInfo = this.pDeviceInfo;
}
let dId = deviceInfo.deviceId;
uni.showLoading({
title: '正在連接...', //提示的內(nèi)容,
mask: true
});
//連接藍牙
uni.createBLEConnection({
deviceId: dId,//設(shè)備id
success: res=> {
uni.hideLoading();
if(res.errCode == 0){
this.connected = true;
this.connectedName=deviceInfo.name;
uni.setStorageSync('deviceInfo',deviceInfo);
this.deviceId=dId;
uni.showToast({
title: '連接成功',
icon: 'success',
duration: 1000
});
}
uni.stopBluetoothDevicesDiscovery({
success: res => {
console.log('連接藍牙成功之后關(guān)閉藍牙搜索');
}
})
},
fail:err=>{
uni.showToast({
title: '連接失敗!',
icon: 'none',
duration: 2000
});
}
})
},
getBLEDeviceServices(){
//獲取服務(wù)
uni.showLoading({
title: '正在打印...', //提示的內(nèi)容,
mask: true
});
let deviceId = this.deviceId;
uni.getBLEDeviceServices({
deviceId,
success: (res) => {
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary) {
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
}
}
},
fail: (res) => {
uni.hideLoading();
console.log("獲取藍牙服務(wù)失敗:" + JSON.stringify(res))
}
})
},
//獲取單個服務(wù)的特征值(characteristic)
getBLEDeviceCharacteristics(deviceId, serviceId){
if(!!this.characteristics && !!this.serviceId){
this.PrintStr();
return;
}
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => {
uni.hideLoading();
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.properties.write && !this.serviceId) {
this.serviceId = serviceId;
this.characteristics = item.uuid;
this.PrintStr();
}
}
},
fail(res) {
uni.hideLoading();
console.error('獲取特征值失敗:', res)
}
})
},
closeBluetoothAdapter(){
uni.closeBluetoothAdapter({
success: res => {
console.log('關(guān)閉藍牙適配器');
}
});
},
onUnload() {
this.closeBluetoothAdapter();
}
回看筆者往期高贊文章,也許能收獲更多喔!
JS葵花寶典秘籍筆記,為你保駕護航金三銀四 TypeScript趁早學(xué)習(xí)提高職場競爭力 一個合格的初級前端工程師需要掌握的模塊筆記 前端模擬面試字數(shù)過23477萬內(nèi)容 Vue.js筆試題解決業(yè)務(wù)中常見問題 【初級】個人分享Vue前端開發(fā)教程筆記 長篇總結(jié)之JavaScript,鞏固前端基礎(chǔ) 前端面試必備ES6全方位總結(jié) 達達前端個人web分享92道JavaScript面試題附加回答 【圖文并茂,點贊收藏哦!】重學(xué)鞏固你的Vuejs知識體系 【思維導(dǎo)圖】前端開發(fā)-鞏固你的JavaScript知識體系 14期-連肝7個晚上,總結(jié)了計算機網(wǎng)絡(luò)的知識點!(共66條) 這是我的第一次JavaScript初級技巧 localStorage和sessionStorage本地存儲 HTML5中的拖放功能 挑戰(zhàn)前端知識點HTTP/ECMAScript 必學(xué)必會-音頻和視頻 前端170面試題+答案學(xué)習(xí)整理(良心制作) 前端HTML5面試官和應(yīng)試者一問一答 哪吒鬧海,席卷圖文學(xué)習(xí)前端Flex布局 騰訊位置服務(wù)開發(fā)應(yīng)用 【進階】面試官問我Chrome瀏覽器的渲染原理(6000字長文) 面試官一上來就問我Chrome底層原理和HTTP協(xié)議(萬字長文) 熬夜總結(jié)了 “HTML5畫布” 的知識點 this/call/apply/bind(萬字長文) HTTP/HTTPS/HTTP2/DNS/TCP/經(jīng)典題 執(zhí)行上下文/作用域鏈/閉包/一等公民 Web頁面制作基礎(chǔ) 學(xué)習(xí)總結(jié)之HTML5劍指前端(建議收藏,圖文并茂)
??關(guān)注+點贊+收藏+評論+轉(zhuǎn)發(fā)??
點贊、收藏和評論
我是Jeskson(達達前端),感謝各位人才的:點贊、收藏和評論,我們下期見!(如本文內(nèi)容有地方講解有誤,歡迎指出?謝謝,一起學(xué)習(xí)了)
我們下期見!
文章持續(xù)更新,可以微信搜一搜「 程序員哆啦A夢 」第一時間閱讀,回復(fù)【資料】有我準備的一線大廠資料,本文 https://www.1024bibi.com 已經(jīng)收錄
github收錄,歡迎Star:https://github.com/webVueBlog/WebFamily
愛心三連擊
1.看到這里了就點個在看支持下吧,你的在看是我創(chuàng)作的動力。
2.關(guān)注公眾號,獲取更多前端硬核文章!加個星標,不錯過每一條成長的機會。
3.如果你覺得本文的內(nèi)容對你有幫助,就幫我轉(zhuǎn)發(fā)一下吧。
