fix(视频号组件): padding 影响布局
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :style="[componentStyle, { '--row-count': value.rowCount }]">
|
<view class="channel-list-container" :style="[componentStyle, { '--row-count': value.rowCount }]">
|
||||||
<!-- 轮播模式 -->
|
<!-- 轮播模式 -->
|
||||||
<swiper v-if="value.showStyle == 'carousel' && carouselConfig.type != 'hide'" :indicator-dots="isIndicatorDots"
|
<swiper v-if="value.showStyle == 'carousel' && carouselConfig.type != 'hide'" :indicator-dots="isIndicatorDots"
|
||||||
:autoplay="carouselConfig.autoplay || false" :interval="carouselConfig.interval || 3000"
|
:autoplay="carouselConfig.autoplay || false" :interval="carouselConfig.interval || 3000"
|
||||||
@@ -11,9 +11,8 @@
|
|||||||
<!-- 视频号视频卡片,轮播模式 -->
|
<!-- 视频号视频卡片,轮播模式 -->
|
||||||
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
:show-view-count="value.showViewCount"
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
:cover-style="computedCoverStyle" :play-btn-style="value.playBtnStyle"
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
:aspect-ratio="value.aspectRatio" />
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
@@ -25,24 +24,26 @@
|
|||||||
<!-- 视频号视频卡片,列表模式 -->
|
<!-- 视频号视频卡片,列表模式 -->
|
||||||
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
:show-view-count="value.showViewCount"
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
:cover-style="computedCoverStyle" :play-btn-style="value.playBtnStyle"
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
:aspect-ratio="value.aspectRatio" />
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 其他布局模式(如滚动布局) -->
|
<!-- 其他布局模式(如滚动布局) -->
|
||||||
<scroll-view v-else
|
<scroll-view v-else
|
||||||
:class="['channel-nav', value.showStyle == 'fixed' ? 'fixed-layout' : value.showStyle, 'row1-of' + value.rowCount]"
|
:class="['channel-nav', value.showStyle == 'fixed' ? 'fixed-layout' : 'singleSlide', 'row1-of' + value.rowCount]"
|
||||||
:scroll-x="value.showStyle == 'singleSlide'">
|
:scroll-x="true"
|
||||||
|
:scroll-y="false"
|
||||||
|
:enhanced="true"
|
||||||
|
:bounces="false">
|
||||||
<view class="uni-scroll-view-content">
|
<view class="uni-scroll-view-content">
|
||||||
<view v-for="(item, index) in value.list" :key="index" :class="['channel-nav-item', value.mode]">
|
<view v-for="(item, index) in value.list" :key="index"
|
||||||
|
:class="['channel-nav-item', value.mode, 'row1-of' + value.rowCount]">
|
||||||
<!-- 视频号视频卡片,滚动模式 -->
|
<!-- 视频号视频卡片,滚动模式 -->
|
||||||
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
<diy-channel-video :value="item" @video-play="playVideo" :list-mode="true"
|
||||||
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
:title-line-clamp="value.titleLineClamp" :show-play-btn="value.showPlayBtn"
|
||||||
:show-view-count="value.showViewCount"
|
:show-view-count="value.showViewCount" :cover-style="computedCoverStyle"
|
||||||
:cover-style="computedCoverStyle" :play-btn-style="value.playBtnStyle"
|
:play-btn-style="value.playBtnStyle" :aspect-ratio="value.aspectRatio" />
|
||||||
:aspect-ratio="value.aspectRatio" />
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@@ -107,6 +108,14 @@ export default {
|
|||||||
// 组件创建时的逻辑
|
// 组件创建时的逻辑
|
||||||
// 可以在这里进行初始化操作,如获取页面宽度等
|
// 可以在这里进行初始化操作,如获取页面宽度等
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
// 组件挂载后添加鼠标拖拽滚动功能
|
||||||
|
if (!['fixed', 'carousel'].includes(this.value?.showStyle)) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.addMouseDragScroll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
/**
|
/**
|
||||||
* 组件刷新监听
|
* 组件刷新监听
|
||||||
@@ -134,24 +143,24 @@ export default {
|
|||||||
* @returns {string} 样式字符串
|
* @returns {string} 样式字符串
|
||||||
*/
|
*/
|
||||||
componentStyle() {
|
componentStyle() {
|
||||||
let style = '';
|
const style = {};
|
||||||
// 背景色
|
// 背景色
|
||||||
if (this.value?.componentBgColor) {
|
if (this.value?.componentBgColor) {
|
||||||
style += 'background-color:' + this.value?.componentBgColor + ';';
|
style.backgroundColor = this.value?.componentBgColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 圆角样式
|
// 圆角样式
|
||||||
if (this.value?.componentAngle == 'round') {
|
if (this.value?.componentAngle == 'round') {
|
||||||
style += 'border-top-left-radius:' + (2 * this.value?.topAroundRadius) + 'rpx;';
|
style.borderTopLeftRadius = (2 * this.value?.topAroundRadius) + 'rpx';
|
||||||
style += 'border-top-right-radius:' + (2 * this.value?.topAroundRadius) + 'rpx;';
|
style.borderTopRightRadius = (2 * this.value?.topAroundRadius) + 'rpx';
|
||||||
style += 'border-bottom-left-radius:' + (2 * this.value?.bottomAroundRadius) + 'rpx;';
|
style.borderBottomLeftRadius = (2 * this.value?.bottomAroundRadius) + 'rpx';
|
||||||
style += 'border-bottom-right-radius:' + (2 * this.value?.bottomAroundRadius) + 'rpx;';
|
style.borderBottomRightRadius = (2 * this.value?.bottomAroundRadius) + 'rpx';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 装饰效果:阴影
|
// 装饰效果:阴影
|
||||||
style += 'box-shadow:' + (this.value?.ornament?.type == 'shadow' ? '0 0 10rpx ' + this.value?.ornament?.color : '') + ';';
|
style.boxShadow = this.value?.ornament?.type == 'shadow' ? '0 0 10rpx ' + this.value?.ornament?.color : '';
|
||||||
// 装饰效果:边框
|
// 装饰效果:边框
|
||||||
style += 'border:' + (this.value?.ornament?.type == 'stroke' ? '2rpx solid ' + this.value?.ornament?.color : '') + ';';
|
style.border = this.value?.ornament?.type == 'stroke' ? '2rpx solid ' + this.value?.ornament?.color : '';
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
@@ -289,6 +298,105 @@ export default {
|
|||||||
item.coverUrl = wechatChannelConfig.video.defaultCoverUrl;
|
item.coverUrl = wechatChannelConfig.video.defaultCoverUrl;
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 添加鼠标拖拽滚动功能
|
||||||
|
* 在Web环境中实现与微信小程序相同的拖拽滚动效果
|
||||||
|
*/
|
||||||
|
addMouseDragScroll() {
|
||||||
|
// 只在Web环境中添加
|
||||||
|
// #ifndef MP
|
||||||
|
console.log('addMouseDragScroll called');
|
||||||
|
|
||||||
|
let isDragging = false;
|
||||||
|
let startX = 0;
|
||||||
|
let startScrollLeft = 0;
|
||||||
|
let currentScrollElement = null;
|
||||||
|
|
||||||
|
// 查找最近的可滚动祖先元素
|
||||||
|
const findScrollableParent = (element) => {
|
||||||
|
while (element && element !== document) {
|
||||||
|
const style = window.getComputedStyle(element);
|
||||||
|
if (style.overflowX === 'auto' || style.overflowX === 'scroll') {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
element = element.parentElement;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标按下事件
|
||||||
|
const handleMouseDown = (e) => {
|
||||||
|
// 检查是否点击在组件内
|
||||||
|
if (this.$el.contains(e.target)) {
|
||||||
|
console.log('mousedown event in component:', e);
|
||||||
|
// 查找可滚动元素
|
||||||
|
currentScrollElement = findScrollableParent(e.target);
|
||||||
|
if (currentScrollElement) {
|
||||||
|
console.log('Found scrollable element:', currentScrollElement);
|
||||||
|
isDragging = true;
|
||||||
|
startX = e.pageX;
|
||||||
|
startScrollLeft = currentScrollElement.scrollLeft;
|
||||||
|
currentScrollElement.style.cursor = 'grabbing';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标移动事件
|
||||||
|
const handleMouseMove = (e) => {
|
||||||
|
if (!isDragging || !currentScrollElement) return;
|
||||||
|
console.log('mousemove event:', e);
|
||||||
|
e.preventDefault();
|
||||||
|
const dx = e.pageX - startX;
|
||||||
|
currentScrollElement.scrollLeft = startScrollLeft - dx;
|
||||||
|
console.log('scrollLeft:', currentScrollElement.scrollLeft);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标释放事件
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
if (isDragging && currentScrollElement) {
|
||||||
|
console.log('mouseup event');
|
||||||
|
currentScrollElement.style.cursor = 'grab';
|
||||||
|
}
|
||||||
|
isDragging = false;
|
||||||
|
currentScrollElement = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加全局事件监听器
|
||||||
|
document.addEventListener('mousedown', handleMouseDown);
|
||||||
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
document.addEventListener('mouseleave', handleMouseUp);
|
||||||
|
|
||||||
|
console.log('Global mouse event listeners added');
|
||||||
|
|
||||||
|
// 组件销毁时移除事件监听器
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
document.removeEventListener('mousedown', handleMouseDown);
|
||||||
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
|
document.removeEventListener('mouseleave', handleMouseUp);
|
||||||
|
console.log('Global mouse event listeners removed');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 为所有.channel-nav元素添加必要的样式
|
||||||
|
setTimeout(() => {
|
||||||
|
const channelNavs = document.querySelectorAll('.channel-nav');
|
||||||
|
console.log('Found channel-nav elements:', channelNavs.length);
|
||||||
|
channelNavs.forEach(element => {
|
||||||
|
element.style.overflowX = 'auto';
|
||||||
|
element.style.overflowY = 'hidden';
|
||||||
|
element.style.whiteSpace = 'nowrap';
|
||||||
|
element.style.width = '100%';
|
||||||
|
element.style.maxWidth = '100%';
|
||||||
|
element.style.cursor = 'grab';
|
||||||
|
element.style.userSelect = 'none'; // 防止文本选择
|
||||||
|
console.log('Added styles to channel-nav:', element);
|
||||||
|
});
|
||||||
|
}, 100); // 延迟执行,确保DOM已完全渲染
|
||||||
|
|
||||||
|
console.log('Mouse drag scroll setup completed');
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,6 +405,10 @@ export default {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './css/common-channel.scss';
|
@import './css/common-channel.scss';
|
||||||
|
|
||||||
|
.channel-list-container {
|
||||||
|
padding: 16px 16px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表布局样式
|
* 列表布局样式
|
||||||
*/
|
*/
|
||||||
@@ -304,7 +416,6 @@ export default {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 16px 16px 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -312,13 +423,36 @@ export default {
|
|||||||
* 支持固定布局和滚动布局
|
* 支持固定布局和滚动布局
|
||||||
*/
|
*/
|
||||||
.channel-nav {
|
.channel-nav {
|
||||||
padding: 16rpx;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
padding: 16rpx;
|
||||||
|
|
||||||
|
// 确保在H5环境中可以水平滚动
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
// 隐藏滚动条但保留滚动功能
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
|
||||||
|
// 启用触摸滚动和鼠标拖拽滚动
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
.uni-scroll-view-content {
|
.uni-scroll-view-content {
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 16rpx;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef MP-WEIXIN */
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单滑动模式
|
// 单滑动模式
|
||||||
@@ -327,6 +461,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channel-nav-item {
|
.channel-nav-item {
|
||||||
@@ -339,33 +474,59 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
/* #ifdef MP-WEIXIN */
|
||||||
|
&.row1-of1 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&.row1-of2 {
|
||||||
|
width: calc(50% - 8rpx);
|
||||||
|
}
|
||||||
|
&.row1-of3 {
|
||||||
|
width: calc(33.333% - 10.67rpx);
|
||||||
|
}
|
||||||
|
&.row1-of4 {
|
||||||
|
width: calc(25% - 12rpx);
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 列布局
|
// 1 列布局
|
||||||
&.row1-of1 {
|
&.row1-of1 {
|
||||||
.uni-scroll-view-content {
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 列布局
|
// 2 列布局
|
||||||
&.row1-of2 {
|
&.row1-of2 {
|
||||||
.uni-scroll-view-content {
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 列布局
|
// 3 列布局
|
||||||
&.row1-of3 {
|
&.row1-of3 {
|
||||||
.uni-scroll-view-content {
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 列布局
|
// 4 列布局
|
||||||
&.row1-of4 {
|
&.row1-of4 {
|
||||||
.uni-scroll-view-content {
|
.uni-scroll-view-content {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
// #endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,7 +552,6 @@ export default {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
grid-template-columns: repeat(var(--row-count, 2), 1fr);
|
||||||
gap: 16rpx;
|
gap: 16rpx;
|
||||||
padding: 16rpx;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.channel-item {
|
.channel-item {
|
||||||
|
|||||||
@@ -883,7 +883,7 @@ image {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/ .channel-list {
|
/deep/ .channel-list-container {
|
||||||
padding: 0rpx !important;
|
padding: 0rpx !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user