一块儿封装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/…

相关文章
相关标签/搜索