nut-popup 二次封装 弹窗 选择组件 vue3

2023-11-30 18:01

本文主要是介绍nut-popup 二次封装 弹窗 选择组件 vue3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

<template><nut-popup overlay-class="diolagClass" pop-class="nut-popup-name-class" :position="posititon"v-model:visible="showBasic" @click-overlay="handleClickoverlay" duration="0.2"><div class="search-container" v-show="isSearch"><div class="search-ipt"><input type="text" v-model="cityValue" /><IconFont name="search" color="#cccccc" style="position: absolute;left: 10px;top: 50%;transform: translateY(-50%);"></IconFont></div><div class="search-Icon"><IconFont name="search" color="#ffffff" style="font-size: 16px"></IconFont></div></div><scroll-view :scroll-y="true" :style="{ 'min-height': `${listContainerHeight / 2}px` }"><div class="list-container" v-if="!status"><div class="item" @click="toggleAllItems" :class="{ selected: areAllOptionsSelected() }">全部</div><div class="item" v-for="(item, index) in state.options1" :key="item.id" @click="toggleItem(item)":class="{ selected: isSelected(item.name) }">{{ item.name }}</div></div><div class="list-container" v-else><div class="item" v-for="(item, index) in state.options1" :key="item.id" @click="toggleRadioItem(item)":class="{ selected: isSelected(item.name) }">{{ item.name }}</div></div></scroll-view><div class="footerBtn" v-if="!status"><div class="footerBtn-left">已选择<span style="color: #ee0a24">{{ selectedItems.length }}</span>个</div><div class="footerBtn-right"><nut-button plain type="primary" @click="resetSelected"><template #icon><IconFont name="del2"></IconFont></template>重置</nut-button><nut-button style="margin-left: 20px" color="linear-gradient(to right, #ff6034, #ee0a24)"@click="handleClickConfirm" type="info">确认选择</nut-button></div></div><div v-else style="height: 40px"></div></nut-popup>
</template>
<script setup>
import { reactive, ref } from "vue";
import { storeToRefs } from "pinia";
import { IconFont } from "@nutui/icons-vue-taro";
import { toRefs } from "vue";
import Taro from "@tarojs/taro";
const props = defineProps({list: Array,status: Boolean,listContainerHeight: Number,showBasic: Boolean,type: String,posititon: String,isSearch: Boolean
});
const { list, status, listContainerHeight, showBasic, type, posititon, isSearch } =toRefs(props);
const selectedItems = ref([]);//判断一下当前的组件是哪个数据触发的
if (type.value == "movie" && Taro.getStorageSync("movie").length) {selectedItems.value = Taro.getStorageSync("movie");} else if (type.value == "cinema" && Taro.getStorageSync("cinema").length) {selectedItems.value = Taro.getStorageSync("cinema");} else {selectedItems.value = [];}const emit = defineEmits(["onFlagChange", "onconfirmItems", "seatChange", "onupdatedItems"])
const sleectedCloneItems = ref([]);const state = reactive({options1: list,
});const isSelected = (id) => {// console.log(id,"valSeat");return selectedItems.value.includes(id);
};const toggleItem = (e) => {if (isSelected(e.name)) {selectedItems.value = selectedItems.value.filter((item) => item !== e.name);} else {selectedItems.value.push(e.name);}
};
// 新增函数来检查是否所有选项都被选中
const areAllOptionsSelected = () => {return state.options1.every((item) => isSelected(item.name));
};// 修改点击"全部"选项的逻辑
const toggleAllItems = () => {if (areAllOptionsSelected()) {selectedItems.value = [];} else {selectedItems.value = state.options1.map((item) => item.name);}
};const toggleRadioItem = (e) => {selectedItems.value = [e.name];emit("seatChange", selectedItems.value);
};
const handleClickoverlay = () => {emit("onFlagChange", false);}//点击确定
const handleClickConfirm = async () => {console.log(selectedItems);await emit("onconfirmItems", { result: selectedItems.value, type: type.value })await emit("onFlagChange", false);}
//重置按钮const resetSelected = () => {if (!selectedItems.value.length) {return}selectedItems.value = [];
}</script>
<style lang="less">
.diolagClass {top: 65px !important;
}.nut-popup-name-class {margin-top: 65px;padding-top: 20px;
}.nut-popup--top {width: 100% !important;border-bottom-left-radius: 40px;border-bottom-right-radius: 40px;
}.list-container {display: flex;// align-items: center;justify-content: space-around;flex-wrap: wrap;padding: 0 20px;.selected {color: #ee0a24 !important;border: 1px solid #ee0a24;background-color: #fff !important;}.item {margin-top: 10px;font-size: 24px;width: 160px;height: 60px;line-height: 60px;background-color: #f7f8fb;border-radius: 25px;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;text-overflow: ellipsis;overflow: hidden;color: #15181d;text-align: center;}
}.footerBtn {display: flex;justify-content: space-between;align-items: center;padding: 20px;.footerBtn-left {color: #858a99;font-size: 30px;}.footerBtn-right {}
}.search-container {display: flex;justify-content: space-between;padding: 20px 40px;align-items: center;.search-ipt {background-color: #fff;border: 1px solid #ccc;// flex: 4;flex: 1;position: relative;border-radius: 45px;padding: 20px;font-size: 25px;input {padding-left: 70px;color: #858a99;}}.search-Icon {background-color: #fff;width: 50px;height: 50px;line-height: 50px;border-radius: 50%;display: flex;justify-content: center;align-items: center;margin-left: 40px;background-color: #ee0a24;opacity: 0.6;padding: 10px;}
}
</style>

1.目前组件需求 

移动端使用 ,当需要时选择 单选或者多选的时候 都可以用这个组件

2.效果图片

3.样式大家还可以微调 

这篇关于nut-popup 二次封装 弹窗 选择组件 vue3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437997

相关文章

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

Python用Flask封装API及调用详解

《Python用Flask封装API及调用详解》本文介绍Flask的优势(轻量、灵活、易扩展),对比GET/POST表单/JSON请求方式,涵盖错误处理、开发建议及生产环境部署注意事项... 目录一、Flask的优势一、基础设置二、GET请求方式服务端代码客户端调用三、POST表单方式服务端代码客户端调用四

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期