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 |  * Common part of Checkbox & Radio | ||||||
|  */ |  */ | ||||||
|  | import { useSlots } from '../utils'; | ||||||
| import Icon from '../icon'; | import Icon from '../icon'; | ||||||
| import findParent from './find-parent'; | import findParent from './find-parent'; | ||||||
| 
 | 
 | ||||||
| @ -41,18 +42,18 @@ export default (parent, bem) => ({ | |||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   render(h) { |   render(h) { | ||||||
|     const CheckIcon = this.$scopedSlots.icon ? ( |     const { checked } = this; | ||||||
|       this.$scopedSlots.icon({ checked: this.checked }) |     const slots = useSlots(this); | ||||||
|     ) : ( |     const CheckIcon = slots('icon', { checked }) || ( | ||||||
|       <Icon name="success" style={this.iconStyle} /> |       <Icon name="success" style={this.iconStyle} /> | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     const Label = this.$slots.default && ( |     const Label = slots('default') && ( | ||||||
|       <span |       <span | ||||||
|         class={bem('label', [this.labelPosition, { disabled: this.isDisabled }])} |         class={bem('label', [this.labelPosition, { disabled: this.isDisabled }])} | ||||||
|         onClick={this.onClickLabel} |         onClick={this.onClickLabel} | ||||||
|       > |       > | ||||||
|         {this.$slots.default} |         {slots('default')} | ||||||
|       </span> |       </span> | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
| @ -64,7 +65,7 @@ export default (parent, bem) => ({ | |||||||
|         }} |         }} | ||||||
|       > |       > | ||||||
|         <div |         <div | ||||||
|           class={bem('icon', [this.shape, { disabled: this.isDisabled, checked: this.checked }])} |           class={bem('icon', [this.shape, { disabled: this.isDisabled, checked }])} | ||||||
|           onClick={this.onClickIcon} |           onClick={this.onClickIcon} | ||||||
|         > |         > | ||||||
|           {CheckIcon} |           {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> | import { use } from '../utils'; | ||||||
|   <div |  | ||||||
|     class="van-hairline--top-bottom" |  | ||||||
|     :class="b({ fixed })" |  | ||||||
|     :style="style" |  | ||||||
|   > |  | ||||||
|     <slot /> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
| 
 | 
 | ||||||
| <script> | const [sfc, bem] = use('tabbar'); | ||||||
| import create from '../utils/create'; |  | ||||||
| 
 |  | ||||||
| export default create({ |  | ||||||
|   name: 'tabbar', |  | ||||||
| 
 | 
 | ||||||
|  | export default sfc({ | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|       items: [] |       items: [] | ||||||
| @ -33,14 +22,6 @@ export default create({ | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   computed: { |  | ||||||
|     style() { |  | ||||||
|       return { |  | ||||||
|         zIndex: this.zIndex |  | ||||||
|       }; |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
| 
 |  | ||||||
|   watch: { |   watch: { | ||||||
|     items() { |     items() { | ||||||
|       this.setActiveItem(); |       this.setActiveItem(); | ||||||
| @ -64,6 +45,16 @@ export default create({ | |||||||
|         this.$emit('change', active); |         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 Vue from 'vue'; | ||||||
| import use from './use'; | import use from './use'; | ||||||
|  | import { useSlots } from './slots'; | ||||||
| 
 | 
 | ||||||
| const isServer = Vue.prototype.$isServer; | const isServer = Vue.prototype.$isServer; | ||||||
| 
 | 
 | ||||||
| @ -44,6 +45,7 @@ export { | |||||||
|   isObj, |   isObj, | ||||||
|   isDef, |   isDef, | ||||||
|   isServer, |   isServer, | ||||||
|  |   useSlots, | ||||||
|   camelize, |   camelize, | ||||||
|   isAndroid |   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