Element分析(組件篇)——Radio

_index.js

單選框內(nèi)部一共有三個組件:el-radio渺贤、el-radio-buttonel-radio-group,我們將一一進行講解。

import Radio from './src/radio';
import RadioButton from './src/radio-button.vue';
import RadioGroup from './src/radio-group.vue';

export default function(Vue) {
  Vue.component(Radio.name, Radio);
  Vue.component(RadioButton.name, RadioButton);
  Vue.component(RadioGroup.name, RadioGroup);
};

export { Radio, RadioButton, RadioGroup };

radio-group

radio-group的實現(xiàn)十分簡單缰趋,就是一個div.radio-group包裹著一個slot捧杉。

<template>
  <div class="el-radio-group">
    <slot></slot>
  </div>
</template>

script包含一系列改變樣式的prop陕见。

props: {
  size: String,  // Radio 按鈕組尺寸
  fill: {  // 按鈕激活時的填充色和邊框色
    type: String,
    default: '#20a0ff'
  },
  textColor: {  // 按鈕激活時的文本顏色
    type: String,
    default: '#fff'
  }
},

watch上監(jiān)聽了value,它會觸發(fā)change事件并且向父組件傳遞el.form.change事件味抖。

watch: {
  value(value) {
    this.$emit('change', value);
    this.dispatch('ElFormItem', 'el.form.change', [this.value]);
  }
}

其中dispatch是從emitter這一mixin中引入的评甜,我們將在mixin篇中進行講解,簡單的說仔涩,這是用來模擬vue1.0中向父組件傳播事件的$dispatch的忍坷。

mixins: [Emitter],

radio

radio組件其實也先相對簡單,它同樣引入了emitter這一mixin熔脂,我們將按照從外往里的順序進行分析佩研。

label

首先最外面是一個label標(biāo)簽作為包裹。

<label class="el-radio">
</label>

input

然后霞揉,是作為inputspan部分旬薯,它包含一個用來表示選中效果的span和一個不可以見的input用來模擬原生的radio

最外層el-radio__input

最外層是span.el-radio__input适秩,上面有一些動態(tài)class绊序,來調(diào)整樣式,我們也將一一進行講解秽荞。

<span class="el-radio__input"
  :class="{
    'is-disabled': disabled,
    'is-checked': model === label,
    'is-focus': focus
  }"
>
</span>

disabled

disabled是一個簡單的Boolean型的prop骤公,會影響是否可以選中。

props:{
  disabled: Boolean,
}

label

labelradio選中時的value扬跋,也是通過prop傳遞的阶捆。

props: {
  label: {},
}

model

model是一個計算屬性,也不是很復(fù)雜,就是用來實現(xiàn)v-model的洒试。

computed: {
  model: {
    get() {
      // 如果父組件是radio-group刊咳,返回父組件的value,否則返回自己的value
      return this.isGroup ? this._radioGroup.value : this.value;
    },

    set(val) {
      if (this.isGroup) {
        // 如果父組件是 radio-group儡司,派發(fā)input事件娱挨,讓父組件去 emit input 事件
        this.dispatch('ElRadioGroup', 'input', [val]);
      } else {
        // 否則自己 emit input 事件
        this.$emit('input', val);
      }
    }
  }
}

其中isGroup是另一個計算屬性,用來一直向上尋找捕犬,看看有沒有父組件乃至祖先組件是radio-group跷坝。

computed: {
  isGroup() {
    let parent = this.$parent;
    while (parent) {
      if (parent.$options.componentName !== 'ElRadioGroup') {
        parent = parent.$parent;
      } else {
        this._radioGroup = parent;
        return true;
      }
    }
    return false;
  },
}

focus

focus是一個data屬性,會在原生的input的獲得焦點和失去焦點時被改變碉碉。

el-radio__inner

el-radio__inner是用來實現(xiàn)選中效果的柴钻,通過css控制。

<span class="el-radio__inner"></span>

input

最后是一個input來模擬原生的radio垢粮,上面進行了一些簡單的處理贴届,并綁定了相應(yīng)的數(shù)據(jù)。

