工作中遇到的問題及小知識點


 

一、本地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格式

     let newdate = new FormData()
               newdate.append('title', item.file.name);
               newdate.append('tags', 'brand_action_upload');    
               newdate.append('multipartFile', result);

  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>");一句搞定它不香么

二十四、整行字體漸變色

    .title span {
      background: linear-gradient(135deg,#f2e1b5, #fff3d6 33%, #e8ce91);
      -webkit-background-clip:text;
      color:transparent;
    }
 
 
二十五、css3 之image之object-fit作用
//默認值。替換內容拉伸填滿整個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'
        });
    }
}


//點擊切換錨點鏈接
function clickMao() {
    $(".activity_main_li").each(function(i, item) {
        $(item).click(function(e) {
            $(".activity_main_li").removeClass("active")
            $(this).addClass("active");
            let id = $(this).attr("currentName");
            currentGun = true;
            let to = allHeights[i] - 45;
            scrollX(i)
            $('html,body').animate({
                scrollTop: to
            }, 500)
            setTimeout(_ => {
                currentGun = false;
            }, 600)
        })
    })
}

//標簽橫向滾動
function scrollX(index) {
    let MarL = $(".activity_main_li").width() * index - 80
    $('.activity_main_ul').animate({
        scrollLeft: MarL
    }, 200)
}
 

 

&&&&&&&&&&&&&&&&&&&《項目中的知識點》&&&&&&&&&&&&&&&&&&&&&&&&

 

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()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM