1. 安装better-scroll
npm install better-scroll
2. 在具体实现功能里引用better-scroll 并且在store里引入数据
import BetterScroll from 'better-scroll';import { mapGetters } from 'vuex';
3. 在页面的左右目录外层添加ref 做了标记
4. 在data中定义
5. 在computed中引入数据; 在watch 监听左右两边滚动和右边列表高度;并且监听currentIndex
6. 在html中定义左侧滑动的样式
7.methods 里定义 添加this._initBScroll();和this._initRightHeight();方法;用于watch里监听
8. 添加点击左侧目录,右侧内容更着变化的方法
最后完整代码
<template> <div class="all"> <p>应用列表</p> <div class="main"> <div class="mulu"> <div class="fenlei">分类目录</div> <div ref="category"> <ul class="content" id="category"> <li v-for="(item, i) in applist" ref="menuList" :key="i" :class="{ current: i === currentIndex }" @click="clickList(i)" > <span :class="{ xianSpan: i === currentIndex }"></span> <span class="btn">{{ item.categoryName }}</span> </li> </ul> </div> </div> <div class="wrapper" ref="wrapper"> <ul class="content" ref="itemList"> <li v-for="(app, index) in applist" :key="index" class="cateAndlist"> <div class="catename">{{ app.categoryName }}</div> <div class="appAll"> <div v-for="(item, i) in app.appList" :key="i" class="listonce" :class="{ nopower: !item.authorized }"> <div class="getInto" @click="toapp(item.appUrl)" v-if="item.authorized"> <span>进入</span> <img src="@/assets/img/goapp.png" width="12" height="12" class="goimg" alt="" /> </div> <div v-else class="getIntos"> <span>访问权限未授权</span> </div> <div class="bottom"> <img :src="!item.iconUrl ? defaluteIcon : item.iconUrl" alt="" /> <div class="bottom_right"> <div class="appname">{{ item.appName }}</div> <div class="description" :title="item.description">{{ item.description }}</div> </div> </div> </div> </div> </li> </ul> </div> </div> </div></template><script>import BetterScroll from 'better-scroll';import { mapGetters } from 'vuex';export default { name: 'portal', data() { return { defaluteIcon: 'http://imservice.oss-cn-north-1.unicloudsrv.com/20200723044236469_workeractive.png', scrollY: 0, //右侧列表滑动的y轴坐标 rightLiTops: [], //所有分类头部位置 leftBscroll: null, rightBscroll: null, }; }, watch: { applist() { //监听数据 this.$nextTick(() => { // this.wordlimit(); //左右两边滚动 this._initBScroll(); //右边列表高度 this._initRightHeight(); }); }, }, computed: { ...mapGetters(['applist']), currentIndex(index) { const { scrollY, rightLiTops } = this; return rightLiTops.findIndex((tops, index) => { this._initLeftScroll(index); return scrollY >= tops && scrollY < rightLiTops[index + 1]; }); }, }, mounted() { // 调用 获取app列表的接口 this.$store.dispatch('getHomeAppList'); }, methods: { toapp(url) { window.open(url); }, _initBScroll() { // 挂在左右的实例 this.leftBscroll = new BetterScroll(this.$refs.category, {}); this.rightBscroll = new BetterScroll(this.$refs.wrapper, { scrollY: true, click: true, mouseWheel: true, }); // 监听右侧内容滑动时,左侧目录选中样式跟着变 this.rightBscroll.on('scrollEnd', pos => { this.scrollY = Math.abs(pos.y); }); // this.wordlimit(); }, _initRightHeight() { let itemArray = []; //定义一个伪数组 let top = 0; itemArray.push(top); //获取右边所有li的礼 let allList = this.$refs.itemList.getElementsByClassName('cateAndlist'); //allList伪数组转化成真数组 Array.prototype.slice.call(allList).forEach(li => { top += li.clientHeight; //获取所有li的每一个高度 itemArray.push(top); }); this.rightLiTops = itemArray; }, //点击左边实现滚动 clickList(index) { this.scrollY = this.rightLiTops[index]; this.rightBscroll.scrollTo(0, -this.scrollY, 200); }, _initLeftScroll(index) { let menu = this.$refs.menuList; let el = menu[index]; this.leftBscroll.scrollToElement(el, 300, 0, -300); }, wordlimit() { var cname = document.getElementsByClassName('description'); for (var i = 0; i < cname.length; i++) { var nowhtml = cname[i].innerHTML; var nowlength = cname[i].innerHTML.length; if (nowlength > 22) { cname[i].innerHTML = nowhtml.substr(0, 22) + '…'; } } }, },};</script><style lang="scss" scoped>.all { width: calc(100% - 40px); height: calc(100% - 40px); margin: 20px; background: #ffffff; box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.07); border-radius: 4px; p { font-size: 20px; margin: 0; font-family: SourceHanSansCN-Bold, SourceHanSansCN; font-weight: bold; color: #000000; padding: 20px 26px; border-bottom: 2px solid #eeeeee; } .main { padding: 20px 20px 0 20px; display: flex; height: calc(100% - 110px); .mulu { width: 14%; .fenlei { color: #707070; font-size: 18px; line-height: 25px; font-weight: 600; } #category { margin-top: 30px; font-size: 16px; color: #707070; line-height: 24px; padding: 0; height: 90%; overflow: auto; li { padding-left: 20px; margin-top: 4px; cursor: pointer; position: relative; .xianSpan { border-left: 3px solid #1890ff; position: absolute; top: 4px; height: 15px; left: 10px; display: inline-block; } a { width: 90%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; display: inline-block; text-decoration: none; color: #333; } .activedom { color: #1890ff; font-weight: bold; } } .current { color: #1890ff; position: relative; } } } .wrapper { height: 100%; overflow: hidden; width: 86%; .content { .cateAndlist { .catename { font-size: 18px; line-height: 25px; color: #333333; margin: 20px 0 10px 10px; font-weight: 600; } .appAll { width: 100%; display: flex; align-items: center; flex-wrap: wrap; .listonce { background: #f0f3f9; border-radius: 4px; width: calc(100% - 80% - 42px); padding: 10px; margin: 10px; min-width: 200px; .getInto { background: #f5f8ff; border-radius: 4px; border: 1px solid #b4c9fc; padding: 5px 15px; font-size: 12px; font-family: MicrosoftYaHei; color: #278dff; float: right; display: flex; align-items: center; cursor: pointer; .goimg { margin-left: 4px; } } .getIntos { font-size: 12px; font-family: MicrosoftYaHei; color: #c7c7c7; text-align: right; line-height: 28px; } .bottom { clear: both; display: flex; align-items: center; padding-bottom: 20px; width: 100%; .bottom_right { line-height: 24px; width: 60%; margin-left: 10px; height: 72px; .appname { font-size: 16px; font-family: PingFangSC-Semibold, PingFang SC; font-weight: 600; color: #000000; word-break: break-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .description { font-size: 12px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #666666; word-break: break-all; text-overflow: -o-ellipsis-lastline; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 2; -webkit-box-orient: vertical; } } } } .nopower { background: #f3f3f3; } } } } } }}</style>
页面样式