diff --git a/packages/mixins/checkbox.js b/packages/mixins/checkbox.js
index 94ea5dc23..f95e3d46f 100644
--- a/packages/mixins/checkbox.js
+++ b/packages/mixins/checkbox.js
@@ -1,6 +1,7 @@
 /**
  * Common part of Checkbox & Radio
  */
+import { useSlots } from '../utils';
 import Icon from '../icon';
 import findParent from './find-parent';
 
@@ -41,18 +42,18 @@ export default (parent, bem) => ({
   },
 
   render(h) {
-    const CheckIcon = this.$scopedSlots.icon ? (
-      this.$scopedSlots.icon({ checked: this.checked })
-    ) : (
+    const { checked } = this;
+    const slots = useSlots(this);
+    const CheckIcon = slots('icon', { checked }) || (
       <Icon name="success" style={this.iconStyle} />
     );
 
-    const Label = this.$slots.default && (
+    const Label = slots('default') && (
       <span
         class={bem('label', [this.labelPosition, { disabled: this.isDisabled }])}
         onClick={this.onClickLabel}
       >
-        {this.$slots.default}
+        {slots('default')}
       </span>
     );
 
@@ -64,7 +65,7 @@ export default (parent, bem) => ({
         }}
       >
         <div
-          class={bem('icon', [this.shape, { disabled: this.isDisabled, checked: this.checked }])}
+          class={bem('icon', [this.shape, { disabled: this.isDisabled, checked }])}
           onClick={this.onClickIcon}
         >
           {CheckIcon}
diff --git a/packages/tabbar-item/index.js b/packages/tabbar-item/index.js
new file mode 100644
index 000000000..0e898695e
--- /dev/null
+++ b/packages/tabbar-item/index.js
@@ -0,0 +1,54 @@
+import { use, useSlots } from '../utils';
+import Icon from '../icon';
+import Info from '../info';
+import RouterLink from '../mixins/router-link';
+
+const [sfc, bem] = use('tabbar-item');
+
+export default sfc({
+  mixins: [RouterLink],
+
+  props: {
+    icon: String,
+    dot: Boolean,
+    info: [String, Number]
+  },
+
+  data() {
+    return {
+      active: false
+    };
+  },
+
+  beforeCreate() {
+    this.$parent.items.push(this);
+  },
+
+  destroyed() {
+    this.$parent.items.splice(this.$parent.items.indexOf(this), 1);
+  },
+
+  methods: {
+    onClick(event) {
+      this.$parent.onChange(this.$parent.items.indexOf(this));
+      this.$emit('click', event);
+      this.routerLink();
+    }
+  },
+
+  render(h) {
+    const { icon, active } = this;
+    const slots = useSlots(this);
+    const style = active ? { color: this.$parent.activeColor } : null;
+
+    return (
+      <div class={bem({ active })} style={style} onClick={this.onClick}>
+        <div class={bem('icon', { dot: this.dot })}>
+          {slots('icon', { active }) || (icon && <Icon name={icon} />)}
+          <Info info={this.info} />
+        </div>
+        <div class={bem('text')}>{slots('default', { active })}</div>
+      </div>
+    );
+  }
+});
diff --git a/packages/tabbar-item/index.vue b/packages/tabbar-item/index.vue
deleted file mode 100644
index e93ac536d..000000000
--- a/packages/tabbar-item/index.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-<template>
-  <div
-    :class="b({ active })"
-    :style="style"
-    @click="onClick"
-  >
-    <div :class="b('icon', { dot })">
-      <slot
-        name="icon"
-        :active="active"
-      >
-        <icon
-          v-if="icon"
-          :name="icon"
-        />
-      </slot>
-      <van-info :info="info" />
-    </div>
-    <div :class="b('text')">
-      <slot :active="active" />
-    </div>
-  </div>
-</template>
-
-<script>
-import Info from '../info';
-import create from '../utils/create';
-import RouterLink from '../mixins/router-link';
-
-export default create({
-  name: 'tabbar-item',
-
-  components: {
-    [Info.name]: Info
-  },
-
-  mixins: [RouterLink],
-
-  props: {
-    icon: String,
-    dot: Boolean,
-    info: [String, Number]
-  },
-
-  data() {
-    return {
-      active: false
-    };
-  },
-
-  computed: {
-    style() {
-      return this.active ? { color: this.$parent.activeColor } : null;
-    }
-  },
-
-  beforeCreate() {
-    this.$parent.items.push(this);
-  },
-
-  destroyed() {
-    this.$parent.items.splice(this.$parent.items.indexOf(this), 1);
-  },
-
-  methods: {
-    onClick(event) {
-      this.$parent.onChange(this.$parent.items.indexOf(this));
-      this.$emit('click', event);
-      this.routerLink();
-    }
-  }
-});
-</script>
diff --git a/packages/tabbar/index.vue b/packages/tabbar/index.js
similarity index 66%
rename from packages/tabbar/index.vue
rename to packages/tabbar/index.js
index 4ed9c28e9..77a7a9719 100644
--- a/packages/tabbar/index.vue
+++ b/packages/tabbar/index.js
@@ -1,19 +1,8 @@
-<template>
-  <div
-    class="van-hairline--top-bottom"
-    :class="b({ fixed })"
-    :style="style"
-  >
-    <slot />
-  </div>
-</template>
+import { use } from '../utils';
 
-<script>
-import create from '../utils/create';
-
-export default create({
-  name: 'tabbar',
+const [sfc, bem] = use('tabbar');
 
+export default sfc({
   data() {
     return {
       items: []
@@ -33,14 +22,6 @@ export default create({
     }
   },
 
-  computed: {
-    style() {
-      return {
-        zIndex: this.zIndex
-      };
-    }
-  },
-
   watch: {
     items() {
       this.setActiveItem();
@@ -64,6 +45,16 @@ export default create({
         this.$emit('change', active);
       }
     }
+  },
+
+  render(h) {
+    return (
+      <div
+        style={{ zIndex: this.zIndex }}
+        class={['van-hairline--top-bottom', bem({ fixed: this.fixed })]}
+      >
+        {this.$slots.default}
+      </div>
+    );
   }
 });
-</script>
diff --git a/packages/utils/index.js b/packages/utils/index.js
index c38a41e87..2c710e80f 100644
--- a/packages/utils/index.js
+++ b/packages/utils/index.js
@@ -1,5 +1,6 @@
 import Vue from 'vue';
 import use from './use';
+import { useSlots } from './slots';
 
 const isServer = Vue.prototype.$isServer;
 
@@ -44,6 +45,7 @@ export {
   isObj,
   isDef,
   isServer,
+  useSlots,
   camelize,
   isAndroid
 };
diff --git a/packages/utils/slots.js b/packages/utils/slots.js
new file mode 100644
index 000000000..b324e9b35
--- /dev/null
+++ b/packages/utils/slots.js
@@ -0,0 +1,8 @@
+export function useSlots({ $slots, $scopedSlots }) {
+  return (name, props) => {
+    if ($scopedSlots[name]) {
+      return $scopedSlots[name](props);
+    }
+    return $slots[name];
+  };
+}