国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue省市區三聯動下拉選擇組件的實現

2019-11-19 16:42:33
字體:
來源:轉載
供稿:網友

我們曾經經常會遇到需要選擇省市區的需求,我們可能是找一個插件來實現,但是有了vue之后,我們自己完全可以簡單的實現這個效果,并封裝為獨立的.vue組件,便于日后使用

我們今天來實現一個 利用vuejs開發的 省市區三聯動的組件  CitySelect.vue組件

首先來看一下最終的效果(沒有寫太多的樣式...)

組件所需要的省市區的JSON數據(已經封裝為commonjs模塊了):    provinces.js

這個數據中有這樣幾個字段:

code: 當前省市區的編碼

sheng: 當前所在的省

name: 省市區的名字

level: 級別,省 level = 1, 市 level=2, 區/縣城 level = 3

di: 縣,市級別的區分

如何使用?

這里采用了 v-model暴露接口, 所以我們下拉選擇的值,你只需要在 v-model綁定的屬性中去拿即可

我們使用的字段是  cityInfo用于接收組件的數據, 組件為了返回足夠的數據, 它是一個對象

使用代碼示例  : 

App.vue

<template> <div id="app"> <h5>vue 省市區三聯動 demo</h5> <city-select v-model="cityInfo"></city-select> <h6>v-model的值是 <code>{{ cityInfo }}</code></h6> <h6>從v-model得知,你選擇了 <i>{{ cityName }}</i></h6> </div></template><script> import CitySelect from './components/CitySelect.vue' export default { data() { return { cityInfo: '', } }, components: { CitySelect }, computed: { cityName() { const names = []; this.cityInfo.province && names.push(this.cityInfo.province.name + ' ') this.cityInfo.city && names.push(this.cityInfo.city.name + ' ') this.cityInfo.block && names.push(this.cityInfo.block.name + ' ') return names.join('') } } }</script><style lang="stylus"> h6 padding 10px border 1px dotted h6 i color #f00 border 1px dotted #ccc</style>

cityName是我們需要展示的數據,作為一個計算屬性而存在,因為這個值是不斷變化的,從cityInfo中抽取出來的數據

下面我們來看一下組件的實現代碼

CitySelect.vue

<template> <div class="city-select"> <select v-model="selectedProvince" name="province"> <option v-for="(item, index) in provinces" v-if="item.level === 1" :value="item"> {{ item.name }} </option> </select> <select v-model="selectedCity" name="city"> <option v-for="(item, index) in cities" :value="item"> {{ item.name }} </option> </select> <select v-model="selectedBlock" name="block"> <option v-for="(item, index) in blocks" :value="item"> {{ item.name }} </option> </select> </div></template><script>/** * 省 市 區/縣城 三聯動選擇器*/import provinces from './provinces.js'import Vue from 'vue'export default { name: 'app', created() { // 數據初始化,默認選中北京市,默認選中第一個;北京市數據為總數據的前18個 let beijing = this.provinces.slice(0, 19) this.cities = beijing.filter(item => { if (item.level === 2) { return true } }) this.selectedCity = this.cities[0] this.blocks = beijing.filter(item => { if (item.level === 3) { return true } }) this.selectedBlock = this.blocks[0] }, watch: { selectedProvince(newVal, oldVal) { // 港澳臺數據只有一級,特殊處理 if (newVal.sheng === '71' || newVal.sheng === '81' || newVal.sheng === '82') { this.cities = [newVal] this.blocks = [newVal] } else { this.cities = this.provinces.filter(item => {  if (item.level === 2 && item.sheng && newVal.sheng === item.sheng) {  return true  } }) } var _this = this // 此時在渲染DOM,渲染結束之后再選中第一個 Vue.nextTick(() => { _this.selectedCity = _this.cities[0] _this.$emit('input', _this.info) }) }, selectedBlock() { var _this = this Vue.nextTick(() => { _this.$emit('input', _this.info) }) }, selectedCity(newVal) { // 選擇了一個市,要選擇區了 di是城市的代表,sheng if (newVal.sheng === '71' || newVal.sheng === '81' || newVal.sheng === '82') { this.blocks = [newVal] this.cities = [newVal] } else { this.blocks = this.provinces.filter(item => {  if (item.level === 3 && item.sheng && item.sheng == newVal.sheng && item.di === newVal.di && item.name !== '市轄區') {  return true  } }) } var _this = this Vue.nextTick(() => { _this.selectedBlock = _this.blocks[0] // 觸發與 v-model相關的 input事件 _this.$emit('input', _this.info) }) } }, computed: { info() { return { province: this.selectedProvince, city: this.selectedCity, block: this.selectedBlock } } }, data() { return { selectedProvince: provinces[0], selectedCity: 0, selectedBlock: 0, cities: 0, provinces, blocks: 0 } }}</script><style lang="stylus" scoped> .city-select select outline 0</style>

組件關鍵點說明:

HTML模板采用三個 select下拉控件,分別具有v-model由于綁定選擇的數據,使用v-for遍歷省市區數據

data中的數據,分別是選中的省市區的值(對象形式); 以及當前這個省的城市,這個城市的區,見名知意

在create鉤子函數中我們進行了數據的初始化,默認我們顯示北京相關的信息,改變v-model對應的屬性值

實現三聯動的重點:

我們使用watch監測當前省市區的改變(v-model中綁定的數據),一旦省 有變化,就需要拉取這個省相關的數據,并且默認選中第一條數據;  市,區的變化類似。

在這里我們采用了 ES5中的filter來進行數據的過濾,我們只要把數據過濾出來了,vue自動幫我們重新渲染,所以我們只需要把重點放在數據的篩選上就可以了

v-model接口的暴露:

要將數據綁定到v-model所綁定的屬性上,需要通過觸發 input事件,參見 v-model的實現原理這篇文章

Vue.nextTick(() => { _this.$emit('input', _this.info) })

也就是這行代碼實現了組件內部數據暴露的效果: v-model所綁定的cityInfo拿到了組件內部的值

這里的 nextTick類似于setTimeout實現的效果,可以在執行完其他任務(例如渲染DOM)之后再執行相應的回調,我們使用它,可以保證我們的下一步操作是在DOM渲染完畢之后再執行的,保證邏輯的正確性

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 美姑县| 壤塘县| 青阳县| 江西省| 巴青县| 临城县| 义乌市| 木里| 德格县| 元阳县| 军事| 兰坪| 宜兰市| 区。| 宜君县| 昌江| 剑阁县| 平阴县| 灵石县| 崇信县| 米易县| 黄梅县| 鄂尔多斯市| 安达市| 凉城县| 渝中区| 保靖县| 积石山| 正镶白旗| 南漳县| 芒康县| 南木林县| 绥芬河市| 福州市| 滦平县| 安平县| 东阳市| 泰安市| 团风县| 乌兰察布市| 石首市|