Taro+vue3 实现滑动列表 时切换电影

这篇具有很好参考价值的文章主要介绍了Taro+vue3 实现滑动列表 时切换电影。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Taro+vue3 实现滑动列表 时切换电影,taro,javascript,前端

<template>
    <div class="movie-list-component">
        <view class="list-container">
            <scroll-view id="contentScroll" class="scroll-view" :scroll-with-animation="true" :scroll-left="scrollLeft"
                :scroll-x="true" style="width: 100%;" @scroll="onScroll" @touchstart="onTouchStart" @touchend="onTouchEnd">
                <div class="movie-item seat"></div>
                <view :data-id="item.id" @click="selectMovie" :id="`movieItem${item.id}`" class="movie-item"
                    :class="{ active: modelValue == item.id }" v-for="( item, index ) in  list " :key="index">
                    <div class="img-container">
                        <image class="img" :src="item?.image" alt="" />
                    </div>
                    <!-- <div class="point-container"></div> -->
                </view>
                <div class="movie-item seat1"></div>
            </scroll-view>
        </view>
    </div>
</template>
<script setup lang="ts">
import Taro from "@tarojs/taro";
import { onMounted, ref, reactive, toRefs, watch } from "vue";
const props = defineProps({
    // 子组件接收父组件传递过来的值
    list: {
        type: Array<any>,
        required: true,
    },
    modelValue: {
        type: Number,
        required: true,
    },
});
//使用父组件传递过来的值
const { list, modelValue } = toRefs(props);
const emit = defineEmits(["onchangeMovie"]);
const clientWidths = ref(0)
const isSwitchingMovie = ref(false)
onMounted(() => {

    list?.value.map((item, index) => {
        if (item.id === modelValue?.value) {
            list?.value.unshift(list?.value.splice(index, 1)[0]);
        }
    });

});
const scrollLeft = ref(0);
//选择电影
const selectMovie = (e) => {
    isSwitchingMovie.value = true; // 点击切换电影时设置为true
    let offsetLeft = e.currentTarget.offsetLeft;
    let { id } = e.currentTarget.dataset;
    if (!id) {
        id = list.value[0].id;
    }
    if (modelValue.value === id) {
        return;
    }
    emit("onchangeMovie", id);
    getRect(id, offsetLeft);
};
//滚动事件处理函数
const onScroll = (e) => {
    if (isSwitchingMovie.value) {
        return; // 如果处于切换电影状态,不执行滚动事件逻辑
    }
    requestAnimationFrame(() => {
        const contentScroll = Taro.createSelectorQuery();
        contentScroll.select("#contentScroll").boundingClientRect();
        contentScroll.exec((res) => {
            const clientWidth = res[0].width;
            clientWidths.value = clientWidth;
            // 执行其他逻辑
        });

        const { scrollLeft } = e.detail;
        const currentIndex = Math.round(scrollLeft / (clientWidths.value / 4));
        const index = currentIndex >= list.value.length ? list.value.length - 1 : currentIndex;
        const id = list.value[index]?.id;

        if (modelValue.value !== id) {
            emit("onchangeMovie", id);
        }
    });
};
// 触摸开始事件,用于标记点击切换电影状态开始
const onTouchStart = () => {
    isSwitchingMovie.value = true;
};

// 触摸结束事件,用于标记点击切换电影状态结束
const onTouchEnd = () => {

    isSwitchingMovie.value = false;

};
//计算电影item的偏移量
const getRect = async (id, offsetLeft) => {

    const eleId = `#movieItem${id}`;

    const contentScrollWidth: any = await getContentScrollWidth("#contentScroll");
    const query = Taro.createSelectorQuery();
    query.select(eleId).boundingClientRect();
    query.selectViewport().scrollOffset();
    query.exec(async (res) => {

        //获取item的宽度de 一半
        const subhalfwidth = res[0].width / 2;
        //需要scrollview 移动的距离是
        const juli = offsetLeft - contentScrollWidth / 2 + subhalfwidth;
        scrollLeft.value = juli;
    });
};
// 获取ScrollView的宽度
const getContentScrollWidth = (ele) => {
    return new Promise((resolve) => {
        const query = Taro.createSelectorQuery();
        query.select(ele).boundingClientRect();
        query.selectViewport().scrollOffset();
        query.exec((res) => {
            const width = res[0].width;
            resolve(width);
        });
    });
};
</script>
<style lang="scss">
.movie-list-component {
    display: flex;
    flex-direction: column;

    .list-container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        height: 350px;

        .scroll-view {
            width: 100%;
            height: 320px;
            white-space: nowrap;
            position: relative;

            .movie-item {
                display: inline-block;
                position: relative;
                margin-left: 25px;
                // display: flex;
                // justify-content: center;
                // align-items: center;
                border-radius: 18px;
                // overflow: hidden;
                width: 146px;
                height: 218px;
                transition: width 0.8s;
                transition: height 0.8s;

                .img-container {
                    border-radius: 8px;
                    width: 100%;
                    height: 100%;
                    overflow: hidden;
                    position: relative;
                    z-index: 2;
                    // border: 5px #ffffff solid;

                    .img {
                        width: 100%;
                        height: 100%;
                    }
                }
            }

            .movie-item.active {
                // width: 180px !important;
                // height: 270px !important;
                transform: scale(1.1);
                transition: transform 0.8s ease;


                .img-container {
                    border-radius: 10px;
                    border: 3px #ffffff solid;
                }

                // .point-container {
                //     z-index: 1;
                //     height: 30px;
                //     width: 30px;
                //     background: #5232B7;
                //     // border-radius: 7px;
                //     position: absolute;
                //     bottom: -15px;
                //     left: 50%;
                //     margin-left: -15px;
                //     transform: rotate(45deg);
                // }
            }

            .seat {
                display: inline-block;
                width: 50%;
                height: 290px;
                margin-left: -100px;
            }

            .seat1 {
                display: inline-block;
                width: 36%;
                height: 290px;
                // margin-left: 50px;
            }
        }
    }
} 
</style> 

