I used to choose Mint-UI or Vux framework for mobile terminal projects. I have to say that these two UI frameworks are very good and easy to use, which can save a lot of time for development work.

Tabbar can be used in mint-UI as follows:

<mt-tabbar v-model="selected">
  <mt-tab-item id="Order">
    <img slot="icon" src="http://placehold.it/100x100">
    <span slot="label"< span> </mt-tab-item> </mt-tabbar>Copy the code

After using it, you want to… Why is it necessary to specify an ID for each MT-tab-item? In the case of tabbar, I don’t care about the id of the object I press, I care about which tabbar-item I press. Which leads to the question:

  1. So how do you tell which child component is pressed in the parent component?

You can tell which child component it is by judging the _UID of children

  1. How does a child component throw its _UID to its parent?

Calling $parent.$emit(‘input’, _uid) directly modifs the V-model binding value.

V-bind :value=”selected” V-on :input=”selected = $event.target.value

Armed with these steps of analysis, I wrote a simple Tabbar component of my own

tabbar.vue

<template>
  <div class="l-tabbar">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'LTabbar',
  component: 'LTabbar',
  props: {
    value: {}
  },
  methods: {
    index (id) {
      for (let i = 0; i < this.$children.length; ++i) {
        if (this.$children[i]._uid === id) {
          return i
        }
      }
      return -1
    }
  }
}
</script>

<style lang="scss">
.l-tabbar {
  position: absolute;
  width: 100%;
  height: auto;
  bottom: 0;
  left: 0;
  right: 0;
  background: white;
  display: flex;
  justify-content: space-around;
}
</style>
Copy the code

tabbarItem.vue

<template>
  <div class="tabbar-item"
    @click="$parent.$emit('input', id)"
    :class="{ 'is-selected': $parent.value === id }">
    <div class="item-icon">
      <slot name="icon"></slot>
    </div>
    <div class="item-text">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'LTabbarItem',
  component: 'LTabbarItem'.data () {
    return {
      id: this.$parent.index(this._uid)
    }
  }
}
</script>

<style lang="scss">
@import '.. /.. /common/style/var.scss';

.tabbar-item {
  text-align: center;
  margin: 5px auto;
  width: 100%;
  &.is-selected {
    color: $default-color;
  }
  .item-text {
    font-size: 12px;
  }
}
</style>
Copy the code

Once written, it will be simpler to use than mint-UI components, and you can unbind id dependencies:

<l-tabbar v-model="selected">
  <l-tabbar-item v-for="(item, index) in tabItems" :key="index">
    <svg slot="icon" :class="icon" aria-hidden="true">
      <use :xlink:href="` #${item.icon}`"></use>
    </svg>
    <span>{{ item.title }}</span>
  </l-tabbar-item>
</l-tabbar>
Copy the code

Although by this point the transformation is complete, but there are always some problems. Is it appropriate to call the parent’s methods in the child? But then you think tabbar-Item is just for Tabbar, so you don’t need to worry too much about coupling, reusability, etc. If the thinking is not in place, please give some guidance to the gods.

Improved again (12/03)

Parent: delete methods index child:data () {
  return {
    id: this.$parent.$children.length - 1
  }
}
Copy the code

After careful analysis, I found that every time I insert an item, it is only necessary to get its position in $parent.$children. Since it is inserted into the $children array by way of push, I only need to get the last item, which is its index

Github: github.com/lyh2668 AuthBy: lyh2668