一起封装vue ui组件,然后发到npm上!(2)

前言巴拉巴拉

这次呢就带大家封装一个tabbar。

思考

我们这次封装的tabbar 需要有那些功能???

  1. 能够跳转页面(路由跳转和超链接跳转)
  2. icon 可以自定义
  3. 切换事件(可能我们在切换icon的时候,需要做一些操作!)
  4. 小点点(icon边上的数字)

目的明确开干!

咱们开发的时候为了方便其实可以直接在App.vue里写代码,然后在拷贝到对应的文件里。(cv 无法避免了?)

copy代码并修改

先新建几个文件,需要用到。

把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……好像有点翻车……球的麻袋……

咱们继续如法炮制 TabberItem

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都是写死的,文字也是写死的,最重要的是切换效果呢?跳转呢?????

一个个来莫着急老铁!

效果实现
  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和标题文字了……

点击切换效果

这里我直接上代码,慢慢给大家讲解。

/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…

  1. 为啥有个activeColor?

还记得我上一篇文章说过Tabbar 是一个父容器么?

那么我们可以把一些公用的属性放到父容器上面……

在子组件需要使用的时候 可以通过this.$parent 来获取父容器上的属性方法等等……

你也可以设置一个 默认不选中的颜色哟!

以前我是觉得好高级……点击切换了有个还能触发一个切换事件……然而只是一个emit……

如果你想的话你也可以在每个TabbarItem 上面加……

路由切换

路由这个……就留到下一章把……毕竟有些人基础不是那么好。一下子写太多内容不太好!

下一章内容的话,封装一个公用的路由方法 + Cell 的实现……

源码的话……

github.com/martin-yin/…

转载于:https://juejin.im/post/5cc808d9e51d456e6479b505

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue2 封装 Element UI Tree 组件的步骤如下: 1. 安装 Element UI ```bash npm install element-ui --save ``` 2. 在 main.js 中引入 Element UI ```js import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI) ``` 3. 创建 Tree.vue 组件 ```vue <template> <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"> </el-tree> </template> <script> export default { name: 'Tree', props: { data: { type: Array, default: () => [] }, defaultProps: { type: Object, default: () => ({ children: 'children', label: 'label' }) } }, methods: { handleNodeClick(node) { this.$emit('node-click', node) } } } </script> ``` 4. 在需要使用 Tree 的组件中引入 Tree 组件 ```js import Tree from './Tree.vue' export default { name: 'MyComponent', components: { Tree }, data() { return { treeData: [ { label: '一级 1', children: [ { label: '二级 1-1', children: [ { label: '三级 1-1-1' }, { label: '三级 1-1-2' } ] }, { label: '二级 1-2', children: [ { label: '三级 1-2-1' }, { label: '三级 1-2-2' } ] } ] }, { label: '一级 2', children: [ { label: '二级 2-1', children: [ { label: '三级 2-1-1' }, { label: '三级 2-1-2' } ] }, { label: '二级 2-2', children: [ { label: '三级 2-2-1' }, { label: '三级 2-2-2' } ] } ] } ], defaultProps: { children: 'children', label: 'label' } } }, methods: { handleNodeClick(node) { console.log(node) } } } ``` 5. 在组件模板中使用 Tree 组件 ```vue <template> <div> <tree :data="treeData" :default-props="defaultProps" @node-click="handleNodeClick"> </tree> </div> </template> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值