公司項目過程中遇到的問題(11-20)

一、前言

卑微小前端開始工作了。開始記錄一下自己在工作中遇到的問題,有些是粗心出的錯,有些是基礎不紮實遇到的問題。有些則是真的不知道有這種操作纔出現的問題。總之就記錄自己的在公司項目中遇到的各式各樣的問題。也算是記錄一下自己的成長。也方便自己之後遇到相同問題的時候。可以直接來自己博客找。大部分內容都源自別人寫的博客,算是個縫合怪。。。。嘛。。起碼我這東西還是自己試過可行的。

二、內容

11.js報錯:Cannot read property ‘getAttribute’ of null問題

在使用echarts時,在圖表元素並未加載的情況下進行eharts.init(),會發生此錯誤,因爲eharts並未找到該元素,故無法對其進行渲染。

解決方案:

1.查看填寫的id是否真實存在,若不存在,當然無法根據getElementById來找到該元素;

2.將js文件放在html代碼的後部;

拓展:

不僅是在echarts時,只要是出現對元素操作時均有可能報此錯誤,表示未找到指定的元素。

我看你這個表格的初始化在mounted的時候,通過調用this.drawLine();來實現的,但是你的charts這時候不在頁面節點中,因爲boxShow爲false,所以初始化不成功。echats初始化的時候,節點一定要是在頁面中真實存在的。

12.Vue中使用eChart

由於在項目中需要對數據進行可視化處理,也就是用圖表展示,衆所周知echarts是非常強大的插件。一開始想在網上找一個基於vue封裝好的(懶省事),eg:vue-echarts ,但是拉取下來發現,跟項目中使用的類型有點偏差,而且他們的數據大多都是定製好的,我很難在此基礎上進行更改(惹不起),於是選擇了放棄,最終還是選擇echarts。以下是我使用的一些心得體會~

我的示例是在vue-cli搭建

安裝echarts依賴

npm install echarts -S
或者使用淘寶的鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install echarts -S

創建圖表

首先需要全局引入
在main.js中

// 引入echarts
import echarts from ‘echarts’
Vue.prototype.$echarts = echarts

在Echarts.vue中

