better-scroll是D8黄轶老师基于iscroll重写的一个插件,在vue中使用这个插件能给App带来流畅性,提高了用户体验。
1. 安装
npm install better-scroll --save
2.初始化
<div class="wrapper" ref="wrapper">
<div class="content">
<ul>
<li></li>
</ul>
</div>
</div>
import BScroll from 'better-scroll'
mounted () {
//创建实例
this.scroll = new Bscroll(this.$refs.wrapper)
}
3. 优点
例子1:
代码:
依照上面初始化格式,并且给 class=“list” 加 样式
.list
overflow :hidden
position :absolute
top: 5.9rem
right :0
left : 0
bottom : 0
例子2: 点击字母表的字母,左边城市会自动跳到相对应的位置
watch监听器的用法相当于是我们监视一个数据的变化,在这个数据变化时执行一些操作,这个操作可以是任何操作
watch: {
letter () {
if (this.letter) {
const element = this.$refs[this.letter][0]// * 必须要加 [0] 不然拿不到相应节点
console.log(element)
this.scroll.scrollToElement(element) // 这是 better-srcoll 内置的函数 ,起到自动索引并跳转的作用
}
console.log(this.letter)
}
}
}
原因:普通对象不可迭代
for…of 循环仅适用于迭代。 而普通对象不可迭代。 我们来看一下:
const obj = { fname: 'foo', lname: 'bar' };
for (const value of obj) { // TypeError: obj[Symbol.iterator] is not a function
console.log(value);
}
在这里,我们定义了一个普通对象 obj ,并且当我们尝试 for…of 对其进行操作时,会报错:TypeError: obj[Symbol.iterator] is not a function。
解决方案:
我们可以通过将类数组(array-like)对象转换为数组来绕过它。该对象将具有一个 length 属性,其元素必须可以被索引。我们来看一个例子:(es6语法)
const obj = { length: 3, 0: 'foo', 1: 'bar', 2: 'baz' };
const array = Array.from(obj);
for (const value of array) {
console.log(value);
Array.from() 方法可以让我通过类数组(array-like)或可迭代对象来创建一个新的 Array(数组) 实例。
touchstart:当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
touchmove:当手指在屏幕上滑动时连续地触发。在这个事件发生期间,调用preventDefault() 可以阻止滚动。
touchend:当手指从屏幕上移开时触发。
touchcancel:当系统停止跟踪触摸时触发。关于此事件的确切触发时间,文档中没有明确说明。
上面这几个事件都会冒泡,也都可以取消。虽然这些触摸事件没有在 DOM规范中定义,但它们却 是以兼容 DOM的方式实现的。因此,每个触摸事件的 event 对象都提供了在鼠标事件中常见的属性: bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、 ctrlKey 和 metaKey。
除了常见的 DOM属性外,触摸事件还包含下列三个用于跟踪触摸的属性:
touches:表示当前跟踪的触摸操作的 Touch 对象的数组。
targetTouchs:特定于事件目标的 Touch 对象的数组。
changeTouches:表示自上次触摸以来发生了什么改变的 Touch 对象的数组。
每个 Touch 对象包含下列属性:
clientX:触摸目标在视口中的 x坐标。
clientY:触摸目标在视口中的 y坐标。
identifier:标识触摸的唯一 ID。
pageX:触摸目标在页面中的 x坐标。
pageY:触摸目标在页面中的 y坐标。
screenX:触摸目标在屏幕中的 x坐标。
screenY:触摸目标在屏幕中的 y坐标。
target:触摸的 DOM节点目标。
例子:
滑动字母表,左边城市菜单跟着移动
代码
先在data中定义 touchStatus: false
handleTouchStart () {
this.touchStatus = true
},
handleTouchMove (e) {
if (this.touchStatus) {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
// 定时器 函数节流 提高网页性能
const touchY = e.touches[0].clientY - 70
// 70 是搜索框和头部的高度 下面的 75是第一个字母a到搜索框下边圆的距离
const index = Math.floor((touchY - 75) / 16)
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
this.categoryIndex = index
}
}, 10)
}
},
handleTouchEnd () {
this.touchStatus = false
}
clickcategory(index){ // 这里我们传入一个当前值
this.categoryIndex = index
}
data() {
return {
categoryIndex: 0, //点击当前背景变成白色索引
}
},
在css中设置我们当前选中项为active的类名,并给与一个背景颜色
.active {
background: #ccc
}
最后在html中绑定
<li @click="clickCategory(index)" :class="{active:categoryIndex==index}"> <!-- 选中当前动态绑定class -->
</li>
ref介绍:
ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
在JavaScript中需要通过document.querySelector("#demo")来获取dom节点,然后再获取这个节点的值。在Vue中,我们不用获取dom节点,元素绑定ref之后,直接通过this.$refs即可调用,这样可以减少获取dom节点的消耗。
通俗的讲,ref特性就是为元素或子组件赋予一个ID引用,通过this.$refs.refName来访问元素或子组件的实例
<span ref="span">Hello</span>
this.$refs.span
this.$refs介绍:
this.$refs是一个对象,持有当前组件中注册过 ref特性的所有 DOM 元素和子组件实例
注意:
this.$refs只有在组件渲染完成后才填充,在初始渲染的时候不能访问它们,并且它是非响应式的,因此不能用它在模板中做数据绑定
当ref和v-for一起使用时,获取到的引用将会是一个数组,包含循环数组源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<template>
<div>
<div ref="myDiv" v-for="(item, index) in arr" :key="index">{{item}}</div>
</div>
</template>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
arr: ['one', 'two', 'three', 'four']
}
},
mounted() {
console.log(this.$refs.myDiv)
}
})
</script>
</body>
</html>