You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							317 lines
						
					
					
						
							7.5 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							317 lines
						
					
					
						
							7.5 KiB
						
					
					
				| <template> | |
| 	<!-- #ifndef APP-NVUE --> | |
| 	<view :class="['uni-col', sizeClass, pointClassList]" :style="{ | |
| 		paddingLeft:`${Number(gutter)}rpx`, | |
| 		paddingRight:`${Number(gutter)}rpx`, | |
| 	}"> | |
| 		<slot></slot> | |
| 	</view> | |
| 	<!-- #endif --> | |
| 	<!-- #ifdef APP-NVUE --> | |
| 	<!-- 在nvue上,类名样式不生效,换为style --> | |
| 	<!-- 设置right正值失效,设置 left 负值 --> | |
| 	<view :class="['uni-col']" :style="{ | |
| 		paddingLeft:`${Number(gutter)}rpx`, | |
| 		paddingRight:`${Number(gutter)}rpx`, | |
| 		width:`${nvueWidth}rpx`, | |
| 		position:'relative', | |
| 		marginLeft:`${marginLeft}rpx`, | |
| 		left:`${right === 0 ? left : -right}rpx` | |
| 	}"> | |
| 		<slot></slot> | |
| 	</view> | |
| 	<!-- #endif --> | |
| </template> | |
| 
 | |
| <script> | |
| 	/** | |
| 	 * Col	布局-列 | |
| 	 * @description	搭配uni-row使用,构建布局。 | |
| 	 * @tutorial	https://ext.dcloud.net.cn/plugin?id=3958 | |
| 	 * | |
| 	 * @property	{span} type = Number 栅格占据的列数 | |
| 	 * 						默认 24 | |
| 	 * @property	{offset} type = Number 栅格左侧的间隔格数 | |
| 	 * @property	{push} type = Number 栅格向右移动格数 | |
| 	 * @property	{pull} type = Number 栅格向左移动格数 | |
| 	 * @property	{xs} type = [Number, Object] <768px 响应式栅格数或者栅格属性对象 | |
| 	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4} | |
| 	 * @property	{sm} type = [Number, Object] ≥768px 响应式栅格数或者栅格属性对象 | |
| 	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4} | |
| 	 * @property	{md} type = [Number, Object] ≥992px 响应式栅格数或者栅格属性对象 | |
| 	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4} | |
| 	 * @property	{lg} type = [Number, Object] ≥1200px 响应式栅格数或者栅格属性对象 | |
| 	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4} | |
| 	 * @property	{xl} type = [Number, Object] ≥1920px 响应式栅格数或者栅格属性对象 | |
| 	 * 						@description	Number时表示在此屏幕宽度下,栅格占据的列数。Object时可配置多个描述{span: 4, offset: 4} | |
| 	 */ | |
| 	const ComponentClass = 'uni-col'; | |
| 
 | |
