better-scroll 踩坑总结
废话不多说直接进入正题。
下载安装
npm install better-scroll --save
在项目中使用该插件的页面引入
import Bscroll from 'better-scroll'
实例化scroll
this.$nextTick(() => {
this.scroll = new Bscroll(this.$refs.wrapper,{
scrollY: true,
click: true, //设置为true 滚动元素可点击
tap: true
})
})
项目实战
我这边主要写一个类似于电话本的列表点击定位到页面顶端的功能 主要代码:brandList.vue 组件
1 <template>
2 <div class="brandList">
3 <!-- <div class="recommend">{{branchTitle}}</div> -->
4 <div class="wrapper" ref="wrapper">
5 <div class="content">
6 <div class="brand" v-for= "(item,key) of brandList" :key= "key" :class= "item.code" :ref = "item.code">
7 <div class="title">{{ item.code }}</div>
8 <ul class="itemList" v-if="item.brandList!='undefined'">
9 <li class="item "
10 v-for=" innerItem of item.brandList"
11 :key= "innerItem.id"
12 @click= "handleCityClick(innerItem.id)"
13 >
14 <img class="brandImg" v-lazy="innerItem.logo" alt="">
15 <span class="brandName">{{innerItem.name}}</span>
16 </li>
17 </ul>
18 </div>
19 </div>
20 </div>
21 </div>
22 </template>
23 <script>
24 import Bscroll from 'better-scroll'
25 export default {
26 name:'brandList',
27 props:{
28 brandList:Array,
29 branchTitle:String,
30 letter: String
31 },
32 watch: {
33 letter () {
34 if (this.letter) {
35 // 获取dom元素 我这边本来用this.$refs[this.letter][0]获取元素,但是在手机上就是不滑动,改成了原生获取就好用了
36 const element = document.getElementsByClassName(this.letter)[0]; 40 this.scroll.scrollToElement(element);
41 }
42 }
43 },
44 mounted() {
45 // this.$refs.wrapper 获取dom 元素
46 this.$nextTick(() => {
47 this.scroll = new Bscroll(this.$refs.wrapper,{
48 scrollY: true,
49 click: true,
50 tap: true
51 })
52 })
53 },
54 methods:{
55 handleCityClick(id){
56 this.$router.push({
57 path:'/brandDetail',
58 query:{
59 brandId:id
60 }
61 })
62 }
63 }
64 }
65 </script>
66 <style lang="stylus" scoped>
67 .brandList
68 overflow hidden
69 .recommend
70 height: 58px;
71 font-size: 30px;
72 color: #5b3719;
73 text-align:center;
74 line-height:58px;
75 position fixed
76 left 0
77 right 0
78 z-index 1
79 background:linear-gradient(315deg,rgba(255,252,247,1) 0%,rgba(255,248,239,1) 100%);
80 .wrapper
81 background #f7f7f7
82 position:fixed;
83 top: 198px;
84 bottom: 102px;
85 left:0;
86 right: 0;
87 // z-index: 0;
88 .title
89 font-size: 40px;
90 font-weight: bold;
91 padding: 20px;
92 .itemList
93 width: 90%;
94 padding-left : 20px;
95 display: flex;
96 flex-wrap:wrap;
97 .item
98 width:25%;
99 margin-bottom : 20px;
100 .brandImg
101 width: 146px;
102 height: 146px;
103 border: 2px solid #eee;
104 border-sizing:border-box;
105 border-radius: 10px;
106 .brandName
107 display:block;
108 line-height: 32px;
109 font-size: 22px;
110 color: #333;
111 font-weight: 400;
112 overflow: hidden;
113 text-overflow: ellipsis;
114 white-space: nowrap;
115 text-align: center
116 </style>
右侧字母组件 brandName.vue
<template>
<ul class="list">
<li class="item">#</li>
<li class="item"
v-for= "(item, index) of letters"
:key= "item"
:ref= "item"
@click="handleLetterClick($event,index)"
>{{ item }}
<fade-animation>
<div class="keyCode" v-if="showIndex == index">
<span class="icon">{{item}}</span>
</div>
</fade-animation>
</li>
<li class="item">#</li>
</ul>
</template>
<script>
import FadeAnimation from '@/components/FadeAnimation'
export default {
name:'brandName',
components:{
FadeAnimation
},
props:{
brandList:Array
},
data(){
return{
showIndex:null
}
},
computed:{
letters() {
const letters = [];
this.brandList.forEach(el => {
letters.push(el.code)
})
return letters
}
},
methods:{
handleLetterClick(e,i) {
this.showIndex = i;
setTimeout(()=>{
this.showIndex = null
},2000)
this.$emit('change', e.target.innerText)
}
}
}
</script>
<style lang="stylus" scoped>
.list
position: fixed
right: 0
top: 256px
bottom: 102px;
width: 40px;
display: flex
flex-direction: column
justify-content:center
.item
text-align: center
line-height: 30px
font-size: 22px;
color: #333
position: relative
font-weight bold
.keyCode
width: 138px;
height: 136px;
background:url('../../../assets/image/icon_talk@2x.png')no-repeat center top;
background-size: 100% 100%;
position:absolute;
left:-138px;
top: -48px;
font-size: 50px;
line-height: 136px;
.icon
color: #fff;
font-weight:bold;
margin-left: -30px;
</style>
在父组件中调用 classifiCation.vue
- js引入
import brandList from './components/brandList'
import brandName from './components/brandName'
- 组件注入
components:{
brandList,
brandName
},
- 模板注入
<brand-list v-show= "contentIdx == '1'"
:branchTitle= "branchTitle"
:brandList= "brandList"
:letter= "letter"
></brand-list>
<brand-name @change= "handleLetterChange"
v-show= "contentIdx == '1'"
:brandList= "brandList"
></brand-name>
具体实现效果如下图
点击右侧相应的字母导航,左边内容标题会滚动到头部(位置可自定义)