xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

vue component model prop event All In One

vue component model prop event All In One

vue components & custom events

https://vuejs.org/v2/guide/components-custom-events.html

WTF

demo

<template>
    <div class="inline-block">
        <el-select
            :class="['avatar-select', selected.url ? 'selected' : 'not-selected']"
            v-model="selected.id"
            popper-class="avatar-select-dropdown"
            :loading="loading"
            :popper-append-to-body="false"
            @change="handleChangeAvatar">
            <img class="result-img m-r-8" slot="prefix" :src="selected.url" />
            <div v-show="avatarList.length <= 1" class="no-data c-999 f12">
                暂无数据
            </div>
            <div v-show="avatarList.length > 1" class="avatar-select-options-content" style="max-height: 214px; overflow: auto;">
                <el-option
                    v-show="item.id"
                    v-for="item in avatarList" :key="item.id"
                    :value="item.id" :label="item.name">
                    <div  class="avatar-select-item">
                        <div class="avatar-select-item-img">
                            <img :src="item.url">
                            <span class="name c-333 f12 m-l-10 text-ellipsis" :title="item.name">{{item.name}}</span>
                        </div>
                        <a class="delete f12" v-show="showDeleteBtn" @click.stop="handleDeleteAvatar(item)">删除</a>
                    </div>
                </el-option>
            </div>
            <div v-show="showAvatarBottom" class="avatar-select-btn">
                <a class="hand" v-show="showAddBtn" @click.stop="handleAddAvatar">新建头像及昵称跳转页</a>
                <span v-show="showAddBtn" class="m-l-8 m-r-8" style="color: #c0c4cc;">|</span>
                <a class="hand" v-show="showRefreshBtn" @click.stop="getAvatarList">刷新</a>
            </div>
        </el-select>

        <AddAvatarModal
            :visible="addAvatarModalvisible"
            :spreaderId="spreaderId"
            :gameId="gameId"
            @close="handleAddAvatarModalClose"
            @confirm="handleAddAvatarModalconfirm">
        </AddAvatarModal>

        <el-dialog
            title="删除头像及昵称跳转页"
            :visible.sync="deleteModalvisible"
            width="420px"
            :modal-append-to-body='false'
            :before-close="handleDeleteModalClose">
            <el-row class="p-l-20 p-r-20">
                <el-col :span="24">
                    <i class="el-icon-warning m-r-10 f18 c-yellow"></i>
                    <span class="vertical-top">{{ `确定将删除“${currentDelete.name}”?` }}</span>
                </el-col>
            </el-row>
            <span slot="footer" class="dialog-footer">
                <el-button @click="handleDeleteModalClose">取 消</el-button>
                <el-button type="primary" :loading="confirmDeleteBtnLoading" @click="handleDeleteConfirm">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
import AddAvatarModal from './AddAvatarModal';
import Advertise2GdtService from '@/services/advertise-2/gdtService';
import Utils from '@/utils';

const allOperations = ['add','refresh','delete'];
let avatarListMap = {};
const defaultOption = { id: 0, name: '请选择', url: '' };

