Vue3获取dom元素方法 和 composition API 的使用场景
写在前面: composition API 的使用场景
说明:将 和第三方库交互的逻辑 剥离出去的时候使用composition API
案例说明:
recommend.vue中使用了Slider插件实现主页轮播图效果
一、recommend组件——父组件
- 在父组件(recommend)中引用子组件(slider)
- 作用:动态请求数据,将数据传给子组件slider,对slider组件进行渲染
service文件
- recommend组件的数据请求方法封装在service中
1. base.js:封装了axios数据请求
// 前端发送请求的函数封装
import axios from 'axios'
const ERR_OK = 0
const baseURL='/'
axios.defaults.baseURL = baseURL
export function get(url,params) {
return axios.get(url,{
params
}).then((res) => {
const serverData = res.data
if(serverData.code === ERR_OK){
return serverData.result
}
}).catch((e) => {
console.log(e);
})
}
2. recommend.js:定义了getRecommend函数,获取轮播图的数据(向后台进行数据请求)
// 封装轮播图相关的请求
import { get } from './base'
export function getRecommend() {//获取轮播图的数据
return get('/api/getRecommend')
//与后端的接口要一致,(backend中router.js的注册推荐列表借口路由)
}
views文件—recommend.vue
- 因为recommend组件为一般组件,所以定义在views中
1、 引入slider组件,动态绑定sliders值
:sliders=“sliders”,将动态获取的sliders值渲染在页面上
<template>
<div class="recommend">
<div class="slider-wrapper">
<div class="slider-content">
<slider v-if="sliders.length" :sliders="sliders"></slider>
</div>
</div>
</div>
</template>
1、异步请求数据
recommend.vue调用recommend.js中的getRecommend函数,进行异步请求数据,将请求到的数据保存在sliders数组中
<script>
import { getRecommend } from '@/service/recommend'
import Slider from '@/components/base/slider/slider'
export default {
name: 'recommend',
components: {
Slider
},
data() {
return {
sliders: []
}
},
async created() {
const result = await getRecommend()//获取轮播图数据
this.sliders = result.sliders//将获取的数据传递给sliders数组
},
}
</script>
二、slider组件——子组件
- 因为slider组件是常用组件,所以定义在components中
- 作用:定义常用的轮播图组件,通过 ref 的方法获取dom元素(接收父亲传入的数据)
slider.vue
1、 ref的赋值,给dom元素用 ref =""命名
- 定义slider组件,绑定 ref 属性,赋值为rootRef,绑定这个响应式变量
代码如下:
<template>
<div class="slider" ref="rootRef">
<div class="slider-group">
<div
class="slider-page"
v-for="item in sliders"
:key="item.id"
>
<a :href="item.link">
<img :src="item.pic"/>
</a>
</div>
</div>
<div class="dots-wrapper">
<span
class="dot"
v-for="(item,index) in sliders"
:key="item.id"
:class="{'active':currentPageIndex === index}"
>
</span>
</div>
</div>
</template>
2、 使用props获取轮播图数据(父传子),接收父亲传来的数据
<script>
import {ref} from 'vue'
import useSlider from './user-slider'
export default {
name: 'slider',
props: {
sliders: {//轮播图数据
type: Array,
default() {
return []
}
}
},
3、 composition API 的使用,ref 的使用
- 在setup中声明一个响应式变量,这个变量的名字要和ref命名一致(rootRef ),绑定了ref属性的dom通过此方法获取该元素,最后返回这个变量
- 通过 ref 获取到dom元素,通过 rootRef.value获取该元素的值
- 调用user-slider.js中定义的useSlider方法,传入rootRef 作为参数,并使用结构的方法结构出currentPageIndex
代码如下:
setup() {
const rootRef = ref(null)
const { currentPageIndex } = useSlider(rootRef)
return {
rootRef,
currentPageIndex
}
}
}
</script>
注意:要想获取这个dom必须在onMounted中,因为setup替代了原来的created,所以应该在以上代码添加onMounted函数,因为该例子和第三方库存在交互的逻辑,所以将该函数抽离成了user-slider.js文件,完成对BetterScroll插件的注册和引用
onMounted(() => {
console.log(rootRef.value)
})
user-slider.js
1、 userSlider函数的封装
在user-slider.js中将 对BetterScroll插件的注册 封装成一个userSlider方法 ;userSlider方法中实现挂载时的初始化和卸载时的销毁
2、引入onMounted勾子
因为wrapperRef形参为 ref 定义的,想获取这个dom必须在onMounted中,因此需引入onMounted勾子
// BetterScroll插件的注册 引用 new BetterScroll
import BScroll from '@better-scroll/core'
import Slide from '@better-scroll/slide'
import { onMounted, onUnmounted, ref } from 'vue'
BScroll.use(Slide)
export default function userSlider(wrapperRef) {
const slider = ref(null)//在外部定义,
const currentPageIndex = ref(0)//当前图片索引
//在内部实例化初始化
onMounted(() => {//挂载的时候初始化
const sliderVal = slider.value = new BScroll
(wrapperRef.value, {
click:true,
scrollX:true,
scrollY:false,
momentum:false,
bounce:false,
probeType:2,
slide:true
})
sliderVal.on('slideWillChange',(page) => {
currentPageIndex.value=page.pageX
})
})
onUnmounted(() => {// 卸载的时候销毁
slider.value.destroy()
})
return {
slider,
currentPageIndex
}
}