一塊兒封裝vue ui組件,而後發到npm上!(2)

前言巴拉巴拉

此次呢就帶你們封裝一個tabbar。html

思考

咱們此次封裝的tabbar 須要有那些功能???vue

  1. 可以跳轉頁面(路由跳轉和超連接跳轉)
  2. icon 能夠自定義
  3. 切換事件(可能咱們在切換icon的時候,須要作一些操做!)
  4. 小點點(icon邊上的數字)

目的明確開幹!

我們開發的時候爲了方便其實能夠直接在App.vue裏寫代碼,而後在拷貝到對應的文件裏。(cv 沒法避免了😱)git

copy代碼並修改

先新建幾個文件,須要用到。 github

把color-ui小程序項目裏的操做條拷貝過來,並修改爲我們可使用的。

view ===> div
    text ===> p

    <div class="cu-bar foot tabbar bg-black">
      <div class="action text-orange">
        <p class="icon-homefill"></p> 首頁
      </div>
      <div class="action text-gray">
        <p class="icon-similar"></p> 分類
      </div>
      <div class="action text-gray">
        <p class="icon-recharge"></p>
        積分
      </div>
      <div class="action text-gray">
        <div class="icon-cart">
          <p class="cu-tag badge">99</p>
        </div>
        購物車
      </div>
      <div class="action text-gray">
        <div class="icon-my">
          <p class="cu-tag badge"></p>
        </div>
        個人
      </div>
    </div>
複製代碼

漂亮的一批批的,咱們已經完成了一丟丟。

切割代碼

這一步我要把 Tabbar 和 TabbarItem 分割開。小程序

  1. 先在packages/tabbar/src/main.js 寫入父容器代碼
export default {
    name: 'Tabbar',
    render(h) {
      return (
        <div class="cu-bar foot tabbar bg-black">{this.$slots.default}</div>
      );
    }
}
// 有同窗可能注意到了this.$slots.default
// 下文有講解,莫慌!
複製代碼
  1. 在packages/tabbar/index.js 註冊
import Tabbar from './src/main';
Tabbar.install = function(Vue) {
    Vue.component(Tabbar.name, Tabbar);
};
export default Tabbar;
複製代碼
  1. main.js 中use一下
import Tabbar from '../packages/tabbar';
Vue.use(Tabbar);
複製代碼
  1. App.vue 使用並預覽
<Tabbar></Tabbar>
複製代碼

emmmmmmmmm……好像有點翻車……球的麻袋……數組

我們繼續如法炮製 TabberItembash

Tips:
在tabbar-item/src/main.js 中咱們只須要放一個 TabbarItem.

export default {
    name: 'TabbarItem',
    render(h) {
      return (
        <div class="action text-gray">
            <div class="icon-my">
                <p class="cu-tag badge"></p>
            </div>
            個人
        </div>
      );
    }
}

爲啥?
由於每個TabbarItem 都是要傳入不一樣icon和文字的撒!
複製代碼

哎,成了?好像還有點問題……icon都是寫死的,文字也是寫死的,最重要的是切換效果呢?跳轉呢?????ide

一個個來莫着急老鐵!

效果實現
  1. 經過tabbar-item 實現icon 配置和標題
import Icon from '../../icon'; // 上一篇文章我們封裝icon
export default {
    name: 'TabbarItem',
    props: {
        icon: String
    },
    components: {
      Icon
    },
    render(h) {
      return (
        <div class="action text-gray">
            <Icon icon={icon}></Icon>  // 這裏呢直接調用……
            個人
        </div>
      );
    }
}
複製代碼
App.vue

<Tabbar>
  <TabbarItem icon="icon-homefill">首頁</TabbarItem>
  <TabbarItem icon="icon-similar">分類</TabbarItem>
  <TabbarItem icon="icon-cart">購物車</TabbarItem>
  <TabbarItem icon="icon-my">個人</TabbarItem>
</Tabbar>

複製代碼

能夠看到我們已經能夠自定義icon和標題文字了……

點擊切換效果

這裏我直接上代碼,慢慢給你們講解。ui

/packages/tabbar/src/main.js

export default {
  name: 'Tabbar',
  data() {
    return {
      items: []      // 這裏放一個數組用於存放 TabbarItem
    };
  },
  props: {
    value: Number,   // 確定會有人納悶這個是啥??? 下文解釋1
    fixed: Boolean,
    activeColor: String,  // 請看下文解釋2
    bgColor: {
      type: String,
      default: 'bg-black'
    }
  },
  methods: {
    setActiveItem() {    // 判斷 item.active 是否爲true
      this.items.forEach((item, index) => {
        item.active = index === this.value;
      });
    },
    onChange(active) {
      if (active !== this.value) {
        this.$emit('input', active);   // 通知App.vue 更改data值。
        this.$emit('change', active);  // 解釋3
      }
    }
  },
  watch: {
    items() {
      this.setActiveItem();
    },
    value() {
      this.setActiveItem();
    }
  },
  components: {
  },
  render(h) {
    const { fixed, bgColor, $slots } = this; 
    const classed = [
      {
        'foot': fixed,
      },
      bgColor,
      'cu-bar tabbar'
    ]
    return (
      <div class={classed}>
        {$slots.default}
      </div>
    );
  }
}
複製代碼
export default {
  name: 'TabbarItem',
  props: {
    icon: String
  },

  data() {
    return {
      active: false
    };
  },
  beforeCreate() {   // Tabbar組件 = this.$parent,是的之後你能夠經過this.$parent 直接獲取父組件. 
    this.$parent.items.push(this);
  },
  destroyed() {
    this.$parent.items.splice(this.$parent.items.indexOf(this), 1);
  },
  methods: {
    onClick(event) {    // Big Boss…… 不用過多解釋了吧……
      this.$parent.onChange(this.$parent.items.indexOf(this));
    }
  },
  render(h) {
    const { icon, $slots, active } = this;
    const avtive = active ? this.$parent.activeColor + ' action' : 'action text-gray';
    return (
      <div onClick={this.onClick} class={avtive}>
        <div class={icon}>
        </div>
        <span>{$slots.default}</span>
      </div>
    );
  }
}
複製代碼
App.vue

<Tabbar v-model="data" fixed :activeColor="'text-green'" :bgColor="'bg-black'">
  <TabbarItem icon="icon-homefill">首頁</TabbarItem>
  <TabbarItem icon="icon-similar">分類</TabbarItem>
  <TabbarItem icon="icon-cart">購物車</TabbarItem>
  <TabbarItem icon="icon-my">個人</TabbarItem>
</Tabbar>
複製代碼

  1. 有小夥伴必定會納悶! value 是啥?? 看完這個你必定懂了!

cn.vuejs.org/v2/guide/co…this

  1. 爲啥有個activeColor?

還記得我上一篇文章說過Tabbar 是一個父容器麼?

那麼咱們能夠把一些公用的屬性放到父容器上面……

在子組件須要使用的時候 能夠經過this.$parent 來獲取父容器上的屬性方法等等……

你也能夠設置一個 默認不選中的顏色喲!

之前我是以爲好高級……點擊切換了有個還能觸發一個切換事件……然而只是一個emit……

若是你想的話你也能夠在每一個TabbarItem 上面加……

路由切換

路由這個……就留到下一章把……畢竟有些人基礎不是那麼好。一會兒寫太多內容不太好!

下一章內容的話,封裝一個公用的路由方法 + Cell 的實現……

源碼的話……

github.com/martin-yin/…

相關文章
相關標籤/搜索