| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 | <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' >	/* 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>
 |