|  | @@ -0,0 +1,317 @@
 | 
	
		
			
				|  |  | +<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>
 |