当前位置: 首页 > article >正文

vue3-print-nb的使用,点击回调

1. 安装

npm install vue3-print-nb --save

2. main.js引入

import print from 'vue3-print-nb' // 打印插件
app.use(print)

main引入报ts错误,可在env.d.ts里配置以下代码

declare module "vue3-print-nb";

3. 页面使用(代码可直接复制)

  • 注意:打印匹配纸张需要以百分比进行匹配,即设计稿元素里子元素占父级的百分比
<template>
    <el-dialog v-model="isShowPrint" destroy-on-close top="5vh" width="700" :before-close="cancelClick">
        <div class="print">
            <el-tabs tab-position="top" type="card" class="demo-tabs" v-model="activeTab">
                <el-tab-pane label="男生模板" :name="1">
                    <div id="template1" v-loading="printLoading">
                        <div class="template_1">
                            <div class="profile-card">
                                <img class="" src="@/assets/images/posterMaleBg.png" alt="" srcset="">
                                <div class="card-content">
                                    <img v-show="radio == 1" class="avatar" :src="logo" alt="logo" />
                                    <img v-show="radio == 2" class="avatar" :src="male" alt="卡通头像" />
                                    <img v-show="radio == 3" class="avatar real-avatar" :src="userDetail.avatar"
                                        alt="真人头像" />
                                    <div class="user-info">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab nick-name-lab">昵称</div>
                                                <div class="details-val nick-name"> {{ userDetail.nick_name }} </div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab">年龄</div>
                                                <div class="details-val">
                                                    <span>{{ userDetail.age }}</span>
                                                    <span class="birthday">({{ userDetail.birthday }})</span>
                                                </div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab">学历</div>
                                                <div class="details-val">{{ userDetail.qualification }}</div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab"> 身高</div>
                                                <div class="details-val">{{ userDetail.height }}</div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab">职业</div>
                                                <div class="details-val">{{ userDetail.occupation }}</div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab">年收入</div>
                                                <div class="details-val">{{ userDetail.income }}</div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div v-if="userDetail.city_name && userDetail.city_name.length > 7 ? true : false"
                                                class="details row-left ">
                                                <div class="details-lab city-lab">期望城市</div>
                                                <div class="details-val city-val">{{ userDetail.city_name }}</div>
                                            </div>
                                            <div v-else class="details row-left">
                                                <div class="details-lab">期望城市</div>
                                                <div class="details-val">{{ userDetail.city_name }}</div>
                                            </div>
                                            <!--   家乡 -->
                                            <div v-if="userDetail.home_city_name && userDetail.home_city_name.length > 6 ? true : false"
                                                class="details row-right">
                                                <div class="details-lab hometown-lab">家乡</div>
                                                <div class="details-val hometown-val">{{ userDetail.home_city_name }}
                                                </div>
                                            </div>
                                            <div v-else-if="userDetail.home_city_name" class="details row-right">
                                                <div class="details-lab">家乡</div>
                                                <div class="details-val">{{ userDetail.home_city_name }}</div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="expectations">
                                        <div>{{ userDetail.age_min }}-{{ userDetail.age_max }}</div>
                                        <div>身高{{ userDetail.height_min }}-{{ userDetail.height_max }}cm</div>
                                        <div> {{ userDetail.m_qualification }}</div>
                                    </div>
                                    <div class="code_container">
                                        <img class="code_img" :src="qrCodeUrl" alt="二维码" />
                                        <div class="qr_code_content">微信扫一扫,立刻认识ta</div>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="女生模板" :name="2">
                    <div id="template2"  v-loading="printLoading">
                        <div class="template_1">
                            <div class="profile-card">
                                <img class="" src="@/assets/images/posterFemaleBg.png" alt="" srcset="">
                                <div class="card-content">
                                    <img v-show="radio == 1" class="avatar" :src="logo" alt="logo" />
                                    <img v-show="radio == 2" class="avatar" :src="female" alt="卡通头像" />
                                    <img v-show="radio == 3" class="avatar real-avatar" :src="userDetail.avatar"
                                        alt="真人头像" />
                                    <div class="user-info">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab nick-name-lab">昵称</div>
                                                <div class="details-val nick-name"> {{ userDetail.nick_name }} </div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab">年龄</div>
                                                <div class="details-val">
                                                    <span>{{ userDetail.age }}</span>
                                                    <span class="birthday">({{ userDetail.birthday }})</span>
                                                </div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab">学历</div>
                                                <div class="details-val">{{ userDetail.qualification }}</div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab"> 身高</div>
                                                <div class="details-val">{{ userDetail.height }}</div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div class="details row-left">
                                                <div class="details-lab">职业</div>
                                                <div class="details-val">{{ userDetail.occupation }}</div>
                                            </div>
                                            <div class="details row-right">
                                                <div class="details-lab">年收入</div>
                                                <div class="details-val">{{ userDetail.income }}</div>
                                            </div>
                                        </div>
                                        <img class="line" src="@/assets/images/line.png" alt="">
                                        <div class="user-info-row">
                                            <div v-if="userDetail.city_name && userDetail.city_name.length > 7 ? true : false"
                                                class="details row-left ">
                                                <div class="details-lab city-lab">期望城市</div>
                                                <div class="details-val city-val">{{ userDetail.city_name }}</div>
                                            </div>
                                            <div v-else class="details row-left">
                                                <div class="details-lab">期望城市</div>
                                                <div class="details-val">{{ userDetail.city_name }}</div>
                                            </div>
                                            <!--   家乡 -->
                                            <div v-if="userDetail.home_city_name && userDetail.home_city_name.length > 6 ? true : false"
                                                class="details row-right">
                                                <div class="details-lab hometown-lab">家乡</div>
                                                <div class="details-val hometown-val">{{ userDetail.home_city_name }}
                                                </div>
                                            </div>
                                            <div v-else-if="userDetail.home_city_name" class="details row-right">
                                                <div class="details-lab">家乡</div>
                                                <div class="details-val">{{ userDetail.home_city_name }}</div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="expectations">
                                        <div>{{ userDetail.age_min }}-{{ userDetail.age_max }}</div>
                                        <div>身高{{ userDetail.height_min }}-{{ userDetail.height_max }}cm</div>
                                        <div> {{ userDetail.m_qualification }}</div>
                                    </div>
                                    <div class="code_container">
                                        <img class="code_img" :src="qrCodeUrl" alt="二维码" />
                                        <div class="qr_code_content">微信扫一扫,立刻认识ta</div>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </el-tab-pane>
            </el-tabs>
            <div class="footer">
                <div class="footer-left">
                    <el-radio-group v-model="radio" @change="radioChange">
                        <el-radio :value="1">logo</el-radio>
                        <el-radio :value="2">卡通头像</el-radio>
                        <el-radio :value="3">真人头像</el-radio>
                    </el-radio-group>
                </div>
                <div class="footer-right">
                    <el-button v-show="activeTab == 1" type="primary" size="small" v-print="printMaleObj">去打印</el-button>
                    <el-button v-show="activeTab == 2" type="primary" size="small" v-print="printFemaleObj">去打印</el-button>
                    <el-button size="small" @click="cancelClick">取消</el-button>
                </div>

            </div>
        </div>
    </el-dialog>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue';
