笔记

万物寻其根,通其堵,便能解其困。
  博客园  :: 新随笔  :: 管理

vue控件 之 父子模板创建、引用和通信

Posted on 2024-05-06 10:08  草妖  阅读(1)  评论(0)    收藏  举报

离线引入/Vue2注册:

父模板(*.html):

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>测试模板</title>
    <link rel="stylesheet" type="text/css" href="./searchUI/searchUI.css">
    <style type="text/css">
        .searchUI-tips-area{
            width: 250px;
            height: 32px;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <div id="paperFrame">
        <div class="searchUI-tips-area">
            <search-ui-btn ref="searchUIBtn" placeholder="请输入测试搜索UI相关内容" capitalization-test="关于参数大小写问题测试"></search-ui-btn>
        </div>
    </div>
    <script type="text/javascript" src="./jquery-3.6.0.min.js"></script>
    <script type="text/javascript" src="./vue.min.js"></script>
    <script type="text/javascript" src="./searchUI/searchUI.js"></script>
    <script type="text/javascript">
        var pageFrame = new Vue({
            data: {
                childSearchInfo:null,
                scrollops: {
                    vuescroll: {},
                    scrollPanel: {
                        scrollingX: false
                    },
                    rail: {
                    },
                    bar: {
                        size:'8px',
                        onlyShowBarOnScroll: false,
                        background: '#2a3340'
                    }
                },
            },
            //计算属性
            computed: {
            },
            components: {
            },
            //方法
            methods: {
                // search-ui-btn控件相关
                recvSearchInfo:function(info){
                    // 接收搜索内容
                    // 也可以通过pageFrame.$refs['searchUIBtn'].searchInfo获取
                    // 关于参数需要注意大小写问题,如:capitalization-test
                    this.childSearchInfo=info;
                    // 搜索
                }
            },
            //el挂载完后调用
            mounted: function () {
            }
        }).$mount('#paperFrame');
    </script>
</body>
</html>

 

子模板(注册成控件,并与父级模板通信):

Vue.component("search-ui-btn", {
    template: '<div class="search-ui-area"><input class="search-info" type="text" :placeholder="placeholder" v-model="searchInfo"><div class="search-btn" @click="searchBtn">搜索</div></div>',
    props: ["placeholder","CapitalizationTest"],
    data: function () {
        return {
            searchInfo:null,
        }
    },
    watch: {
    },
    computed: {
    },
    methods: {
        searchBtn:function(){
            // 通知父级搜索并返回搜索内容
            this.$parent.recvSearchInfo(this.searchInfo);
        },
    },
    created: function () {
        console.log(this.CapitalizationTest);
    }
});

 

Vue3/<script setup>

父控件:

<template>
    <div class="login-template">
        <!-- 弹窗 -->
        <TipsDialogA :showFlag="tipsDialogAInfo.showFlag" :typeStaus="tipsDialogAInfo.typeStaus" :msgText="tipsDialogAInfo.msgText" @child-event="childEmitEvent"></TipsDialogA>
    </div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import {checkIsNullOrEmpty} from "@/assets/publicJS";
import TipsDialogA from './TipsDialogA.vue';

const tipsDialogAInfo=ref({
    showFlag:false,  // 是否显示
    typeStaus:-1,  // 错误类型
    msgText: "",  // 错误信息
});

// 该函数的作用是提供给子控件访问
const childEmitEvent=(data)=>{
    console.log("接收到子控件传递过来的参数:"+data);
};

const getSecCodeFunc=async()=>{
    tipsDialogAInfo.value.typeStaus=3;
    tipsDialogAInfo.value.msgText="弹出提示!";
    tipsDialogAInfo.value.showFlag=true;
    console.log(tipsDialogAInfo.value);
};
onMounted(()=>{
    console.log("==============");
    getSecCodeFunc();
});
</script>
<style lang="css" scoped>
</style>

 

子控件:

<template>
    <div class="tips-dialog-a-template" v-if="showFlag">
        <div style="display: flex;align-items: center;justify-content: center;">
            <div style="background-color: #fff;border-radius: 5px;">
                <div class="tips-dialog-a-img" :data-status="typeStaus"></div>
                <div class="tips-dialog-a-text" v-text="msgText"></div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { ref, watch,defineEmits } from 'vue';

const recvProps = defineProps({
    showFlag: Boolean,
    typeStaus: Number,
    msgText: String,
});

const parentEmit=defineEmits(["child-event"]);  // 访问父类的函数

/* 写法有误:
watch(recvProps.showFlag, (newValue, oldValue) => {
    console.log("触发watch");
});
 */
watch(() => recvProps.showFlag, (newValue, oldValue) => {
    console.log("触发watch");
    console.log(newValue, oldValue);
    if (newValue) {
        window.setTimeout(function () {
            console.log("访问父类的函数,并将showFlag信息传递过去");
            parentEmit("child-event",{"showFlag":false});
        }, 3000);
    }
});
</script>
<style lang="css" scoped>
</style>