<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端日常總結(jié)

          共 38443字,需瀏覽 77分鐘

           ·

          2021-04-28 23:22

          • 推薦:TypeScript趁早學(xué)習(xí)提高職場競爭力

          Github來源: | 求星星 ? | 給個??關(guān)注,??點贊,??鼓勵一下作者

          希望能夠幫助更多的小伙伴。加我??即可交流問題(不是大佬,互相學(xué)習(xí),創(chuàng)造良好的學(xué)習(xí)環(huán)境)。以下哪些你不懂呢?

          image.png

          1.關(guān)于es5和es6得繼承問題

          • es5的繼承是 先創(chuàng)建子類的實例對象,然后將父類的方法添加到this上,Parent.apply(this)
          • es6的繼承是 先創(chuàng)建父類的實例對象this,所以先調(diào)用父類的super()方法,然后再用子類的構(gòu)造函數(shù)修改this
          • es5的繼承是 通過原型或構(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.塊級綁定

          image.png

          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)建:

          塊級作用域:

          1. 在一個函數(shù)的內(nèi)部
          2. 在一個代碼塊內(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 = '魔王哪吒好帥';
          image.png

          有圖有真相

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

          var da = 12;

          // 不會拋出錯誤
          if (true) {
           let da = 123;
          }
          image.png

          常量的聲明

          • 使用const聲明的變量會被認為時常量constant,表示它們的值被設(shè)置完成后就不能再被改變了

          所以啊,所有的const聲明的變量都需要(在聲明時)進行初始化:

          // 有效的常量
          const da = 12;

          // 語法錯誤:未進行初始化
          const dada;
          image.png
          • 記住:常量聲明與let聲明是一樣的,都是塊級聲明(上述)見上

          示例:

          if(value) {
           const da = '掘金魔王哪吒'
          }
          // da 在此處無法訪問

          無論是在嚴格模式還是非嚴格模式下:對之前用const聲明的常量進行賦值會拋出錯誤

          const da = '掘金:魔王哪吒,好帥'

          da = '是很帥的,魔王哪吒' // 拋出錯誤

          const聲明常量,如果使用const聲明對象如下描述:

          const聲明 會阻止對于 變量綁定 與 變量自身值的修改,這意味著 const 聲明并不會阻止對變量成員的修改。

          阻止:變量綁定,變量自身值的修改

          不阻止:變量成員的修改

          示例:

          // dada 在初始化時綁定了帶有一個屬性的對象
          const dada = {
           string: 'dadaqianduan.cn億萬少女的夢'
          };

          // 正常
          dada.string = '掘金魔王哪吒:億萬少女的夢';

          // 拋出錯誤
          dada = {
           string: '魔王哪吒,你在做夢呢'
          };
          image.png
          • const阻止的是對于變量綁定的修改
          • const不會阻止對成員值的修改

          暫時性死區(qū)

          什么是暫時性死區(qū)呢?就是之前說過,使用let或者是const聲明的變量,在沒有達到聲明處之前是無法訪問的,如果訪問會導(dǎo)致引用錯誤。就算是在安全情況下,也是一樣。

          如下:

          if(value) {
           console.log(typeof da); // 引用錯誤
           let da = '達哥好帥';
          }
          image.png

          當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';
          }
          image.png

          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
          });
          image.png
          • 每次循環(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
          });
          image.png

          注意:使用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ū)別

          1. textContent 會獲取style="display:none中的文本,而innerText不會
          2. textContent會獲取style標簽里面的文本,而innerText不會
          3. textContent不會理會html格式,直接輸出不換行的文本
          4. innerText會根據(jù)標簽里面的元素獨立一行
          5. innerText會根據(jù)標簽里面的元素獨立一行
          6. innerTextIE的兼容性較好
          7. textContent雖然作為標準方法但是只支持IE8+以上的瀏覽器

          5.el.childrenel.childNodes的區(qū)別

          1. el.children,返回指定節(jié)點的所有element子節(jié)點,即返回節(jié)點元素
          2. el.childNodes,返回指定節(jié)點的所有子節(jié)點,包括節(jié)點元素和文本元素

          6.JavaScript語法

          image.png
          1. 方法:將JavaScript代碼放到文檔<head>標簽中的<script標簽之間
          2. 方法:在文檔的<head>部分放一個<script>標簽,并把它的src屬性指向該文件
          3. 方法:把<script>標簽放到HTML文檔的最后,</body>標簽之前(這樣能使瀏覽器更快加載頁面)
          4. JavaScript變量名允許包含字母,數(shù)字,美元符號和下劃線(但第一個字符不允許是數(shù)字)
          5. 通常駝峰格式是函數(shù)名,方法名和對象屬性名命名的首選格式。
          6. JavaScript中幾種數(shù)據(jù)類型:字符串,數(shù)值,布爾值,數(shù)組,對象。
          7. 由瀏覽器提供的預(yù)定義對象被稱為宿主對象。
          8. typeof操作符可以告訴我們它的操作數(shù)是一個字符串,數(shù)值,函數(shù),布爾值還是對象。
          • 字符串:字符串由零個或多個字符構(gòu)成。字符包括(但不限于)字母,數(shù)字,標點符號和空格。
          • 如果字符串包含雙引號,就把整個字符串放在單引號里;如果字符串包含單引號,就把整個字符串放在雙引號里。
          • 用對象來代替?zhèn)鹘y(tǒng)數(shù)組的做法意味可以通過元素的名字而不是下標數(shù)字來引用它們。

          變量作用域:分全局,局部。

          1. 全局變量,可以在腳本中的任何位置被引用。一旦你在某個腳本里聲明了一個全局變量,就可以從這個腳本中的任何位置,包括函數(shù)內(nèi)部,引用它。全局變量的作用域是整個腳本。
          2. 局部變量,只存在于聲明它的那個函數(shù)的內(nèi)部,在那個函數(shù)的外部是無法引用它的。局部變量的作用域僅限于某個特定的函數(shù)。

          7.DOM

          1. getElementById
          2. getElementsByTagName
          3. getElementsByClassName
          4. getAttribute
          5. setAttribute

          JavaScript語言里的對象

          1. 用戶定義對象,由程序員自己創(chuàng)建的對象
          2. 內(nèi)建對象,內(nèi)建在JavaScript語言里的對象
          3. 宿主對象,由瀏覽器提供的對象
          • window對象,瀏覽器窗口本身,整個對象的屬性和方法通常稱為BOM,瀏覽器對象模型。
          • 節(jié)點:元素節(jié)點,文本節(jié)點,屬性節(jié)點

          獲取元素節(jié)點的方法:通過元素ID,通過標簽名,通過類名字

          1. getElementById,這個方法將返回一個與那個給定id屬性值的元素節(jié)點對應(yīng)的對象document.getElementById(id)
          2. getElementsByTagName,這個方法返回一個對象數(shù)組,每個對象分別對應(yīng)著文檔里有著給定標簽的一個元素。element.getElementsByTagName(tag)
          3. getElementsByClassName,這個方法能夠通過Class屬性中的類名來訪問元素

          獲取和數(shù)值屬性:

          1. getAttribute方法就是用來獲取屬性-object.getAttribute(attribute)
          2. 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ù)

          image.png

          帶有參數(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');
          image.png
          function fn(a) {
           "use strict";
           console.log(a === arguments[0]);
           a = '達達前端';
           console.log(a === arguments[0]);
          }
          fn('dadaqianduan');
          image.png

          參數(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
          image.png

          名稱屬性的特殊情況

          image.png

          明確函數(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è)備的傳輸

          1. 初始化藍牙模塊
          2. 搜索藍牙設(shè)備
          3. 連接藍牙設(shè)備
          4. 選擇設(shè)備服務(wù)
          5. 獲取服務(wù)的特征值
          6. 訂閱特征值
          7. 發(fā)送數(shù)據(jù)
          8. 發(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ā)一下吧。

          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆传媒无码 | 亚洲最大中文字幕在线 | 污网站视频 | 欧美又粗又大一区二区 | 日韩色情在线观看 |