import { userQrCode, getUserDetail } from '@/api/userManage/user';
import useLayOutSettingStore from '@/stores/modules/setting'
import { getChoose } from '@/utils/choose'
const props = defineProps({
    id: {
        type: String,
        required: true
    },
    logo: {
        type: String,
        required: true
    },
    male: {
        type: String,
        required: true
    },
    female: {
        type: String,
        required: true
    },
    gender: {
        type: Number,
        required: true
    }
});
let settingStore = useLayOutSettingStore();
const isShowPrint = ref(true);
const activeTab = ref(props.gender);
const emit = defineEmits(['cancel']);

const radio = ref(1)
const userDetail = reactive<any>({});
// 获取用户详情
const Choose = new getChoose();
const getDetail = async () => {
    settingStore.loading = true
    const { data } = await getUserDetail({ user_id: props.id });
    Object.assign(userDetail, data)
    userDetail.height = Choose.getHeightList(userDetail.height)
    userDetail.income = Choose.getAllStatus(userDetail.income, Choose.income)
    userDetail.qualification = Choose.getAllStatus(userDetail.qualification, Choose.qualification)
    if (!userDetail.m_qualification) {
        userDetail.m_qualification = '学历不限'
    } else if (userDetail.m_qualification == '1') {
        userDetail.m_qualification = Choose.getAllStatus(userDetail.m_qualification, Choose.qualification)
    } else {
        userDetail.m_qualification = Choose.getAllStatus(userDetail.m_qualification, Choose.qualification) + '及以上'
    }
    if (userDetail.nick_name.length > 8) {
        userDetail.nick_name = userDetail.nick_name.slice(0, 8) + '...'
    }
    userDetail.birthday = userDetail.birthday.slice(2, 4)
};
// 获取二维码
const qrCodeUrl = ref<any>('');
const getCodeData = async () => {
    const { data }: any = await userQrCode({ user_id: props.id });
    qrCodeUrl.value = data.qr_code_to_user;
};
const cancelClick = () => {
    emit('cancel');
};
onMounted(() => {
    getDetail();
    getCodeData();
});

