Taro+vue3 实现电影切换列表

1.需求

 我们在做类似于猫眼电影的小程序或者H5 的时候 我们会做到那种 左右滑动的电影列表,这种列表一般带有电影场次 

2.效果

3.说明

 这种效果在淘票票 猫眼电影上 都有的 ,一般电影类型的H5 或者小程序 这个是都有的 第一是好看 第二是客观性比较好

4.代码、

1.整体页面
<template><div class="movie-container-index"><Header></Header><div class="swiper-main"><image class="background-img-vague" :src="chooseMovice.posterUrl" style="height: 100%;"></image><div class="wrap"><MovieList :list="movieList" @onchangeMovie="MovieChange" :model-value="chooseMovice.movieId"></MovieList></div><div class="box"></div></div><div class="movie-detail"><div class="name">{{ chooseMovice.movieName }}</div><div class="center-detail"><div>{{ chooseMovice.movieType }}</div><div>{{ chooseMovice.duration }}</div></div><div class="cast">{{ chooseMovice.cast }}</div></div><div class="movie-time-container"><Filter v-if="timeList.length" :data="timeList" @onChanged="onTimeChanged"></Filter></div><div class="movie-arrgement-container" v-if="arrangementList.length && !loading"><Item v-for="(item, index) in arrangementList" :info="item" :key="index"></Item></div><template v-if="arrangementList.length === 0 && loading"><div style="padding:  0 15px;"><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton><nut-skeleton :style="{ width: '100%', margin: '0.5rem 0' }" width="100%" height="15px" title animatedrow="1"></nut-skeleton></div></template><template v-if="arrangementList.length === 0 && !loading"><nut-empty description="暂无场次"></nut-empty></template></div>
</template>
<script setup>
import Header from './header.vue'
import MovieList from './movie-list.vue'
import Filter from './filter.vue'
import { ref, reactive, onMounted } from 'vue'
import Item from './item.vue'
const chooseMovice = ref({movieId: 12343,duration: 149,movieType: '剧情|历史|战争',cast: '吴京 易烊千玺 段奕宏 张涵予 朱亚文',posterUrl: "https://gw.alicdn.com/i1/O1CN01sSmj2b1daSm6IAUcs_!!6000000003752-0-alipicbeacon.jpg_480x480Q30s150.jpg",movieName: '长津湖之水门桥',})
const timeList = ref(["2024-01-09", "2024-01-10", "2024-01-13"])
const arrangementList = ref([])
const loading = ref(true)
const movieList = ref([{movieId: 12343,duration: 149,movieType: '剧情|历史|战争',cast: '吴京 易烊千玺 段奕宏 张涵予 朱亚文',movieName: '长津湖之水门桥',posterUrl: "https://gw.alicdn.com/i1/O1CN01sSmj2b1daSm6IAUcs_!!6000000003752-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "易烊千玺 田雨 陈哈琳 齐溪 公磊 许君聪 王宁 黄尧 巩金国",duration: 106,movieId: 147885,movieName: "奇迹·笨小孩",movieType: "剧情",posterUrl: "https://gw.alicdn.com/i1/O1CN013Ggc2s1Z8HwrwxAfn_!!6000000003149-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "张译,李晨,魏晨,曹炳琨,王骁,张子贤,杨新鸣",duration: 106,movieId: 147886,movieName: "三大队",movieType: "剧情,犯罪",posterUrl: "https://gw.alicdn.com/i4/O1CN01zQvWon1SuCCkUXTr8_!!6000000002306-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "岑珈其,梁朝伟,刘德华,蔡卓妍,任达华,陈家乐,白只,姜皓文,方中信,太保,钱嘉乐,周家怡",duration: 106,movieId: 147887,movieName: "金手指",movieType: "犯罪,剧情",posterUrl: "https://gw.alicdn.com/i4/O1CN01mdCwok1K4QV7FV8gv_!!6000000001110-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "李栋,大鹏,白客,庄达菲,王迅,孙艺洲,李乃文",duration: 106,movieId: 147888,movieName: "年会不能停!",movieType: "喜剧,剧情",posterUrl: "https://gw.alicdn.com/i1/O1CN01v6g8341QMBaLa2FhI_!!6000000001961-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "屈楚萧,张佳宁,傅菁,蒋昀霖,牛超,田壮壮,沙溢",duration: 106,movieId: 147889,movieName: "一闪一闪亮星星",movieType: "爱情,奇幻",posterUrl: "https://gw.alicdn.com/i4/O1CN01W8mzt61aa3k1Xtw3N_!!6000000003345-0-alipicbeacon.jpg_480x480Q30s150.jpg"},{cast: "江户川柯南,高山南,山崎和佳奈,小山力也,林原惠美,置鲇龙太郎,三石琴乃,土师孝也,乃村健次,飞田展男,绪方贤一,松井菜樱子,岩居由希子,大谷育江,茶风林",duration: 106,movieId: 147890,movieName: "名侦探柯南:黑铁的鱼影",movieType: "动画,悬疑,动作",posterUrl: "https://gw.alicdn.com/i1/O1CN01U9wWR81pfku0aqB6O_!!6000000005388-0-alipicbeacon.jpg_480x480Q30s150.jpg"}])
const MovieChange = (e) => {console.log(e);chooseMovice.value = movieList.value.filter((item) => item.movieId == e)[0]}
onMounted(() => {arrangementList.value = [{finishTime: "1704782520000",hallName: "7号激光杜比全景声厅",id: "1194219979173253121",pickUpPrice: 3380,price: 3500,showTime: "1704775500000"}]loading.value = false
})
</script>
<style lang="scss">
.movie-container-index {display: flex;flex-direction: column;.movie-arregment-container {}.swiper-main {height: 324px;position: relative;overflow: hidden;width: 100%;.background-img-vague {position: absolute;left: 0;right: 0;width: 100%;height: 100%;filter: blur(15px);-webkit-filter: blur(15px);}}.movie-detail {display: flex;flex-direction: column;align-items: center;justify-content: center;background-color: #fff;padding: 20px;.name {font-size: 30px;font-weight: 700;color: #15181d;}.center-detail {display: flex;align-items: center;color: #858a99;font-size: 24px;margin-top: 5px;}.cast {color: #858a99;font-size: 24px;margin-top: 5px;word-break: break-all;text-align: center;overflow: hidden;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;}}.wrap {padding: 10px 0;}.box {width: 0;height: 0;border: 10rpx solid;border-color: transparent transparent #fff #fff;transform: rotate(135deg);position: absolute;bottom: -10rpx;left: 0;right: 0;margin: 0 auto;}
}
</style>
2.movie-list代码<template><div class="movie-list-component"><div class="list-container"><scroll-view id="contentScroll" class="scroll-view" :scroll-with-animation="true" :scroll-left="scrollLeft":scroll-x="true"><div class="movie-item seat"></div><div :data-id="item.movieId" @click="selectMovie" :id="`movieItem${item.movieId}`" class="movie-item" :class="{ active: modelValue == item.movieId }" v-for="( item, index ) in  list " :key="index"><div class="img-container"><image class="img" :src="item?.posterUrl" alt="" /></div></div><div class="movie-item seat1"></div></scroll-view></div></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"]);onMounted(() => {// selectMovie(list.value[0].movieId)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) => {let offsetLeft = e.currentTarget.offsetLeft;let { id } = e.currentTarget.dataset;if (!id) {id = list.value[0].movieId;}if (modelValue.value == id) {return;}emit("onchangeMovie", id);getRect(id, offsetLeft);
};
//计算电影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: 324px;.scroll-view {width: 100%;height: 324px;white-space: nowrap;position: relative;.movie-item:nth-child(n+2) {margin-left: 35px;}.movie-item {display: inline-block;position: relative;margin-top: 30px;border-radius: 18px;width: 156px;height: 218px;// line-height: 208px;transition: width 1s;transition: height 1s;.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 {transform: scale(1.15);/* 放大1.2倍 */transition: transform 1s ease;/* 过渡效果 */}.seat {display: inline-block;width: 50%;// height: 290px;margin-left: -110px;}.seat1 {display: inline-block;width: 35%;}}}
}
</style>
filter 组件<template><div class="cinema-detail-filter-container"><div class="date-tab"><nut-tabs :title-gutter="15" v-model="tabTimesIndex" title-scroll><nut-tab-pane v-for="(item, index) in tabTimesList" :pane-key="index" :title="`${item.t} ${item.a}`"></nut-tab-pane></nut-tabs></div></div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref, toRefs, watch } from 'vue';
import moment from "moment";
const tabTimesIndex = ref(0)
const tabTimesList: any = ref([])
const props = defineProps({//子组件接收父组件传递过来的值data: Object,
});
//使用父组件传递过来的值
const { data: timesList } = toRefs(props);
onMounted(() => {getTimes()
});
const emit = defineEmits(['onChanged'])
watch(tabTimesIndex, (index) => {emit('onChanged', tabTimesList.value[index])
})
watch(tabTimesList, () => {emit('onChanged', tabTimesList.value[0])
})
const getTimes = () => {const times = timesList?.valueconst arr: any = []times?.forEach(item => {const time = itemlet t = getweek(moment(time).startOf('day').format('E'))if (time === moment().format('YYYY-MM-DD')) {t = '今天'} else if (time === moment().subtract(-1, 'days').format('YYYY-MM-DD')) {t = '明天'} else if (time === moment().subtract(-2, 'days').format('YYYY-MM-DD')) {t = '后天'}arr.push({time: time,t: t,a: time.substr(5, 9)})});tabTimesList.value = arr}
const getweek = (val) => {const week = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']return week[val - 1];
};
</script>
<style lang="scss">
.cinema-detail-filter-container {display: flex;flex-direction: column;.nut-tabs {.nut-tabs__titles {background: #ffffff !important;.nut-tabs__titles-item {.nut-tabs__titles-item__smile {display: none;}.nut-tabs__titles-item__text {color: #858a99;font-size: 22px !important;}}.nut-tabs__titles-item__line {background: linear-gradient(to right, #5232B7, #7237BC, #5232B7) !important;border-radius: 30px !important;}.nut-tabs__titles-item.active {.nut-tabs__titles-item__smile {display: block;margin-top: 10px;}.nut-tabs__titles-item__text {color: #15181d;}}}.nut-tabs__content {display: none !important;}}
}
</style>
header 组件<template><div class="movie-header-box"><div class="left"><div class="name">万达影城(北京昌平保利光魔店)</div><div class="address">昌平区鼓楼街贾琏时代广场四楼</div></div><div class="right"><IconFont name="locationg3" color="#5232B7"></IconFont></div></div>
</template>
<script setup>
import { IconFont } from '@nutui/icons-vue-taro';
</script>
<style lang="scss">
.movie-header-box {display: flex;align-items: center;justify-content: space-between;background-color: #fff;padding: 25px 30px;.left {.name {color: #15181d;font-weight: 700;font-size: 26px;}.address {color: #858a99;font-size: 22px;margin-top: 10px;}}
}
</style>

5.我这个项目是基于Taro +vue3 +ts 来写的 用的组件库也是京东的nut-ui  以上的代码和组件 也有的是我二次封装的组件 组件也挺方便的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/608882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql InnoDB行锁深入理解

Record Lock记录锁 Record Lock 称为记录锁&#xff0c;锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的&#xff1a; 当一个事务对一条记录加了 S 型记录锁后&#xff0c;其他事务也可以继续对该记录加 S 型记录锁&#xff08;S 型与 S 锁兼容&#xff09;&#xff0c;…

物联网与智能家居:跨境电商与未来生活的融合

物联网&#xff08;Internet of Things&#xff0c;IoT&#xff09;和智能家居技术正迅速崛起&#xff0c;成为跨境电商领域的创新引擎。这两者的巧妙结合不仅为消费者提供更智能、便捷的生活方式&#xff0c;同时也为电商平台和制造商带来了全新的商机。本文将深入探讨物联网与…

C++模板——(3)类模板

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 勤奋&#xff0c;机会&#xff0c;乐观…

使用pyinstaller打包生成exe(解决gradio程序的打包问题)

解决 [Errno 2] No such file or directory: gradio_client\types.json 问题&#xff0c;不需要手动创建hook文件 解决 FileNotFoundError: [Errno 2] No such file or directory: gradio\blocks_events.pyc 问题&#xff0c;不需要将pyi文件重命名为pyc文件 最终实现gradio程…

手撕 PCA

PCA&#xff08;Principal Component Analysis&#xff09;&#xff0c;中文名称&#xff1a;主成分分析。迄今为止最流行的降维算法。 假设 n 维空间中的一个单位立方体&#xff0c;易知&#xff1a;一维空间中该立方体中任意两点的距离不超过 1 1 1&#xff0c;二维空间中该…

自动连接校园网(河海大学)

layout: post # 使用的布局&#xff08;不需要改&#xff09; title: 自动连接校园网&#xff08;河海大学&#xff09; # 标题 subtitle: 网络 #副标题 date: 2024-01-09 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 catal…

GAMES101-Assignment4

一、问题总览 实现de Casteljau算法来绘制由4个控制点表示的Bzier曲线。需要修改main.cpp中的如下函数&#xff1a; bezier&#xff1a;该函数实现绘制Bzier曲线的功能。它使用一个控制点序列和一个OpenCV::Mat对象作为输入&#xff0c;没有返回值。它会使t在0到1的范围内进行…

Python采集微博评论做词云图

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境使用: Python 3.10 Pycharm 第三方模块使用: import requests >>> pip install requests import wordcloud >>> pip install wordclou…

扩展学习|数据融合助推商务智能与分析

文献来源&#xff1a;[1]李爱华,续维佳,石勇.基于数据融合的商务智能与分析架构研究[J].计算机科学,2022,49(12):185-194. 一、信息融合 &#xff08;一&#xff09;信息融合定义演变 早期信息融合的定义指出&#xff0c;其主要任务是综合分析若干传感器观测到的信息[9,…

微信小程序canvas画布实现矩形元素自由缩放、移动功能

获取画布信息并绘制背景 .whml <canvas class="canvas" type="2d" id="myCanvas" bindtouchstart="get_rect_touch_position" bindtouchmove="move_or_scale" bind:tap="finish_edit_check"/> .wxss .c…

【案例实战】业务稳定性运行之全链路混合压测

1.全链路压测开展步骤 &#xff08;1&#xff09;什么是全链路压测 全链路压测是指基于真实业务场景&#xff0c;通过模拟海量的用户请求&#xff0c;对整个后台服务进行压力测试&#xff0c;从而评估整个系统的性能水平。 对应用程序的整个技术栈进行完整的压力和性能测试&a…

关于24年信息系统项目管理师论文如何提升?

信息系统项目管理师论文满分是75分&#xff0c;45分及以上为及格&#xff0c;论文评分可分为优良、及格与不及格3个档次。 评分的分数可分为&#xff1a; &#xff08;1&#xff09;60分至75分优良&#xff08;相当于百分制80分至100分&#xff09;。 &#xff08;2&#xf…

数模学习day09-cftool使用

老版本的MATLAB可以在命令行使用cftool打开&#xff0c;2017a的版本可以直接找到。 x和y在你的工作区中需要已经存在&#xff0c;然后打开该工具箱就可以看见。 选择X和Y xy选择好之后就自动画好了拟合曲线。 Results分析 画好之后结果就呈现在这里了 这里的p1就是拟合系数&…

用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化

目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过&#xff0c;项目地址&#xff1a;xxl-job。它是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单…

【代码随想录】刷题笔记Day48

前言 早上练车去了&#xff08;好久没有8点前醒了&#xff09;&#xff0c;练科目二两小时下来脚根可真酸啊&#xff0c;希望下周一把过。练完顺带去Apple西湖免费换新了耳机&#xff0c;羊毛爽&#xff01; 121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09;…

JS逆向之无限debugger对抗

文章目录 JS中实现debugger的方法无限Debugger示例Demo1Demo2Demo3Demo4总结 无限Debugger实战 JS中实现debugger的方法 首先&#xff0c;我们要知道&#xff0c;在浏览器实现debugger的方法有哪些 debugger关键词 &#xff0c;相当于C内联汇编的int3&#xff0c;在代码中嵌入…

网工内推 | 运维工程师,国企、上市公司,RHCE认证优先

01 广东机场白云信息科技股份有限公司 招聘岗位&#xff1a;基础架构运维工程师&#xff08;中级&#xff09; 职责描述&#xff1a; 1、参与公司业务系统的监控、巡检、维护、故障定位、原因分析&#xff1b; 2、负责业务系统的上线、升级割接工作&#xff1b; 3、负责服务器…

Unity 踩坑记录 AnyState 切换动画执行两次

AnySate 切换动画 Can Transition To Self 将这个勾选去掉&#xff01;&#xff01;&#xff01;

Python学习之路-Hello Python

Python学习之路-Hello Python Python解释器 简介 前面说到Python是解释型语言&#xff0c;Python解释器的作用就是用于"翻译"Python程序。Python规定了一个Python语法规则&#xff0c;根据该规则可编写Python解释器。 常见的Python解释器 CPython&#xff1a;官方…