mirror of
				https://gitee.com/vant-contrib/vant.git
				synced 2025-10-31 03:22:08 +08:00 
			
		
		
		
	[improvement] Tabbar: jsx (#2663)
This commit is contained in:
		
							parent
							
								
									5b3992d4c2
								
							
						
					
					
						commit
						b8ec2ffc5d
					
				| @ -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} | ||||
|  | ||||
							
								
								
									
										54
									
								
								packages/tabbar-item/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								packages/tabbar-item/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||
|     ); | ||||
|   } | ||||
| }); | ||||
| @ -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> | ||||
| @ -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> | ||||
| @ -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 | ||||
| }; | ||||
|  | ||||
							
								
								
									
										8
									
								
								packages/utils/slots.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/utils/slots.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| export function useSlots({ $slots, $scopedSlots }) { | ||||
|   return (name, props) => { | ||||
|     if ($scopedSlots[name]) { | ||||
|       return $scopedSlots[name](props); | ||||
|     } | ||||
|     return $slots[name]; | ||||
|   }; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user