Bootstrap

Vue3获取dom元素方法 和 composition API 的使用场景 和 父传子使用props传值

写在前面: 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
    }
}
;