<input
  class="el-radio__original"
  :value="label"
  type="radio"
  v-model="model"
  @focus="focus = true"
  @blur="focus = false"
  :name="name"
  :disabled="disabled">

radio-button

radio-buttonradio基本上一樣蜡吧。

label

最外面仍然是一個label毫蚓。

<label
  class="el-radio-button"
  :class="[
    size ? 'el-radio-button--' + size : '',
    { 'is-active': value === label }
  ]"
>
</label>

size

size是一個計算屬性,它直接使用了沿著父組件向上尋找到的radio-group上設(shè)置的size昔善。

computed: {
  size() {
    return this._radioGroup.size;
  }
}

_radioGroup也是一個計算屬性元潘,它將一直向上尋找radio-group

computed: {
  _radioGroup() {
    let parent = this.$parent;
    while (parent) {
      if (parent.$options.componentName !== 'ElRadioGroup') {
        parent = parent.$parent;
      } else {
        return parent;
      }
    }
    return false;
  },
}

label

label是一個prop,用來表示選中該按鈕時的value值君仆。

props: {
  label: {},
}

value

value是用來實現(xiàn)v-model的翩概,來獲取選擇的按鈕,從其代碼可以看出來返咱,radio-buttonradio不同钥庇,它不能脫離radio-group單獨使用:

computed: {
  value: {
    get() {
      return this._radioGroup.value;
    },
    set(value) {
      this._radioGroup.$emit('input', value);
    }
  },
}

input

然后是用來模擬原生radioinput,上面綁定了相應(yīng)的數(shù)據(jù):

<input
  class="el-radio-button__orig-radio"
  :value="label"
  type="radio"
  v-model="value"
  :name="name"
  :disabled="disabled">

el_radio-button__inner

最后是真正會顯示的按鈕span即其樣式咖摹,它內(nèi)部的值可以通過匿名的默認(rèn)slot或者label進行設(shè)置评姨,前者具有更高的優(yōu)先級:

<span class="el-radio-button__inner" :style="value === label ? activeStyle : null">
  <slot></slot>
  <template v-if="!$slots.default">{{label}}</template>
</span>

可以看出上面還綁定了一個動態(tài)的style,它通過判斷value === label決定當(dāng)前按鈕是否被選中楞艾,然后應(yīng)用activeStyle参咙,而這個activeStyle也是一個計算屬性,簡單的說它會根據(jù)父級radio-group的屬性來設(shè)置樣式:

computed: {
  activeStyle() {
    return {
      backgroundColor: this._radioGroup.fill,
      borderColor: this._radioGroup.fill,
      color: this._radioGroup.textColor
    };
  },
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末硫眯,一起剝皮案震驚了整個濱河市蕴侧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌两入,老刑警劉巖净宵,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡择葡,警方通過查閱死者的電腦和手機紧武,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敏储,“玉大人阻星,你說我怎么就攤上這事∫烟恚” “怎么了妥箕?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長更舞。 經(jīng)常有香客問我畦幢,道長,這世上最難降的妖魔是什么缆蝉? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任宇葱,我火速辦了婚禮,結(jié)果婚禮上刊头,老公的妹妹穿的比我還像新娘黍瞧。我一直安慰自己,他們只是感情好芽偏,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布雷逆。 她就那樣靜靜地躺著,像睡著了一般污尉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上往产,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天被碗,我揣著相機與錄音,去河邊找鬼仿村。 笑死锐朴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蔼囊。 我是一名探鬼主播焚志,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼畏鼓!你這毒婦竟也來了酱酬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤云矫,失蹤者是張志新(化名)和其女友劉穎膳沽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡挑社,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年陨界,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痛阻。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡菌瘪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阱当,到底是詐尸還是另有隱情麻车,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布斗这,位于F島的核電站动猬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏表箭。R本人自食惡果不足惜赁咙,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望免钻。 院中可真熱鬧彼水,春花似錦、人聲如沸极舔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拆魏。三九已至盯桦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渤刃,已是汗流浹背拥峦。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卖子,地道東北人略号。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像洋闽,于是被迫代替她去往敵國和親玄柠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容