程序员的资源宝库

网站首页 > gitee 正文

uni-vue:自定义封装-利用函数传参的方式在关闭前可以执行自定义方法

sanyeah 2024-03-31 13:09:26 gitee 14 ℃ 0 评论

在封装dialog的时候,我们默认都有确认和取消来关闭弹框的功能,如果单纯进行封装,父组件调用的时候,点击确认按钮就会直接关闭,

通常情况下,我们需要执行一些事情比如事件逻辑操作后才进行关闭,这时候就可以利用函数能座位参数传递来进行关闭前可以自定义条件进行关闭了:

子组件:

定义参数进行判断:

cancel(){
                this.$emit('cancel')
                this.$refs.dialog.close()
            },
            confirm(){
                if(typeof this.callback==="function"){
                    this.callback(()=>{//调用传入的自定义函数
                    //这里的定义会在父组件内可以添加自定义事件
                        this.cancel()//函数内执行本方法
                    })
                }else{
                    this.$emit('cancel')
                    console.log('如果父组件未传入函数-没有进行操作的必要直接关闭的情况')
                    this.cancel()
                }

父组件:如果只是直接关闭,不用传入函数参数,如果需要关闭前进行操作,可以传入一个函数,函数内可以进行操作,操作完最后一行再执行关闭

btnDialog(item){
                switch (item.name){
                    case "删除":
                    this.$refs.dialog.open((close)=>{
                        //open 内传入一个函数-这样可以控制什么时候进行关闭,关闭前做一些事情比如操作,
                        // 再调用子组件定义好的本函数-close 进行关闭
                        //子组件要判断传入的是否为函数不然走else内的逻辑-直接关闭
                        //close 是子组件传过来的一个function,
              

            this.list = this.list.filter(item=>{ // 关闭前可自定义操作逻辑比如删除
            return !item.checked
            })
            close()//关闭核心
            uni.showToast({ // 关闭后也能进行一些操作
            title:"删除成功!",
            icon:"none"
            })


                    })
                    break;
                    default:
                    break;
                }
            },

 

需要注意的是,在打开的时候就要进行赋值来判断是否是函数:

子组件内:

open(callback=false){
                this.callback = callback;//传入的自定义函数
                this.$refs.dialog.open()
            },

整体代码:

子组件:

<template>
    <view>
        <uni-transtion ref="dialog">
            <view style="width:600rpx;background:#fff;" class="rounded">
                <view class="flex align-center justify-center font-weight-bold
                border-light-secondary border-bottom
                " style="height:100rpx">
                    {{title}}
                </view>
                <view class="flex align-center justify-center p-3">
                    <slot></slot>
                </view>
                <view class="flex border-light-secondary border-top" style="height:100rpx">
                    <view class="flex flex-1 text-muted align-center justify-center"
                    @tap="cancel()"
                    >{{cancelText}}</view>
                    <view class="flex flex-1 text-muted align-center justify-center"
                    @tap="confirm()">{{confirText}}</view>
                </view>
            </view>
        </uni-transtion>
    </view>
</template>

<script>
    import uniTranstion from '@/common/uni-ui/uni-popup/uni-popup.vue'
    export default {
        data(){
            return {
                callback:false
            }
        },
        props:{
            title:{
                type:String,
                default:'提示'
            },
            cancelText:{
                type:String,
                default:"取消"
            },
            confirText:{
                type:String,
                default:'q确定'
            }
        },
        components:{
            uniTranstion
        },
        methods:{
            open(callback=false){
                this.callback = callback;//传入的自定义函数
                this.$refs.dialog.open()
            },
            cancel(){
                this.$emit('cancel')
                this.$refs.dialog.close()
            },
            confirm(){
                if(typeof this.callback==="function"){
                    this.callback(()=>{//调用传入的自定义函数
                    //这里的定义会在父组件内可以添加自定义事件
                        this.cancel()//函数内执行本方法
                    })
                }else{
                    this.$emit('cancel')
                    console.log('如果父组件未传入函数-没有进行操作的必要直接关闭的情况')
                    this.cancel()
                }
                
                },
        }
    }
</script>

<style>
</style>

父组件:

<template>
    <view class="content">
        <!-- nav -->
        <nav-bar>
            <template v-if="checkedCount===0">
                <text slot="left" class="font-weight-bold font-md ml-3">
                    首页
                </text>
                <template>
                </template>
                <template slot="right">
                    <view
                    style="width: 60rpx;height: 60rpx;"
                    class="flex align-center justify-center bg-light rounded-circle mr-3"
                    >
                    <text class="iconfont text-center icon-zengjia"></text>
                    </view>
                    <view 
                    style="width: 60rpx;height: 60rpx;"
                    class="flex align-center justify-center bg-light rounded-circle mr-3"
                    >
                    <text class="iconfont icon-gengduo"></text>
                    </view>
                </template>
            </template>
            <template v-else>
                <text slot="left" class="font-md ml-3" @click="handlercheckedall(false)">取消</text>
                <text>已选中{{checkedCount}}个</text>
                <text slot="right" class="font-md mr-3" @click="handlercheckedall(true)">全选</text>
            </template>
        </nav-bar>
        <view style="height:44px;"></view>
        <!-- content -->
        <!-- <view style="height:2000px;background: #F1F1F1;"> -->
            <view class="px-3 py-2">
                <view class="position-relative">
                    <view style="width: 70rpx;height:70rpx;position: absolute;left: 0;top:0;" class="flex align-center justify-center">
                        <text class="iconfont icon-sousuo"></text>
                    </view>
                    <input type="text" style="height:70rpx;padding-left: 70rpx;" placeholder="请输入" class="bg-light">
                </view>
            </view>
            <f-list v-for="(item,index) in list" :key="index"
            :item="item"
            :index="index"
            @select = "select"
            >
            </f-list>
            <view v-if="checkedCount>0">
                <view style="height:115rpx;"></view>
                <view style="height:115rpx;margin-bottom:115rpx;" class="flex align-stretch bg-primary
                 text-white fixed-bottom">
                    <view class="flex flex-1 flex-column align-center justify-center" style="line-height:1.5"
                    hover-class="bg-hover-primary"
                    v-for="(item,index) in actions"
                    :key="index"
                    @click="btnDialog(item)"
                    >
                        <text class="iconfont" :class="item.icon"></text>
                        {{item.name}}
                    </view>
                </view> 
            </view>
            <f-dialog ref="dialog" @cancel="cancel" cancelText="取消" confirText="确定">
                是否确认删除?
            </f-dialog>
            <f-dialog ref="renamedialog" cancelText="取消重命名" confirText="确定重命名">
                <input v-model="renamevalue" type="text" placeholder="输入新名"/>
            </f-dialog>
    </view>
</template>
<script>
    import fDialog from '@/components/common/f-dialog.vue'
    import navBar from '@/components/common/nav-bar.vue'
    import fList from '@/components/common/f-list.vue'
    export default {
        data() {
            return {
                renamevalue:"",
                actionsM:[
                    {
                        icon:"icon-xiazai",
                        name:"下载"
                    },
                    {
                        icon:"icon-fenxiang-1",
                        name:"分享"
                    },
                    {
                        icon:"icon-shanchu",
                        name:"删除"
                    },
                    {
                        icon:"icon-chongmingming",
                        name:"重命名"
                    },
                ],
                list:[
                    {
                        type:"dir",
                        name:"我的笔记",
                        create_time:'2019-01-09 09:10:00',
                        checked:false
                    },
                    {
                        type:"image",
                        name:"风景.jpg",
                        create_time:'2019-01-09 09:10:00',
                        checked:false
                    },
                    {
                        type:"video",
                        name:"天启者.mp4",
                        create_time:'2019-01-09 09:10:00',
                        checked:true
                    },
                    {
                        type:"text",
                        name:"记事本.text",
                        create_time:'2019-01-09 09:10:00',
                        checked:false
                    },
                    {
                        type:"none",
                        name:"压缩包.rar",
                        create_time:'2019-01-09 09:10:00',
                        checked:false
                    },
                    
                ]
                }
        },
        components: {
        navBar,fList,fDialog
        },
        onLoad() {
        },
        computed:{
            actions(){
                if(this.checkedCount>1){
                    return [
                        {
                            icon:"icon-xiazai",
                            name:"下载"
                        },
                        {
                            icon:"icon-fenxiang-1",
                            name:"分享"
                        },
                    ] 
                }
                return this.actionsM
            },
            checkedList(){ 
                return this.list.filter(item=>item.checked)
            },
            checkedCount(){
                return this.checkedList.length
            },
        },
        methods: {
            cancel(){
                this.$refs.dialog.$refs.dialog.close()
                //在cancel内 这样调用也能关闭 利用事件传参在父组件中进行监听并访问关闭,
                //一般不会用 不然会覆盖下面传参的关闭
            },
            btnDialog(item){
                switch (item.name){
                    case "删除":
                    this.$refs.dialog.open((close)=>{
                        //open 内传入一个函数-这样可以控制什么时候进行关闭,关闭前做一些事情比如操作,
                        // 再调用子组件定义好的本函数-close 进行关闭
                        //子组件要判断传入的是否为函数不然走else内的逻辑-直接关闭
                        //close 是子组件传过来的一个function,
                        this.list = this.list.filter(item=>{
                            return !item.checked
                        })
                        close()//核心执行
                        uni.showToast({
                            title:"删除成功!",
                            icon:"none"
                        })
                    })
                    break;
                    case "重命名":
                    this.renamevalue = this.checkedList[0].name
                    this.$refs.renamedialog.open(close2=>{//close2 是参数所以可以自定义名执行时一致即可
                        this.checkedList[0].name = this.renamevalue
                        close2()
                    })
                    break;
                    default:
                    break;
                }
            },
            select(e){
                console.log(e)
                this.list[e.index].checked = e.value
            },
            handlercheckedall(checked){
                this.list.forEach(item=>{
                    item.checked = checked
                })
            }
        }
    }
</script>
<style>
</style>

 

 

 

 

 

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表