| 	// -1 默认值,因为在微信小程序端只给Number会有默认值0 | |
| 	export default { | |
| 		name: 'uniCol', | |
| 		// #ifdef MP-WEIXIN | |
| 		options: { | |
| 			virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现 | |
| 		}, | |
| 		// #endif | |
| 		props: { | |
| 			span: { | |
| 				type: Number, | |
| 				default: 24 | |
| 			}, | |
| 			offset: { | |
| 				type: Number, | |
| 				default: -1 | |
| 			}, | |
| 			pull: { | |
| 				type: Number, | |
| 				default: -1 | |
| 			}, | |
| 			push: { | |
| 				type: Number, | |
| 				default: -1 | |
| 			}, | |
| 			xs: [Number, Object], | |
| 			sm: [Number, Object], | |
| 			md: [Number, Object], | |
| 			lg: [Number, Object], | |
| 			xl: [Number, Object] | |
| 		}, | |
| 		data() { | |
| 			return { | |
| 				gutter: 0, | |
| 				sizeClass: '', | |
| 				parentWidth: 0, | |
| 				nvueWidth: 0, | |
| 				marginLeft: 0, | |
| 				right: 0, | |
| 				left: 0 | |
| 			} | |
| 		}, | |
| 		created() { | |
| 			// 字节小程序中,在computed中读取$parent为undefined | |
| 			let parent = this.$parent; | |
| 
 | |
| 			while (parent && parent.$options.componentName !== 'uniRow') { | |
| 				parent = parent.$parent; | |
| 			} | |
| 
 | |
| 			this.updateGutter(parent.gutter) | |
| 			parent.$watch('gutter', (gutter) => { | |
| 				this.updateGutter(gutter) | |
| 			}) | |
| 
 | |
| 			// #ifdef APP-NVUE | |
| 			this.updateNvueWidth(parent.width) | |
| 			parent.$watch('width', (width) => { | |
| 				this.updateNvueWidth(width) | |
| 			}) | |
| 			// #endif | |
| 		}, | |
| 		computed: { | |
| 			sizeList() { | |
| 				let { | |
| 					span, | |
| 					offset, | |
| 					pull, | |
| 					push | |
| 				} = this; | |
| 
 | |
| 				return { | |
| 					span, | |
| 					offset, | |
| 					pull, | |
| 					push | |
| 				} | |
| 			}, | |
| 			// #ifndef APP-NVUE | |
| 			pointClassList() { | |
| 				let classList = []; | |
| 
 | |
| 				['xs', 'sm', 'md', 'lg', 'xl'].forEach(point => { | |
| 					const props = this[point]; | |
| 					if (typeof props === 'number') { | |
| 						classList.push(`${ComponentClass}-${point}-${props}`) | |
| 					} else if (typeof props === 'object' && props) { | |
| 						Object.keys(props).forEach(pointProp => { | |
| 							classList.push( | |
| 								pointProp === 'span' ? | |
| 								`${ComponentClass}-${point}-${props[pointProp]}` : | |
| 								`${ComponentClass}-${point}-${pointProp}-${props[pointProp]}` | |
| 							) | |
| 						}) | |
| 					} | |
| 				}); | |
| 
 | |
| 				// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误 | |
| 				return classList.join(' '); | |
| 			} | |
| 			// #endif | |
| 		}, | |
| 		methods: { | |
| 			updateGutter(parentGutter) { | |
| 				parentGutter = Number(parentGutter); | |
| 				if (!isNaN(parentGutter)) { | |
| 					this.gutter = parentGutter / 2 | |
| 				} | |
| 			}, | |
| 			// #ifdef APP-NVUE | |
| 			updateNvueWidth(width) { | |
| 				// 用于在nvue端,span,offset,pull,push的计算 | |
| 				this.parentWidth = width; | |
| 				['span', 'offset', 'pull', 'push'].forEach(size => { | |
| 					const curSize = this[size]; | |
| 					if ((curSize || curSize === 0) && curSize !== -1) { | |
| 						let RPX = 1 / 24 * curSize * width | |
| 						RPX = Number(RPX); | |
| 						switch (size) { | |
| 							case 'span': | |
| 								this.nvueWidth = RPX | |
| 								break; | |
| 							case 'offset': | |
| 								this.marginLeft = RPX | |
| 								break; | |
| 							case 'pull': | |
| 								this.right = RPX | |
| 								break; | |
| 							case 'push': | |
| 								this.left = RPX | |
| 								break; | |
| 						} | |
| 					} | |
| 				}); | |
| 			} | |
| 			// #endif | |
| 		}, | |
| 		watch: { | |
| 			sizeList: { | |
| 				immediate: true, | |
| 				handler(newVal) { | |
| 					// #ifndef APP-NVUE | |
| 					let classList = []; | |
| 					for (let size in newVal) { | |
| 						const curSize = newVal[size]; | |
| 						if ((curSize || curSize === 0) && curSize !== -1) { | |
| 							classList.push( | |
| 								size === 'span' ? | |
| 								`${ComponentClass}-${curSize}` : | |
| 								`${ComponentClass}-${size}-${curSize}` | |
| 							) | |
| 						} | |
| 					} | |
| 					// 支付宝小程序使用 :class=[ ['a','b'] ],渲染错误 | |
| 					this.sizeClass = classList.join(' '); | |
| 					// #endif | |
| 					// #ifdef APP-NVUE | |
| 					this.updateNvueWidth(this.parentWidth); | |
| 					// #endif | |
| 				} | |
| 			} | |
| 		} | |
| 	} | |
| </script> | |
| 
 | |
