首頁 > 軟體

vue中mixins的工具的封裝方式

2022-05-24 14:00:47

mixins工具的封裝

vue的mixins的工具是什麼?

就是我們再寫資訊管理系統時,涉及到大量的增刪查改呼叫後臺介面的重複的方法,我們可以把這些方法集合起來直接作為一個js檔案,後面可以直接引入,資料和方法都不需要宣告,直接使用即可。

再概括一下,就是請求後臺介面的方法的集合。

js工具程式碼

具體註釋我會直接寫在程式碼裡,然後大家可以自己直接對照著程式碼看

程式碼如下:

//這裡引入了qs,使用npm install qs就可進行安裝,在後面下載的方法裡用到(get方法拼接引數),
//如果沒有這個需求,可以不引入(同時注意刪除下方的下載方法)
import qs from 'qs'
export default {
  data() {
    return {
    //這個mixinViewModuleOptions需要在使用這個工具的時候在vue檔案的data中宣告
      mixinViewModuleOptions: {
        mockData: null,
        getDataListURL: '', // 資料列表介面 API地址
        activatedIsNeed: true, // 此頁面是否在啟用(進入)的時候,呼叫查詢資料列表介面
        queryDataURL: '', // table查詢介面
        deleteURL: '', // 刪除介面
        downLoadURL: '', // 下載介面
        deleteIsBatch: false, // 是否批次刪除
        deleteIsBatchKey: 'id', // 刪除介面,批次狀態下有那個key進行標記操作,比如 pid,uid
        // getDataListIsPage: true // 不同的資料介面,返回的資料介面不相同,用次變數來區別
      },
      dataForm: {}, // 查詢條件
      dataList: [], // 資料列表
      page: 1, // 當前頁碼
      rows: 10, // 每頁數
      total: 0, // 總條數
      dataListLoading: false, // 資料列表,loading狀態
      dataListSelections: [], // 資料列表,多選項
      addOrUpdateVisible: false, // 新增/更新,彈窗visible狀態
    }
  },
  created() {
    if (this.mixinViewModuleOptions.activatedIsNeed) {
     //獲取資料的方法
      this.getDataList()
    }
  },
  methods: {
    // 下載excel
    downLoadHandle(id) {
      if (!this.dataList.length) {
        return this.$message.warning('沒有可匯出的資料')
      }
      if (!id) {
        return this.$message.warning('id欄位無效錯誤')
      }
      const ids = this.dataListSelections.map(a => a[id]).join(',')
      //最開始引入的qs在這裡用到,作用:將dataForm這個物件用‘&'拼接成字串,再拼到下載連結後
      const dataForm = qs.stringify(Object.assign({}, this.dataForm, { ids }))
   
      const url = `${window.SITE_CONFIG.BASE_URL.serverIP}${this.mixinViewModuleOptions.downLoadURL}?${dataForm}`
      window.open(url)
    },
     // 刪除
    deleteHandle(id) {
      if (!id && this.mixinViewModuleOptions.deleteIsBatch
      && this.dataListSelections.length <= 0) {
        return this.$message({
          message: '請選擇刪除項',
          type: 'warning',
          duration: 800,
        })
      }
      this.$confirm('您確定刪除此條內容麼', '提示', {
        confirmButtonText: '確定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        let ids = ''
        if (this.dataListSelections.length) {
          ids = this.dataListSelections.map(item =>
          `${item[this.mixinViewModuleOptions.deleteIsBatchKey]}`).join(',')
        } else {
          ids = id
        }
        this.$http.get(`/${this.mixinViewModuleOptions.deleteURL}`, {
          params: {
            id: ids,
          },
        }).then(({ data }) => {
          if (data.code !== 1) {
            return this.$message.error(data.msg)
          }
          this.$message({
            type: 'success',
            message: '刪除成功!',
            duration: 800,
            onClose: () => {
              this.getDataList()
            },
          })
        })
      }).catch(() => {
      })
    },
    // 新增 / 修改
    addOrUpdateHandle(id) {
      this.addOrUpdateVisible = true
      this.$nextTick(() => {
        this.$refs.addOrUpdate.dataForm.id = id
        this.$refs.addOrUpdate.init()
      })
    },
    dataListSelectionChangeHandle(val) {
      this.dataListSelections = val
    },
    // 查詢
    queryHandle() {
      this.page = 1
      this.getDataList()
    },
    // 獲取table資料
    getDataList() {
      this.dataList = []
      this.dataListLoading = true
      return this.$http.get(`/${this.mixinViewModuleOptions.getDataListURL}`, {
        params: {
          page: this.page,
          rows: this.rows,
          ...this.dataForm,
        },
      }).then(({ data }) => {
        this.dataListLoading = false
        if (data.code !== 1) {
          this.dataList = []
          this.total = 0
          return this.$message.error(data.msg)
        }
        this.dataList = data.data ? data.data : []
        this.total = data.total ? data.total : 0
        return data.data
      }).catch(() => {
        this.dataListLoading = false
      })
    },
    // 分頁, 每頁條數
    pageSizeChangeHandle(val) {
      this.page = 1
      this.rows = val
      if (this.dataForm.pageSize) {
        this.dataForm.pageNum = 1
        this.dataForm.pageSize = val
      }
      this.getDataList()
    },
    // 分頁, 當前頁
    pageCurrentChangeHandle(val) {
      this.page = val
      if (this.dataForm.pageNum) {
        this.dataForm.pageNum = val
      }
      this.getDataList()
    },
  },
}

三、使用這個檔案

1.引入

//js檔名稱是view-module.js,引入過來之後命名 mixinViewModule(後面需要用到,注意一致)
import mixinViewModule from "@/mixins/view-module";

2.宣告