export default {
    name: 'AvatarSelect',
    components: { AddAvatarModal },
    props: {
        value: {
            type: [Number, String],
            default: 0,
        },
        operations: {
            type: Array,
            default: () => allOperations,
        },
        spreaderId: {
            type: Number,
            default: 0,
        },
        gameId: {
            type: Number,
            default: 0,
        },
    },
    model: {
        prop: 'value',
        event: 'change'
    },
    data () {
        return {
            avatarList: [],
            selected: {
                id: '',
                url: '',
                name: '',
            },
            addAvatarModalvisible: false,
            deleteModalvisible: false,
            currentDelete: {
                id: '',
                url: '',
                name: '',
            },
            confirmDeleteBtnLoading: false,
            loading: false,
        };
    },
    computed: {
        showAddBtn () {
            return this.operations.includes('add');
        },
        showRefreshBtn () {
            return this.operations.includes('refresh');
        },
        showDeleteBtn () {
            return this.operations.includes('delete');
        },
        showAvatarBottom () {
            return this.showAddBtn || showRefreshBtn;
        },
    },
    mounted () {
        this.getAvatarList();
    },
    methods: {
        getAvatarList () {
            const param = {
                game_id: this.gameId,
                spreader_id: this.spreaderId,
            };
            this.loading = true;
            return Advertise2GdtService.getGdtProfileList(param).then(resp => {
                let avatarList = resp.data.data.rows || [];
                this.loading = false;
                avatarList = Utils.convertObjInArray(avatarList, { 'head_image_url': 'url', id: 'id', name: 'name', description: 'description' });
                this.avatarList = [].concat(defaultOption, avatarList);
                avatarListMap = {...avatarListMap, ...Utils.getListMap(this.avatarList, 'id')};
                this.$nextTick(() => {
                    const listStyle = document.querySelector('.avatar-select .el-select-dropdown__list')?.style;
                    if (listStyle) {
                        listStyle.paddingTop = 0;
                        listStyle.paddingBottom = 0;
                    }
                    if (this.value) {
                        this.handleChangeAvatar(this.value);
                    }
                });
            }).catch(err => {
                this.loading = false;
            });
        },

        handleDeleteModalClose () {
            this.deleteModalvisible = false;
        },

        handleDeleteAvatar (avatarItem) {
            this.deleteModalvisible = true;
            this.currentDelete = avatarItem;
        },

        handleDeleteConfirm () {
            const param = {
                game_id: this.gameId,
                spreader_id: this.spreaderId,
                id: this.currentDelete.id
            };
            this.confirmDeleteBtnLoading = true;
            return Advertise2GdtService.deleteGdtProfile(param).then(resp => {
                this.confirmDeleteBtnLoading = false;
                this.$message.success('删除头像成功');
                this.handleDeleteModalClose();

                setTimeout(() => {
                    this.getAvatarList();
                }, 300);
            }).catch(err => {
                this.confirmDeleteBtnLoading = false;
            });
        },
        handleAddAvatar () {
            this.addAvatarModalvisible = true;
        },

        handleAddAvatarModalClose () {
            this.addAvatarModalvisible = false;
        },

        handleAddAvatarModalconfirm () {
            this.handleAddAvatarModalClose();

            // 不加定时器会有闪屏
            setTimeout(() => {
                this.getAvatarList();
            }, 300);
        },

        handleChangeAvatar (id) {
            const option = avatarListMap[id] || {};
            if (option.id) {
                this.selected.id = option.id;
                this.selected.name = option.name;
                this.selected.url = option.url;
            }
            this.$emit('change', id);
        },
    },
    watch: {
        value: {
            handler (val) {
                if (val) {
                    console.log('va ???', val);
                    this.handleChangeAvatar(val);
                }
            },
            immediate: true,
        },
    },
};
</script>

<style lang="scss" scoped>
.avatar-select {
    width: 300px;

    &.selected {
        /deep/ .el-input__inner {
            padding-left: 38px;
        }
    }

    &.not-selected {
        /deep/ .el-input__inner {
            padding-left: 15px;
        }
    }

    /deep/ .el-input__inner::placeholder {
        color: #c0c4cc !important;
    }

    .result-img {
        width: 24px;
        height: 24px;
        border-radius: 2px;
        position: relative;
        top: -1px;
    }
}

.el-select-dropdown.avatar-select-dropdown {

    .el-select-dropdown__wrap {

        .el-select-dropdown__item {
            padding: 0;
            height: 56px;
            line-height: 56px;

            .avatar-select-item {
                box-sizing: content-box;
                display: flex;
                justify-content: space-between;
                align-items: center;
                height: 56px;
                // line-height: 56px;
                padding: 0 10px;

                .avatar-select-item-img {
                    display: flex;
                    justify-content: flex-start;
                    align-items: center;
                    width: calc(100% - 50px);
                }

                img {
                    width: 40px;
                    height: 40px;
                    border-radius: 8px;
                }

                .name {
                    display: inline-block;
                    width: 178px;
                }

                .delete {
                    justify-content: flex-end;
                }
            }
        }
    }

    .avatar-select-btn {
        box-sizing: border-box;
        height: 36px;
        line-height: 36px;
        padding: 0 10px;
        border-top:  1px solid #EBEEF5;

        &.no-top-border {
            border-top-color:  transparent;
        }
    }

    .no-data {
        height: 80px;
        line-height: 80px;
        text-align: center;
    }
}
</style>


refs



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2021-09-28 21:04  xgqfrms  阅读(145)  评论(1编辑  收藏  举报