前言
剛剛接手了一個公司內部的後臺系統專案,剛開始的時候真的是一步一個坑,經過一週的加班,基本把常用的功能和元件都完成了,基本緩了一口氣。
技術棧: ivew + vue + vue-cli
廢話不多說,下面總結一下封裝元件的一些問題 大致頁面如下
元件的封裝
- 實現 input select radio checkbox date 的元件的封裝
1.因為vue需要資料驅動檢視,需要把所有屬性在頁面中初始化
export default {
data() {
return {
list: [ {name: 'applicationNo', title: '採購申請編號 :', type: 'input', placeholder: '', disable: true, value: '111'
}, {name: 'createUserName', title: '申請人 :', type: 'input', value: '', disable: true
}, {name: 'organLeaderName', title: '機構負責人', type: 'input', value: '', disable: true
}, {name: 'expectTime', title: '希望到貨時間', type: 'input', value: '', data: [], placeholder: '', disable: true
}, {name: 'transportOrganName', title: '配送機構', type: 'input', value: '', placeholder: '', disable: true
}, {name: 'receive', title: '接車地址', type: 'input', value: '', disable: true
}, {name: 'detailAddress', title: '詳細地址', type: 'input', value: '', data: [], col: '12', disable: true
}, {name: 'contract', title: '聯絡人', type: 'input', value: '', data: [], disable: true
}, {name: 'telphone', title: '聯絡電話', type: 'input', value: '', data: [], disable: true
}, {name: 'remark', title: '備註', type: 'input', value: '', data: [], disable: true, col: '20'
} ],複製程式碼
1.1 封裝元件,實現提交按鈕的判斷,因為初始化定義了type
根據type
來判斷是什麼提交按鈕(如:input,select…)
<
template>
<
div class="form-input-group">
<
template v-if="type == 'text'">
<
span class="form-list-text">
{{
value
}
}<
/span>
<
/template>
<
template v-else-if="type == 'input'">
<
Input class="input-item" v-model="inputValue" :placeholder="placeholder" :disabled="disable">
<
/Input>
<
template v-if="detail">
<
span class="input-detail">
{{detail
}
}<
/span>
<
/template>
<
/template>
<
template v-else-if="type == 'select'">
<
Select class="input-item" v-model="inputValue" :placeholder="placeholder" :disabled="disable">
<
Option v-for="item in selectData" :value="item" :key="item.value">
{{item
}
}<
/Option>
<
/Select>
<
/template>
<
template v-else-if="type == 'date'">
<
DatePicker type="date" :placeholder="placeholder" @on-change="setDate" :disabled="disable">
<
/DatePicker>
<
/template>
<
template v-else-if="type == 'city'">
<
city-select :value="value" @setCity="SetCity">
<
/city-select>
<
/template>
<
template v-else-if="type == 'model'">
<
Input class="input-model-hidden" v-model="modelValue.code">
<
/Input>
<
Input class="input-item input-model" :placeholder="modelValue.name" readonly>
<
/Input>
<
div class="input-shadow" @click="showModel = true">
<
/div>
<
/template>
<
template v-else-if="type == 'cars'">
<
car-select :value="value" @setCar="SetCar">
<
/car-select>
<
/template>
<
FormModel v-if="showModel" @closeModel="closeModel" @confirmModel="confirmModel">
<
/FormModel>
<
/div>
<
/template>
/** * [inputGroup 輸入框] * 接受引數:[type: 輸入框型別,name:要繫結的屬性名, data: 下拉選單或級聯選單資料] * type值:[text:普通文字,input:普通輸入框,select:下拉框,date:日期選擇框,city:省市區,cascader:級聯選單] * 接受方法:[getValue:獲取屬性名和返回值] * 返回值:{
name: name, value: value
} * 級聯選單返回值:{
name: name, value: [value1, value2]
} * 使用示例: <
input-group v-bind="propsData">
<
/input-group>
*/複製程式碼
父元件中我們不能只傳遞
type
值去判斷提交按鈕型別,當檢視訂單並不能修改的時候還需要把value
值傳遞給子元件顯示,並且設定disabled
屬性不可編輯。還需要傳遞其它屬性(eg:placeholder
,disable
,name
)等
1.2 從而在父元件和子元件需要做兩件事
<
Row class="form-list-search">
<
Col :span="item.col ? item.col : '6'" v-for="(item,index) in list" :key="index">
<
span class="form-list-title">
{{item.title
}
}<
/span>
<
input-group v-bind="item" @setCarCode="setCarCode" @setValue="setValue">
<
/input-group>
<
/Col>
<
/Row>
複製程式碼
使用 v-bind="item"
傳遞屬性值。那麼在input元件下如何接收?看程式碼
// input.vue export default {
data() {
return {
inputValue: '', selectData: [], modelValue: {
}, showModel: false, dateData: ''
}
}, props: {
data: {
default: ''
}, value: {
default: ''
}, type: {
required: true
}, name: {
required: true
}, disable: {
type: Boolean
}, detail: {
default: ''
}, placeholder: String, index: Number
}, components: {
CitySelect, FormModel, CarSelect
}複製程式碼
1.3 當子元件的發生改變時,我們需要監聽元件中value
的變化並把值傳遞給父元件,從而改變檢視。$emit()
created() {
this.inputValue = this.value this.selectData = this.data this.inputkey = this.key
}, methods: {
setDate(date) {
this.inputValue = date // this.dateData = date // let returnData = {name: this.name, value: this.dateData
} // this.$emit('dateData', returnData)
}, SetCity(val) {
let returnData = {name: this.name, value: val
} this.$emit('setCityCode', returnData)
}, SetCar(val) {
console.log(val, 'input.vue') this.$emit('setCarCode', val)
}, confirmModel(data) {
if (data) {
this.showModel = false this.modelValue = data
}
}, closeModel(data) {
if (data) {
this.showModel = false
}
}
}, watch: {
value(val) {
this.inputValue = val
}, data(val) {
this.selectData = val
}, inputValue(val) {
// console.log(val) let returnData = {name: this.name, value: val
} if (this.index != undefined) {
returnData.index = this.index
} if (this.type == 'date') {
returnData.value = Util.unixTime(val)
} this.$emit('setValue', returnData)
}
}
}複製程式碼
1.4 三級聯動元件
大致思路
- 結合iview元件Cascader 級聯選擇,動態載入,如果有下一級選單,在物件內部定義
children[]
,並且push新的二級物件結構,loading: false
說明還有下一級,還會呼叫loadData
方法
<
template>
<
div>
<
Cascader :data="cascaderData" :load-data="loadData" v-model="cascader" @on-change="setValue">
<
/Cascader>
<
/div>
<
/template>
<
script>
import Util from '../../libs/util.js' import {getBrand, getSeriesList, getModelList
} from '../../api/index' export default {
data() {
return {
cascaderData: [], cascader: []
}
}, async mounted() {
// 返回一級選單資料 let brandList = await getBrand() // 渲染檢視 Util.CommonCascader(this, brandList.result, this.cascaderData)
}, created() {
}, methods: {
loadData(item, callback) {
item.loading = true // 呼叫二級選單介面,傳入id getSeriesList(item.value).then((res) =>
{
Util.CascaderChild(this, res.result, item.children, 'name', 'code') callback() item.loading = false
}).then(() =>
{
// 呼叫三級選單介面,傳入id getModelList(item.value).then((res) =>
{
Util.CascaderChild(this, res.result, item.children, 'name', 'code', true) callback() item.loading = false
})
})
}, setValue(val) {
this.$emit('setCar', val)
}
}, watch: {
value(val) {
this.cascader = val
}
}, components: {
}
}<
/script>
<
style scoped>
<
/style>
複製程式碼