| <style lang='scss' scoped> | |
| 	/* breakpoints */ | |
| 	$--sm: 768px !default; | |
| 	$--md: 992px !default; | |
| 	$--lg: 1200px !default; | |
| 	$--xl: 1920px !default; | |
| 
 | |
| 	$breakpoints: ('xs' : (max-width: $--sm - 1), | |
| 	'sm' : (min-width: $--sm), | |
| 	'md' : (min-width: $--md), | |
| 	'lg' : (min-width: $--lg), | |
| 	'xl' : (min-width: $--xl)); | |
| 
 | |
| 	$layout-namespace: ".uni-"; | |
| 	$col: $layout-namespace+"col"; | |
| 
 | |
| 	@function getSize($size) { | |
| 		/* TODO 1/24 * $size * 100 * 1%; 使用计算后的值,为了解决 vue3 控制台报错 */ | |
| 		@return 0.04166666666 * $size * 100 * 1%; | |
| 	} | |
| 
 | |
| 	@mixin res($key, $map:$breakpoints) { | |
| 		@if map-has-key($map, $key) { | |
| 			@media screen and #{inspect(map-get($map,$key))} { | |
| 				@content; | |
| 			} | |
| 		} | |
| 
 | |
| 		@else { | |
| 			@warn "Undeinfed point: `#{$key}`"; | |
| 		} | |
| 	} | |
| 
 | |
| 	/* #ifndef APP-NVUE */ | |
| 	#{$col} { | |
| 		float: left; | |
| 		box-sizing: border-box; | |
| 	} | |
| 
 | |
| 	#{$col}-0 { | |
| 		/* #ifdef APP-NVUE */ | |
| 		width: 0; | |
| 		height: 0; | |
| 		margin-top: 0; | |
| 		margin-right: 0; | |
| 		margin-bottom: 0; | |
| 		margin-left: 0; | |
| 		/* #endif */ | |
| 		/* #ifndef APP-NVUE */ | |
| 		display: none; | |
| 		/* #endif */ | |
| 	} | |
| 
 | |
| 	@for $i from 0 through 24 { | |
| 		#{$col}-#{$i} { | |
| 			width: getSize($i); | |
| 		} | |
| 
 | |
| 		#{$col}-offset-#{$i} { | |
| 			margin-left: getSize($i); | |
| 		} | |
| 
 | |
| 		#{$col}-pull-#{$i} { | |
| 			position: relative; | |
| 			right: getSize($i); | |
| 		} | |
| 
 | |
| 		#{$col}-push-#{$i} { | |
| 			position: relative; | |
| 			left: getSize($i); | |
| 		} | |
| 	} | |
| 
 | |
| 	@each $point in map-keys($breakpoints) { | |
| 		@include res($point) { | |
| 			#{$col}-#{$point}-0 { | |
| 				display: none; | |
| 			} | |
| 
 | |
| 			@for $i from 0 through 24 { | |
| 				#{$col}-#{$point}-#{$i} { | |
| 					width: getSize($i); | |
| 				} | |
| 
 | |
| 				#{$col}-#{$point}-offset-#{$i} { | |
| 					margin-left: getSize($i); | |
| 				} | |
| 
 | |
| 				#{$col}-#{$point}-pull-#{$i} { | |
| 					position: relative; | |
| 					right: getSize($i); | |
| 				} | |
| 
 | |
| 				#{$col}-#{$point}-push-#{$i} { | |
| 					position: relative; | |
| 					left: getSize($i); | |
| 				} | |
| 			} | |
| 		} | |
| 	} | |
| 
 | |
| 	/* #endif */ | |
| </style>
 | |
| 
 |