const radioChange = (val: number) => {
    radio.value = val;
};
// 打印
const printLoading = ref(false)
const printMaleObj = ref({
    id:'template1',
    popTitle: 'good print',
    extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
    beforeOpenCallback(vue:any) {
        printLoading.value = true
    },
    openCallback(vue:any) {
        printLoading.value = false
    },
})
const printFemaleObj = ref({
    id:'template2',
    popTitle: 'good print',
    extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
    beforeOpenCallback(vue:any) {
        printLoading.value = true
    },
    openCallback(vue:any) {
        printLoading.value = false
    },
})

</script>
<style scoped lang="scss">
@page {
    size: auto;
    margin: 0mm;
}

@mixin template_1 {
    display: flex;
    align-items: center;
    justify-content: center;

    .profile-card {
        overflow: hidden;
        display: flex;
        flex-direction: column;
        justify-content: space-between;

        .poster-bg {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }

        .card-content {
            width: 100%;
            height: 100%;

            .avatar {
                position: absolute;
                top: 19%;
                left: 15%;
                width: 25%;
                height: 17%;
                border-radius: 8%;
            }

            .real-avatar {
                object-fit: cover;
            }

            .user-info {
                position: absolute;
                top: 35%;
                left: 12%;
                width: 75.6%;
                height: 26.6%;
                padding: 0 5%;
                display: flex;
                flex-direction: column;

                .user-info-row {
                    width: 100%;
                    display: flex;
                    justify-content: space-between;
                    margin: 4% 0;
                    font-family: PingFangSC, PingFang SC;

                    .details {
                        display: flex;
                        line-height: 100%;

                        .details-lab {
                            font-size: 14px;
                            color: #666;
                        }

                        .details-val {
                            flex: 1;
                            font-size: 14px;
                            color: #333;
                            font-weight: 580;

                            .birthday {
                                color: #666666;
                                margin-left: 5%;
                                font-weight: 400;
                            }
                        }

                        .nick-name-lab {
                            width: 17.1%;
                        }


                        .city-lab {
                            width: 34.1%;
                        }

                        .city-val {
                            line-height: 100%;
                        }

                        .hometown-lab {
                            width: 22%;
                        }
                    }

                    .row-left {
                        width: 55.7% !important;

                        .details-val {
                            margin-left: 4%;
                        }
                    }

                    .row-right {
                        flex: 1;

                        .details-val {
                            margin-left: 6%;
                        }
                    }
                }

                .user-info-row:nth-child(1) {
                    margin-top: 7.3%;
                }

                .user-info-row:nth-child(4) {
                    margin-bottom: 0;
                }

                .line {
                    width: 100%;
                    height: 1px;
                }

            }

            .expectations {
                position: absolute;
                left: 16.8%;
                bottom: 15.7%;
                width: 34.4%;
                height: 11.8%;
                display: flex;
                flex-direction: column;
                justify-content: space-around;
                font-size: 14px;
                font-weight: 400;
                color: #333;
            }

            .code_container {
                position: absolute;
                height: 20.7%;
                width: 25%;
                bottom: 13.5%;
                right: 16%;
                display: flex;
                flex-direction: column;
                text-align: center;

                .code_img {
                    height: 77%;
                    width: 93%;

                }

                .qr_code_content {
                    font-size: 10px;
                    font-weight: 580;
                    margin-top: 10%;
                    color: #333333;
                }
            }

        }
    }


}

