scroll-view 实现滑动显示,确保超出正常显示,小程序app,h5兼容
在uniapp 开开发的项目中,滑动操作是很多的
1.在插件市场使用了几款插件,但是都不太好用,要么是 显示的tab 过多,滑动到最后一个,当前显示那个跑左边显示不全,要么是滑动到最后一个后面的无法自动滑动,
2.基于借鉴别人写的以及自己处理了一下,目前感觉还行
3.使用需知道,显示的名字字段名字必须为name
自己循环处理一下即可, 并且不能为空(实际情况也不会为空),目前发现bug
4.若有其他需求,请自行修改
第一步
新建组件scroll-easy.vue
<template>
<view class="mianbox">
<scroll-view scroll-x="true" :style="{ height: defH + 'rpx',background: `${debg}` }" class="contentMain"
scroll-with-animation :scroll-left="scrollLeft">
<view :style="{ height: defH + 'rpx',lineHeight: defH + 'rpx'}" v-for="(item, index) in getList"
:key="index" class="scroll-item" @click="handItem(item,index)">
<view :style="curIndex === index ? getActiveStyle : getDefaultStyle">
{{ item.name }}
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
props: {
list: { // 循环的数据
type: Array,
required: true,
default: () => ([])
},
// 选中的下标
index: {
type: Number,
default: 0
},
// 默认传入样式
itemStyleDefault: {
type: Object,
default: () => ({})
},
// 默认传入选中样式
itemStyleActive: {
type: Object,
default: () => ({})
},
// 切换部分高度
defH: {
type: String,
default: '100'
},
// 切换整块的背景颜色
debg: {
type: String,
default: '#f1f1f1'
},
// 名字过长是否缩写
isNameEllipsis: {
type: Boolean,
default: false
},
// 超过数量
exceed: {
type: String,
default: "4"
},
},
data() {
return {
father_W: 0, // 导航区宽度
scrollLeft: 0, // 横向滚动条位置
curIndex: 0,
// 这里是最初的样式 如果父组件不传下来
defcss: {
'color': '#999',
'font-size': '14px',
'height': '100%',
},
actcss: {
'color': '#333',
'font-size': '16px',
'font-weight': 'bold',
'height': '98%',
'margin': '0 auto',
}
}
},
computed: {
getList() {
let arr = this.list
if (this.isNameEllipsis) {
arr.map((item) => {
item.name = this.formatwordlimit(item.name, this.exceed)
})
}
return arr
},
getDefaultStyle() {
return this.setStyle(this.defcss, this.itemStyleDefault)
},
getActiveStyle() {
return this.setStyle(this.actcss, this.itemStyleActive)
}
},
watch: {
index: {
handler(newVal, oldVal) {
this.scrollLf(newVal)
if (newVal) {
this.scrollLf(newVal)
}
},
immediate: true
}
},
mounted() {
// 初始化
this.init()
},
methods: {
formatwordlimit(cname, wordlength) {
let nowLength = cname.length
if (nowLength > wordlength) {
return cname = cname.substr(0, wordlength) + '..'
} else {
return cname
}
},
setStyle(target1, target2) {
// 传进来的覆盖当前的 属性名要一致
Object.assign(target1, target2)
let style = ''
Object.keys(target1).forEach((e) => {
style += `${e}: ${target1[e]};`
})
return style
},
init() {
// 返回一个 SelectorQuery 对象实例。可以在这个实例上使用 select 等方法选择节点,并使用 boundingClientRect 等方法选择需要查询的信息。
const query = uni.createSelectorQuery().in(this);
// 获取到循环父级盒子的宽度
query.select('.contentMain').boundingClientRect(data => {
// 拿到 scroll-view 组件宽度
this.father_W = data.width
}).exec();
// 获取标题区域宽度,和每个子元素节点的宽度以及元素距离左边栏的距离
query.selectAll('.scroll-item').boundingClientRect(data => {
let len = data.length;
for (let i = 0; i < len; i++) {
//获取到每个元素距离最左边的距离
this.getList[i].left = data[i].left;
// 获取到每个元素 宽度
this.getList[i].width = data[i].width
}
}).exec()
},
handItem(item, index) {
this.scrollLf(index)
this.$emit('handItem', item, index);
},
scrollLf(index) {
this.curIndex = index;
this.scrollLeft = this.getList[index].left - this.father_W / 2 + this.getList[index].width / 2;
}
}
}
</script>
<style scoped>
.mianbox {
width: 100%;
height: 100%;
}
.contentMain {
white-space: nowrap;
}
.scroll-item {
display: inline-block;
margin: 0 20rpx;
text-align: center;
}
</style>
直接使用
例如在index.vue
中
import scrollEasy from '../../components/scroll-easy.vue'
注意路径
<template>
<view>
1.默认样式
<view>
<scrollEasy :index='currindex' :list='category' @handItem='handthis' />
</view>
<view>
1.默认选中下标
<scrollEasy :index='currindex1' :list='category' @handItem='handthis' />
</view>
<view>
2.自定义背景颜色
<scrollEasy :list='category' debg='pink' :index='currindex' @handItem='handthis' />
</view>
<view>
3.自定义tab 默认样式
<scrollEasy :list='category' :index='currindex' @handItem='handthis'
:item-style-default="{ 'font-size': '32rpx','color': 'red'}" />
</view>
<view>
4.自定义tab 选中样式
<scrollEasy :list='category' :index='currindex' @handItem='handthis'
:item-style-active="{ 'font-size': '40rpx','font-weight': 'bold','color': 'red','border-bottom': '1px solid red'}" />
</view>
<view>
5.自定义 是否开启名字过长限制字数....
<scrollEasy :list='categoryOther' exceed='5' isNameEllipsis :index='currindex' @handItem='handthis' />
</view>
<view>
6.自定义高度
<scrollEasy debg='green' defH='180' :list='category' :index='currindex' @handItem='handthis' />
</view>
7.自定义布局
<view class='combox'>
<view class="left">
<scrollEasy :list='category' :index='currindex' @handItem='handthis' />
</view>
<view class="right">
站位部分
</view>
</view>
<view style="display: flex;">
<view v-for="(item,index) in category" :key="index" @click="addcurrindex(index)">
<button style="flex: 1;">{{index}}</button>
</view>
</view>
</view>
</template>
<script>
import scrollEasy from '../../components/scroll-easy.vue'
export default {
components: {
scrollEasy
},
data() {
return {
currindex: 0,
currindex1: 2,
category: [{
id: 1,
name: '面试信息1'
},
{
id: 2,
name: '面试信息2'
},
{
id: 3,
name: '面试信息3'
},
{
id: 4,
name: '面试信息4'
},
{
id: 6,
name: '面试信息5'
},
{
id: 7,
name: '面试信息6'
},
{
id: 81,
name: '充值中心7'
}, {
id: 62,
name: '火车司机8'
},
{
id: 73,
name: '销售专员9'
},
{
id: 84,
name: '娱乐主播10'
}
],
categoryOther: [{
id: 1,
name: '面试信息1'
},
{
id: 2,
name: '面试信息水电费2'
},
{
id: 3,
name: '面试信息3'
},
{
id: 4,
name: '面试信息4'
},
{
id: 6,
name: '面试信息四大分卫二5'
},
{
id: 7,
name: '面试信息6'
},
{
id: 81,
name: '充值中心7'
}, {
id: 62,
name: '火车司机8'
},
{
id: 73,
name: '销售专员9'
},
{
id: 84,
name: '娱乐主播10'
}
]
}
},
methods: {
addcurrindex(index) {
this.currindex = index
},
handthis(item, index) {
console.log(item)
console.log(index)
this.currindex = index
}
}
}
</script>
<style lang="scss" scoped>
.combox {
width: 100%;
display: flex;
}
.left {
flex: 1;
width: 0;
}
.right {
min-width: 100px;
width: 100rpx;
background: greenyellow;
text-align: center;
line-height: 100rpx;
}
</style>
原文地址:https://blog.csdn.net/qq_33323469/article/details/144406287
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!