以上代码是滑动的组件 文章来源地址https://www.toymoban.com/news/detail-794376.html

到了这里,关于Taro+vue3 实现滑动列表 时切换电影的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3+taro+Nutui 开发小程序(一)

    前言:最近在调研开发小程序,发现现在taro框架逐渐成熟,能完美地使用vue3来进行开发,调研中发现京东的Nutui也不错所以准备写一个由0到1的vue3+taro+Nutui的小程序。 这篇我们首先搭建一个框架: vscode插件准备环节: 目前我用到的插件如下: Eslint   用来vue格式化代码的

    2024年02月08日
    浏览(33)
  • vue3+taro+Nutui 开发小程序(二)

    上一篇我们初始化了小程序项目,这一篇我们来整理一下框架 首先可以看到我的项目整理框架是这样的:  components:这里存放封装的组件 custom-tab-bar:这里存放自己封装的自定义tabbar interface:这里放置了Ts的一些基本泛型,不用Ts的可以忽略 pages:这里放置了小程序的所有页面

    2024年02月16日
    浏览(43)
  • Taro+Vue3 小程序引入echarts表

    背景:根据需求在一个报告界面需要展示不同的echarts表来使数据更友好的显示。 效果如下: 一.taro支持echarts 官方说明:Taro 文档支持引用小程序端第三方组件库 物料文档:Taro 物料市场 | 让每一个轮子产生价值 二.引入echarts-for-weixin插件 github地址: https://github.com/ecomfe/echar

    2024年02月13日
    浏览(36)
  • taro vue3 ts nut-ui 项目

    查看 Taro 全部版本信息​ 可以使用  npm info  查看 Taro 版本信息,在这里你可以看到当前最新版本 使用命令创建模板项目: taro init 项目名 微信小程序自定义 TabBar 先安装 cnpm install pinia 以便解决 小程序的 页面首次加载 在 app.config.js 中设置 在  src 目录 下 pages 文件夹,在里

    2024年02月06日
    浏览(40)
  • Taro+Vue3开发微信小程序的分享好友功能

    1、背景:使用taro框架和vue3框架开发小程序,实现一个把pdf文件直接分享给微信好友。 一开始看taro文档理解有偏差,导致分享出去的文件是个app的小程序连接。如下图  实现代码如下: 后续仔细查看taro文档, Taro 文档,发现这种写法是个页面组件,转发出去的是个小程序,

    2024年02月12日
    浏览(60)
  • taro+vue3 搭建一套框架,适用于微信小程序和H5

    安装 Taro。可以在终端输入以下命令进行安装: 创建项目。使用以下命令创建 Taro+Vue3 项目: 其中,myApp 是项目名称。 进入项目并启动。使用以下命令进入项目并启动: 注意,需要先进入对应的目录再启动。 编写代码。在 src 目录下编写代码,可以像使用 Vue 开发 Web 应用程

    2024年02月10日
    浏览(58)
  • taro 微信小程序写滑动删除左滑

    思路: css写布局,增加过渡效果,逻辑控制哪一条展开,展开项增加展开样式,滑动判断

    2024年02月10日
    浏览(66)
  • vue3 setup+Taro3 调用原生小程序自定义年月日时分多列选择器,NutUI改造

    NutUI 有日期时间选择器,但是滑动效果太差,卡顿明显。换成 原生小程序 很顺畅 上代码: 若需要自定义年开始时间,见 initColumn 方法 如作为组件,通过父级传递,可使用:

    2024年02月13日
    浏览(46)
  • Taro + vue3 + js + nutUI 框架中自定义tabbar的组件封装以及页面跳转的逻辑

    1.需求:   在H5 中需要封装一个自定义的tabbar 菜单跳转 通过nut-ui 进行二次封装 2. 注意点   H5 中原生的tabbar 在ios 中会出现问题 所以进行 封装tabbar 3. 代码操作 首先全部的代码  4.解析 tabList: 菜单的内容数组  根据自己菜单的数量 来决定 const tabList = reactivemenu[]([     {    

    2024年04月17日
    浏览(53)
  • 一文帮你搞定H5、小程序、Taro长列表曝光埋点

    对于很多前端同学来说,“埋点”常常是一个不愿面对却又无法逃避的话题。为什么这么说呢,相信很多前端同学都深有体会:首先埋点这个事基本是前端“独享”的,服务端基本不太涉及;其次添加埋点,往往看起来很简单但实际做起来很麻烦,很多时候为了获取一些埋点

    2024年02月16日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包