直接只貼宣告的程式碼讓人看不明代位置,宣告的位置又不好描述,我這裡直接貼圖:

3.使用檔案的html程式碼

<template>
  <section class="main-container-box">
      <el-form ref="form" :model="dataForm" inline>
        <el-form-item label="商品名稱:">
          <el-input placeholder="請輸入物資名稱" v-model="dataForm.goodsName" clearable></el-input>
        </el-form-item>
        <el-form-item>
           //這裡的getDataList方法不需要再methods中宣告,會直接執行view-module.js中的getDataList方法,引數為上面宣告的dataForm
           <el-button type="plain" @click="getDataList">查詢</el-button>
        </el-form-item>
      </el-form>
      //這裡的dataList和view-module.js檔案中的資料列表dataList名稱要一致,並且可以不用在data中宣告
      <el-table-self
            :data="dataList"
            style="width:100%"
            :height="'calc(100vh - 1.3rem)'"
            >
            <el-table-column  label="序號"  type="index" align="center" header-align="center" width="60"></el-table-column>   
            //這裡就是自己表格中的資料,我只是遍歷寫出來的,大家可以不用管----↓
            <el-table-column  
                  v-for="(item,index) in columnList"
                  :key="index"
                  show-overflow-tooltip
                  :align="item.align" 
                  :fixed="item.fixed"
                  :prop="item.prop" 
                  :label="item.label"
            ></el-table-column>
            //---------------------------------------------------------------↑
      </el-table-self>
	//這是分頁元件,注意裡面的引數:page,rows,total和方法pageSizeChangeHandle,pageCurrentChangeHandle名稱都要和view-module中一致
      <el-pagination
        :current-page="page"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="rows"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="pageSizeChangeHandle"
        @current-change="pageCurrentChangeHandle"
      ></el-pagination>
  </section>
</template>

總結:在管理資訊系統中,基本的表格的增刪查改功能有很多,每個都寫一個方法對接介面會很麻煩,有了這個js工具了之後,每個檔案只需要把它引入,然後傳入對應的引數就可以了(mixinViewModuleOptions),只需要注意各個引數和方法名稱都要對應起來,不要寫錯了,就可以節省很多時間和程式碼啦!

vue元件封裝及注意事項

props : {
        beanProps : {
            type : Object
        },
        // 多種型別
        propB: [String, Number],
        // 必傳且是字串
        propC: {
          type: String,
          required: true
        },
        // 數位,有預設值
        propD: {
          type: Number,
          default: 100
        },
        // 陣列/物件的預設值應當由一個工廠函數返回
        propE: {
          type: Object,
          default: function () {
            return { message: 'hello' }
          }
        },
        // 自定義驗證函數
        propF: {
          validator: function (value) {
           return value > 10
          }
        }
    },

我們在 props 中接收資料,注意props物件裡面 鍵值 是對改資料的 資料型別 的規定。做了規範,使用者就只能傳輸指定型別(type型別)的資料,否則報警告

而props物件中的資料,我們可以直接在當前元件中使用  this.beanProps ,可以直接使用。這裡要強調一下,props傳過來的資料只做展示,不得修改,想修改,再新寫一個data中的變數承接做資料的再處理。

呼叫的時候

<!--要呼叫的頁面元件的頁面需要import匯入元件頁面,然後再起別名-->
import treeSelectPeople from "../../../components/tree-select-people.vue";
 
<!--匯入之後要新增元件到component物件裡-->
 components: { treeSelectPeople },
 
<!--然後呼叫的時候標籤名,就是你匯入元件起的變數名了-->
<treeSelectPeople :beanProps="newBean.props"></treeSelectPeople>

我們已經會使用 父元件向子元件傳資料了,那子元件如何來修改父元件的資料呢?

這裡提供 2 種實現方法,但是 第一種不推薦,強烈不推薦

方式一:  

selectValue: {
          data: '1'
        },
 //程式碼段
 this.selectValue.data = '我被修改了'

即,父元件將 物件 資料傳遞給子元件,子元件直接修改props過來的物件的值

可以實現,感覺是一個比較快捷的方式。但是不推薦,這種方式寫多了,容易出錯,特別是多層元件巢狀的時候。這種修改對程式碼的迭代和錯誤的捕捉都不友好,所以建議大家別這樣寫。

他的實現原理簡單提一下: 這個物件、陣列啦,是參照資料型別,說白了,就是儲存單元的資訊是指標,真正資料在別的地方,通過指標查詢的資料,所以這樣寫,對瀏覽器來說僅僅是傳遞了一個指標,資料還是同一份資料。所以你能修改。

方式二:

正兒八經的通過 $emit 方法去掉父元件的方法,在父元件中修改data的資料。(根正苗紅的方法,規範寫法)(就是在子元件新建一個新的變數來獲取父元件傳過來的值) 

<template>
    <section class="f-mainPage">
        <!--selectFunc 選擇完成的回撥      searchList 下拉選單的資料-->
        <search @selectFunc="selectFunc" :searchList="searchList" :selectValue="selectValue"></search>
    </section>
</template>
<script type="text/ecmascript-6">
  import Search from '../vuePlugin/search'
  export default {
    data() {
      return {
        searchList: ['草船借箭', '大富翁', '測試資料'],
        // 直接通過props傳遞物件 修改,挺便捷的,但是不規範
        selectValue: {
          data: '1'
        },
        // 通過emit修改,規範寫法
        selectValue2: ''
      }
    },
    mounted() {},
    methods: {
      pageGo(path) {
        this.$router.push('/' + path)
      },
      selectFunc(value) {
        this.selectValue2 = value
        console.log(this.selectValue)
        console.log(this.selectValue2)
      }
    },
    components: {
      Search
    }
  }
</script>

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com