<template>
<view class="container">
<view class="fication-search">
<input type="text" value="" placeholder="请输入您要搜索的内容"/><image class="search-icon" src="../../static/images/search.png" mode=""></image>
</view>
<!-- 滚动区域 -->
<view class="scroll-panel" id="scroll-panel">
<view class="list-box">
<view class="left">
<scroll-view scroll-y="true" :style="{ height: scrollHeight + 'px' }" :scroll-into-view="leftIntoView">
<view
class="item"
v-for="(item, index) in leftArray"
:key="index"
:class="{ active: index == leftIndex }"
:id="'left-' + index"
:data-index="index"
@tap="leftTap"
>
<view class="activelink"></view>
<text class="item-name">{{ item }}</text>
</view>
</scroll-view>
</view>
<view class="main">
<scroll-view scroll-y="true" :style="{ height: scrollHeight + 'px' }" @scroll="mainScroll" :scroll-into-view="scrollInto" scroll-with-animation="true">
<view class="item main-item" v-for="(item, index) in mainArray" :key="index" :id="'item-' + index">
<view class="title">
<view>{{ item.title }}</view>
</view>
<view class="goods" v-for="(item2, index2) in item.list" :key="index2">
<view class="orderlist-list">
<view class="list-left">
<image src="../../static/images/store_bg.png" mode=""></image>
</view>
<view class="list-right">
<view class="list-name">香辣火锅</view>
<view class="list-ping">
<u-rate :count="count" active-color="#FFB800" inactive-color="#E0E0E0" size='32' v-model="value"></u-rate>
<text>{{4.8}}分</text>
</view>
<view class="list-meuns"><text>销量{{99}}+</text><text>配送费¥{{3}}</text><text>距离{{1.2}}km</text></view>
</view>
</view>
</view>
</view>
<view class="fill-last" :style="{ height: fillHeight + 'px' }"></view>
</scroll-view>
</view>
</view>
</view>
</view> </template>
<script>
export default{
data() {
return {
scrollHeight: 400,
scrollTopSize: 0,
fillHeight: 0, // 填充高度,用于最后一项低于滚动区域时使用
leftArray: [],
mainArray: [],
topArr: [],
leftIndex: 0,
scrollInto: '',
count: 5,
value: 4
};
},
computed: {
/* 计算左侧滚动位置定位 */
leftIntoView() {
return `left-${this.leftIndex > 3 ? this.leftIndex - 3 : 0}`;
}
},
mounted() {
/* 等待DOM挂载完成 */
this.$nextTick(() => {
/* 在非H5平台,nextTick回调后有概率获取到错误的元素高度,则添加200ms的延迟来减少BUG的产生 */
setTimeout(() => {
/* 等待滚动区域初始化完成 */
this.initScrollView().then(() => {
/* 获取列表数据,你的代码从此处开始 */
this.getListData();
});
}, 200);
});
},
methods: {
/* 初始化滚动区域 */
initScrollView() {
return new Promise((resolve, reject) => {
let view = uni.createSelectorQuery().select('#scroll-panel');
view.boundingClientRect(res => {
this.scrollTopSize = res.top;
this.scrollHeight = res.height;
this.$nextTick(() => {
resolve();
});
}).exec();
});
},
/* 获取列表数据 */
getListData() {
// Promise 为 ES6 新增的API ,有疑问的请自行学习该方法的使用。
new Promise((resolve, reject) => {
/* 因无真实数据,当前方法模拟数据。正式项目中将此处替换为 数据请求即可 */
uni.showLoading();
setTimeout(() => {
let [left, main] = [[], []]; for (let i = 0; i < 12; i++) {
left.push(`${i + 1}类商品`); let list = [];
let r = Math.floor(Math.random() * 10);
r = r < 1 ? 3 : r;
for (let j = 0; j < r; j++) {
list.push(j);
}
main.push({
title: `第${i + 1}类商品标题`,
list
});
} // 将请求接口返回的数据传递给 Promise 对象的 then 函数。
resolve({ left, main });
}, 1000);
}).then(res => {
console.log('-----------请求接口返回数据示例-------------');
console.log(res); uni.hideLoading();
this.leftArray = res.left;
this.mainArray = res.main; // DOM 挂载后 再调用 getElementTop 获取高度的方法。
this.$nextTick(() => {
this.getElementTop();
});
});
},
/* 获取元素顶部信息 */
getElementTop() {
new Promise((resolve, reject) => {
let view = uni.createSelectorQuery().selectAll('.main-item');
view.boundingClientRect(data => {
resolve(data);
}).exec();
}).then(res => {
let topArr = res.map(item => {
return item.top - this.scrollTopSize; /* 减去滚动容器距离顶部的距离 */
});
this.topArr = topArr; /* 获取最后一项的高度,设置填充高度。判断和填充时做了 +-20 的操作,是为了滚动时更好的定位 */
let last = res[res.length - 1].height;
if (last - 20 < this.scrollHeight) {
this.fillHeight = this.scrollHeight - last + 20;
}
});
},
/* 主区域滚动监听 */
mainScroll(e) {
let top = e.detail.scrollTop;
let index = 0;
/* 查找当前滚动距离 */
for (let i = this.topArr.length - 1; i >= 0; i--) {
/* 在部分安卓设备上,因手机逻辑分辨率与rpx单位计算不是整数,滚动距离与有误差,增加2px来完善该问题 */
if (top + 2 >= this.topArr[i]) {
index = i;
break;
}
}
this.leftIndex = index < 0 ? 0 : index;
},
/* 左侧导航点击 */
leftTap(e) {
let index = e.currentTarget.dataset.index;
this.scrollInto = `item-${index}`;
}
}
};
</script>
<style lang="scss"> page,
.container {
width: 100vw;
height: 100%;
}
/* 容器 */
.container {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start; // & > view {
// width: 100%;
// } .scroll-panel {
flex-grow: 1;
height: 0;
overflow: hidden;
} }
.fication-search{
width: 686rpx;
height: 64rpx;
margin: 12rpx auto;
background: #F5F6F7;
border-radius: 32rpx 32rpx 32rpx 32rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.fication-search input{
padding-left: 24rpx;
font-size: 12px;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #B5B5B5;
}
.fication-search input::-webkit-input-placeholder{
color:red!important;
} .search-icon{
width: 24rpx;
height: 24rpx;
margin-right: 30rpx;
}
.list-box {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
font-size: 28rpx; .left {
width: 196rpx;
background: #F5F6F7;
line-height: 112rpx;
box-sizing: border-box;
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC; .item { position: relative;
display: flex; &:not(:first-child) {
margin-top: 1px; &::after {
content: '';
display: block;
height: 0;
// border-top: #d6d6d6 solid 1px;
width: 620upx;
position: absolute;
top: 0px;
right: 0;
transform: scaleY(0.5); /* 1px像素 */
}
}
.item-name{
padding-left: 32rpx;
}
&.active {
color: #F7433D;
background-color: #fff;
}
&.active .activelink{
width: 8rpx;
height: 48rpx;
margin-top: 32rpx;
padding-left: 0;
background-color: #F7433D;
border-radius: 2px 2px 2px 2px;
}
}
.fill-last {
height: 0;
width: 100%;
background: none;
}
} .title {
line-height: 64rpx;
font-size: 16px;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #000000;
padding: 8rpx 0;
background-color: #fff;
position: sticky;
top: 0;
z-index: 19;
} }
.orderlist-list{
width: 526rpx;
height: 200rpx;
background: #FFFFFF;
margin: 0 auto;
display: flex;
border-bottom: 2rpx solid #F5F6F7;
// border-radius: 8px 8px 8px 8px;
}
.list-left{
margin: 24rpx;
width: 152rpx;
height: 152rpx;
border-radius: 4px 4px 4px 4px;
overflow: hidden;
}
.list-left image{
width: 100%;
height: 100%;
}
.list-right{
flex: 1;
display: flex;
flex-direction: column;
}
.list-name{
margin-top: 24rpx;
font-size: 16px;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 19px;
}
.list-ping{
margin: 20rpx 0;
display: flex;
font-size: 12px;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #FFB800; }
.list-ping text{
margin-left: 6rpx;
}
.list-meuns{
margin-bottom: 28rpx;
font-size: 12px;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #999999;
}
</style>

uniapp(vue)实现点击左侧菜单,右侧显示对应的内容的更多相关文章

  1. uniapp 微信小程序 实现左侧菜单右侧列表,双向联动的效果

    <template> <view class="u-wrap"> <view class="u-search-box"> & ...

  2. C# 窗体 类似framest 左侧点击右侧显示 左侧菜单右侧显示

    首先托一个splitContainer调节大小位置 然后进行再新创建一个窗体名为add 在左侧拖入button按钮 进入代码阶段 更改属性 public Main() { InitializeComp ...

  3. 用JavaScript实现点击左侧列表右侧显示列表内容的方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. ajax实现简单的点击左侧菜单,右侧加载不同网页

    实现:ajax实现点击左侧菜单,右侧加载不同网页(在整个页面无刷新的情况下实现右侧局部刷新,用到ajax注意需要在服务器环境下运行,从HBuilder自带的服务器中打开浏览效果即可) 原理:ajax的 ...

  5. C# WPF 左侧菜单右侧内容布局效果实现

    原文:C# WPF 左侧菜单右侧内容布局效果实现 我们要做的效果是这样的,左侧是可折叠的菜单栏,右侧是内容区域,点击左侧的菜单项右侧内容区域则相应地切换. wpf实现的话,我的办法是用一个tabcon ...

  6. 权限模块_使用权限_实现主页面的效果_显示左侧菜单&只显示有权限的菜单项

    权限模块__使用权限__实现主页面的效果 HomeAction.java public class HomeAction extends ActionSupport { public String i ...

  7. vue实现点击、滑动右侧字母对应各个城市

    1.字母组件给父组件传递当前点击的字母值 @click="handleLetterClick" //绑定事件 handleLetterClick (e) { //向上传递参数 th ...

  8. 关于ubuntu16.4 中安装最新的eclipse或者是STS出现页面特卡,且新建项目没有提示,preference选项中点击左侧标签右侧没反应的解决办法,参照google, 排版不太好,希望对一些小伙伴有所帮助

    up vote21down votefavorite 12 Eclipse was working as good as anything on 14.04. I did a clean instal ...

  9. 当chm文档点击左侧,右侧无内容时的解决方案

    右击chm文件->属性->安全选项卡,选择你登陆计算机的用户名,把权限改成完全控制就可以显示了

随机推荐

  1. do...while循环体

    基本语法 不要忘记while()后还需要加分号!!! 例(输出五句hello): int i = 1; //循环变量初始化 int max = 5; //循环的最大次数 do{ printf(&quo ...

  2. [题解] HDU 5115 Dire Wolf 区间DP

    考虑先枚举所有的物品中最后拿走的,这样就分成了2个子问题,即先拿完左边的,再拿完右边的,最后拿选出的那个.令dp(i,j)表示拿完[i,j]所有物品的最小代价.你可能会说,我们拿[i,j]这一段物品的 ...

  3. PCA原理及其代码实现

    首先简述一下PCA的作用: PCA是一种线性降维方法,它的目标i是通过某种线性投影,将高维的数据映射到低维空间中,并期望在所投影的维度上数据的信息量最大(方差最大),以此使用较少的数据维度,同时保留较 ...

  4. 计算机保研,maybe this is all you need(普通双非学子上岸浙大工程师数据科学项目)

    写在前面 9.28接收了拟录取通知,也终究是尘埃落定了,我人生的又一个阶段也终于结束.面对最终录取结果,或多或少会有所遗憾,但也还是基本达到了预期的目标了. 作为在今年严峻的保研形势下幸存的我,一直想 ...

  5. vue项目Eslint和prettier结合使用

    一.eslint介绍--代码语法检查工具 Eslint是一个代码检查工具,用来检查你的代码语法是否符合指定的规范,ECMAScript标准 二.prettier插件--代码格式化工具 prettier ...

  6. docker gitlab迁移 备份 部署 搭建以及各种问题

    当前环境 服务器A 服务器B ubuntu docker gitlab(版本一致) docker安装gitlab 由于考虑到gitlab 包含了⾃身的nginx.数据库.端⼝占⽤等等因数,这⾥使⽤的是 ...

  7. JavaScript函数式编程之函子

    函子(Functor) 函子是一个特殊的容器,通过一个普通对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理(变形关系),容器包含值和值变形关系(这个变形关系就是函数).函数式编 ...

  8. 【高并发】深度解析ScheduledThreadPoolExecutor类的源代码

    在[高并发专题]的专栏中,我们深度分析了ThreadPoolExecutor类的源代码,而ScheduledThreadPoolExecutor类是ThreadPoolExecutor类的子类.今天我 ...

  9. Codeforces Round #829 (Div. 2)/CodeForces1754

    CodeForces1754 注:所有代码均为场上所书 Technical Support 解析: 题目大意 给定一个只包含大写字母 \(\texttt{Q}\) 和 \(\texttt{A}\) 的 ...

  10. glusterfs安装配置

    目标: 原有的k8s的集群磁盘容量不够,数据迁移无法完成,数据迁移是物理机无法由于采购磁盘流程过程,申请虚拟机搭建glusterfs做分布式存储 磁盘规划: # 查看盘符 $ lsblk # 然后创建 ...