export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  mounted(){
    this.drawLine();
  },
  methods: {
    drawLine(){
        // 基於準備好的dom,初始化echarts實例
        let myChart = this.$echarts.init(document.getElementById('myChart'))
        // 繪製圖表
        myChart.setOption({
            title: { text: '在Vue中使用echarts' },
            tooltip: {},
            xAxis: {
                data: ["襯衫","羊毛衫","雪紡衫","褲子","高跟鞋","襪子"]
            },
            yAxis: {},
            series: [{
                name: '銷量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        });
    }
  }
}

注意:我們要在mounted生命週期函數中實例化echarts對象。因爲我們要確保dom元素已經掛載到頁面中

img

image.png

這樣一個簡單的圖表就完成了,是不是覺得很簡單?假如在一個大型的項目中,而且數據是非常複雜的?那麼該如何操作?

按需引入

由於全局引入會將所有的echarts圖表打包,導致體積過大
在Echarts.vue文件中

// 引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入柱狀圖組件
require('echarts/lib/chart/bar')
// 引入提示框和title組件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')

使用 require 而不是 import

基於前面的疑問,加上實際運用到項目中遇到的一些問題,我思考使用組件的形式。

以組件的形式用echarts

從上邊可以看出,你每次在使用echarts的時候,都必須要重複的引入,這樣很不方便
vue作爲一個組件化開發的框架,我們可以使用組件的方式進行集成。每次我們引入組件,進行使用,這樣就方便的多。
下面是一個我自己對echarts進行的一個簡單的vue組件的集成。
在echarts中
子組件:
img

props部分是我接收到的參數,父組件獲取數據分發,data是父組件分發給echarts的數據源。

父組件:

img

如果在大型的項目,而且圖表又非常的多,那麼vuex少不了。如果把數據集中存儲到了vuex中,echarts組件再從vuex中獲取數據,我們也能隨時保存獲取的結果,對這些數據可以添加收藏也可以加入緩存中,下次再請求可以先從緩存調用。

13.Array.from

ES6爲Array增加了from函數用來將其他對象轉換成數組。

當然,其他對象也是有要求,也不是所有的,可以將兩種對象轉換成數組。

1.部署了Iterator接口的對象,比如:Set,Map,Array。

2.類數組對象,什麼叫類數組對象,就是一個對象必須有length屬性,沒有length,轉出來的就是空數組。

轉換map

將Map對象的鍵值對轉換成一個一維數組。

實際上轉換出來的數組元素的序列是key1,value1,key2,value2,key3,value3…

const map1 = new Map();
map1.set('k1', 1);
map1.set('k2', 2);
map1.set('k3', 3);
console.log('%s', Array.from(map1))

結果:

k1,1,k2,2,k3,3

轉換set

將Set對象的元素轉換成一個數組。

const set1 = new Set();
set1.add(1).add(2).add(3)
console.log('%s', Array.from(set1))

結果

1,2,3

轉換字符串

可以吧ascii的字符串拆解成一個數據,也可以準確的將unicode字符串拆解成數組。

console.log('%s', Array.from('hello world'))
console.log('%s', Array.from('\u767d\u8272\u7684\u6d77'))

結果:

h,e,l,l,o, ,w,o,r,l,d
白,色,的,海

類數組對象

一個類數組對象必須要有length,他們的元素屬性名必須是數值或者可以轉換成數值的字符。

注意:屬性名代表了數組的索引號,如果沒有這個索引號,轉出來的數組中對應的元素就爲空。

console.log('%s', Array.from({
  0: '0',
  1: '1',
  3: '3',
  length:4
}))

結果:

0,1,,3

如果對象不帶length屬性,那麼轉出來就是空數組。

console.log('%s', Array.from({
  0: 0,
  1: 1
}))

結果就是空數組。

對象的屬性名不能轉換成索引號時。

console.log('%s', Array.from({
  a: '1',
  b: '2',
  length:2
}))

結果也是空數組

Array.from可以接受三個參數

我們看定義:

Array.from(arrayLike[, mapFn[, thisArg]])

arrayLike:被轉換的的對象。

mapFn:map函數。

thisArg:map函數中this指向的對象。

第二個參數,map函數

用來對轉換中,每一個元素進行加工,並將加工後的結果作爲結果數組的元素值。

console.log('%s', Array.from([1, 2, 3, 4, 5], (n) => n + 1))

結果:

上面的map函數實際上是給數組中的每個數值加了1。

2,3,4,5,6

第三個參數,map函數中this指向的對象

該參數是非常有用的,我們可以將被處理的數據和處理對象分離,將各種不同的處理數據的方法封裝到不同的的對象中去,處理方法採用相同的名字。

在調用Array.from對數據對象進行轉換時,可以將不同的處理對象按實際情況進行注入,以得到不同的結果,適合解耦。

這種做法是模板設計模式的應用,有點類似於依賴注入。

let diObj = {
  handle: function(n){
    return n + 2
  }
}
console.log('%s', Array.from(
  [1, 2, 3, 4, 5], 
  function (x){
    return this.handle(x)
  }, 
  diObj))

結果:

3,4,5,6,7

14.請求頭帶不上數據(暫且不懂)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-nkDrYiOk-1593335281024)(C:\Users\wuyuxin\AppData\Roaming\Typora\typora-user-images\image-20200414112405550.png)]

15.vue父子組件通信方式詳解以及vue報錯Injection “elForm” not found

vue父子組件通信方式
https://www.jb51.net/article/140581.htm
Injection “elForm” not found
在利用element 中的dialog的時候報錯Injection “elForm” not found
在網上搜索說是因爲vue版本和element版本不匹配之類的,但是我出現這個問題的原因是因爲:

  <el-form>
        <el-form-item label="ccc">12
   直接寫了el-form-item而沒用 el-form包裹住

本日感想:
寫代碼的時候要嚴謹…

16.CSS巧妙實現分隔線的幾種方法

單個標籤實現分隔線:

點此查看實例展示

html:

<div class="line_01">小小分隔線 單標籤實現</div>

css:

.demo_line_01{
    padding: 0 20px 0;
    margin: 20px 0;
    line-height: 1px;
    border-left: 200px solid #ddd;
    border-right: 200px solid #ddd;
    text-align: center;
}

優點:代碼簡潔

巧用背景色實現分隔線:

點此查看實例展示

html:

<div class="line_02"><span>小小分隔線 巧用色實現</span></div>

css:

.demo_line_02{
    height: 1px;
    border-top: 1px solid #ddd;
    text-align: center;
}
.demo_line_02 span{
    position: relative;
    top: -8px;
    background: #fff;
    padding: 0 20px;
}

優點:代碼簡潔,可自適應寬度

inline-block實現分隔線:

點此查看實例展示

html:

<div class="line_03"><b></b><span>小小分隔線 inline-block實現</span><b></b></div>

css:

.demo_line_03{
    width:600px;
}
.demo_line_03 b{
    background: #ddd;
    margin-top: 4px;
    display: inline-block;
    width: 180px;
    height: 1px;
    _overflow: hidden;
    vertical-align: middle;
}
.demo_line_03 span{
    display: inline-block;
    width: 220px;
    vertical-align: middle;
}

浮動實現分隔線:

點此查看實例展示

html:

<div class="line_04"><b></b><span>小小分隔線 浮動來實現</span><b></b></div>

css:

.demo_line_04{
    width:600px;
}
.demo_line_04{
    overflow: hidden;
    _zoom: 1;
}
.demo_line_04 b{
    background: #ddd;
    margin-top: 8px;
    float: left;
    width: 26%;
    height: 1px;
    _overflow: hidden;
}

利用字符實現分隔線:

點此查看實例展示

html:

<div class="line_05">———————————<span>小小分隔線 字符來實現</span>————————————</div>

css:

.demo_line_05{
    letter-spacing: -1px;
    color: #ddd;
}
.demo_line_05 span{
    letter-spacing: 0;
    color: #222;
    margin:0 20px;
}

優點:代碼簡潔 以上簡單介紹了分隔線的寫法,也許還有其它比較合適的寫法,看環境各取所需吧!

17.HTML畫分隔線

  1. 我們先是找到我們想要畫分割線的內容。

    HTML如何畫一條分割線

其實分割線也是很好理解,就是在兩段內容有一個分割。

HTML如何畫一條分割線

然後我們輸入關鍵Hr就可以了,注意這是一個標籤。

HTML如何畫一條分割線

然後我們觀看效果,我們可以看到內容被成功分割。

HTML如何畫一條分割線

有些同學會考慮使用Canvas元素,這個有點小題大做,非常不建議。

HTML如何畫一條分割線

最後,我們建議在Hr後面加上斜線,養成一個比較好的代碼規範。

HTML如何畫一條分割線

18.ElementUI日期選擇器時間選擇範圍限制

ElementUI是餓了麼推出的一套基於vue2.x的一個ui框架。官方文檔也很詳細,這裏做一個element-ui日期插件的補充。

官方文檔中使用picker-options屬性來限制可選擇的日期,這裏舉例子稍做補充。

單個輸入框的

組件代碼:

<el-date-picker
       v-model="value1"
       type="date"
       placeholder="選擇日期"
       :picker-options="pickerOptions0">
</el-date-picker>

情景1: 設置選擇今天以及今天之後的日期

data (){
   return {
       pickerOptions0: {
          disabledDate(time) {
            return time.getTime() < Date.now() - 8.64e7;
          }
        },  
   }     
}    

情景2: 設置選擇今天以及今天以前的日期

data (){
   return {
       pickerOptions0: {
          disabledDate(time) {
            return time.getTime() > Date.now() - 8.64e6
          }
        },  
   }     
}   

情景3: 設置選擇今天之後的日期(不能選擇當天時間)

data (){
   return {
       pickerOptions0: {
          disabledDate(time) {
            return time.getTime() < Date.now();
          }
        },  
   }     
}    

情景4: 設置選擇今天之前的日期(不能選擇當天)

data (){
   return {
       pickerOptions0: {
          disabledDate(time) {
            return time.getTime() > Date.now();
          }
        },  
   }     
}    

情景5: 設置選擇三個月之前到今天的日期

data (){
   return {
       pickerOptions0: {
          disabledDate(time) {
            let curDate = (new Date()).getTime();
            let three = 90 * 24 * 3600 * 1000;
            let threeMonths = curDate - three;
            return time.getTime() > Date.now() || time.getTime() < threeMonths;;
          }
        },  
   }     
} 

兩個輸入框

組件代碼

<el-date-picker
       v-model="value1"
       type="date"
       placeholder="開始日期"
       :picker-options="pickerOptions0">
</el-date-picker>
<el-date-picker
       v-model="value2"
       type="date"
       placeholder="結束日期"
       :picker-options="pickerOptions1">
</el-date-picker>

情景1: 限制結束日期不能大於開始日期

data(){
    return {
         pickerOptions0: {
                disabledDate: (time) => {
                    if (this.value2 != "") {
                        return time.getTime() > Date.now() || time.getTime() > this.value2;
                    } else {
                        return time.getTime() > Date.now();
                    }

                }
            },
            pickerOptions1: {
                disabledDate: (time) => {
                    return time.getTime() < this.value1 || time.getTime() > Date.now();
                }
            },
    }      
}       

針對選擇範圍(type=“daterange”)的日期篩選,類似於單個輸入框的情況,直接使用參數time進行判斷

19.vue如何循環渲染element-ui中table內容

對於大多數前端開發者來說,vuejs+element-ui是開發後臺管理系統過程中必不可少的技術框架。而後臺管理系統中,最常見的形式就是表格和表單,以便用來增刪改查。

element-ui中table的使用

——當el-table元素中注入data對象數組後,在el-table-column中用prop屬性來對應對象中的鍵名即可填入數據,用label屬性來定義表格的列名。可以使用width屬性來定義列寬。

相當於是要枚舉出所有需要展示的參數,這種情況在參數比較少的情況下是比較方便的,但是在有很多數據或者參數不確定的情況下,這種枚舉的方式就不太適合了。

 <template>
    <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </template>

循環渲染出element-ui中table表格內容

table表格分爲兩個部分,一部分值thead表頭,還有是tbody主體部分,所以可以分別循環出來,看代碼:

<el-table
    :data="rightsDate"     <-- 表格裏面的數據源 -->
      border
      stripe
      height="713">
      <el-table-column
          v-for="info in rightHeader" :key="info.key"     <!-- 設置表頭數據源,並循環渲染出來,property對應列內容的字段名,詳情見下面的數據源格式 -->
          :property="info.key"
          :label="info.label"
         >
             <template slot-scope="scope">
                   {{scope.row[scope.column.property]}}  <!-- 渲染對應表格裏面的內容 -->
              </template>
          </el-table-column>
          <el-table-column label="啓用狀態">
                <template slot-scope="scope">
                        <el-switch
                          v-model="scope.row.ifUse"
                          :active-color="ACT_COLOR"
                          :inactive-color="INACT_COLOR">
                        </el-switch>
                  </template>
             </el-table-column>
</el-table>
模擬數據源展示:rightHeader: [
        {
          label: '編碼',
          key: 'code'
        },
        {
          label: '姓名',
          key: 'name'
        },
        {
          label: '權限描述',
          key: 'description'
        }
      ],
rightsDate:[{
      "id":221,
      "code": "01",
      "name": "西藥開立權限",
      "description": "醫生對西藥處方權限",
      "ifUse":"0"
    }, {
      "id":222,
      "code": "02",
      "name": "草藥開立權限",
      "description": "醫生對草藥處方權限",
      "ifUse":"0"
    }, {
      "id":223,
      "code": "03",
      "name": "成藥開立權限",
      "description": "醫生對成藥處方權限",
      "ifUse":"0"
    }, {
      "id":224,
      "code": "04",
      "name": "麻醉開立權限",
      "description": "醫生對麻醉處方權限",
      "ifUse":"0"
    },
    {
      "id":225,
      "code": "05",
      "name": "精一開立權限",
      "description": "醫生對精一處方權限",
      "ifUse":"0"
    }
  ]

展示結果:

img

20.v-if與默認樣式間的小問題

在這裏插入圖片描述

    .el-form-item.el-form-item--small {
      margin-bottom: 10px;
    }

當你設置全局el-form-item樣式之後。

如果你不需要使用這塊el-form-item下面的東西時,應記得將其v-if = false.

僅僅只是將它所在的代碼塊內的代碼v-if 置爲 false的話,就會出現。一塊只有margin-bottom爲10px的空白塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章