@mixin template_2 {}

.print {
    .template_1 {
        @include template_1;

        .profile-card {
            position: relative;
            width: 450px;
            height: 636px;

        }
    }
}

.footer {
    display: flex;
    justify-content: space-between;
    padding: 15px;
}

@media print {
    .template_1 {
        @include template_1;

        .profile-card {
            position: relative;
            width: 1800px;
            height: 100vh;

            .user-info {
                top: 36% !important;

                .user-info-row {
                    margin: 5% 0 !important;

                    .details-lab {
                        font-size: 1.5rem !important;
                    }

                    .details-val {
                        font-size: 1.5rem !important;
                    }

                    .city-lab {
                        width: 34% !important;
                    }

                    .city-val {
                        line-height: 120% !important;
                        margin-left: 3.5% !important;
                        transform: translateY(-12%);
                    }

                    .hometown-val {
                        line-height: 120% !important;
                        transform: translateY(-10%);
                    }
                }
            }
            .expectations {
                font-size: 1.5rem !important;
            }

            .qr_code_content {
                font-size: 1rem !important;
            }
        }


    }


}
</style>

4. 父级组件使用

<template>
<PrintUser v-if="isShowPrint" :id="id" :logo :male :female :gender="gender" @cancel="printCancel"/> 
</template>
<script setup lang="ts">
import logo from '@/assets/images/logo.png'
import male from '@/assets/images/male.png'
import female from '@/assets/images/female.png'

const id = ref<string>('')
const isShowPrint = ref<boolean>(false)
const gender = ref<any>(1)
const showPrintUser = (row: any) => { 
    isShowPrint.value = true
    id.value = row.user_id
    gender.value = row.gender
}
const printCancel = ()=>{
    isShowPrint.value = false
}

</script>

http://www.kler.cn/a/567873.html

相关文章:

  • 《深度揭秘:生成对抗网络如何重塑遥感图像分析精度》
  • PHP的学习
  • include 与 require 的区别及最佳使用场景
  • 如何正确理解mAP、精度、召回率等概念
  • AQS源码级别解析
  • Redis大key如何处理的?
  • 【Java进阶】java设计模式之单例模式
  • c++_sort函数
  • Java设计模式 —— 【行为型模式】中介者模式(Mediator Pattern)详解
  • 实验环境搭建集锦(docker linux ros2+强化学习环境+linux上单片机串口调试)
  • OpenAI 正式发布 GPT-4.5 模型
  • FastAdmin 与其他后台框架的对比分析
  • 使用AI后为什么思考会变得困难?
  • INT202 Complexity of Algroithms 算法的复杂度
  • 第49天:Web开发-JavaEE应用SpringBoot栈模版注入ThymeleafFreemarkerVelocity
  • JVM垃圾回收机制垃圾回收相关算法垃圾收集器
  • 域名解析ip后如何查询该ip地址
  • 保姆级教程:用Chart.js实现柱状图与折线图联动
  • Harmony os next~鸿蒙原子化服务开发实战:天气卡片开发全解析
  • PostgreSQL中的模式(Schema)