1. 程式人生 > 其它 >vue 封裝元件時v-model的實現

vue 封裝元件時v-model的實現

技術標籤:Vuevue封裝元件

官方:一個元件上的 v-model 預設會利用名為 value 的 prop 和名為 input 的事件。

v-model實際上只是一個語法糖:

<input v-model="password">

作用與以下相似:

<input type="text" :value="password" @input="password=$event.target.value">

也就是通過v-model傳遞的值,最終是傳遞給了子元件props中value屬性,子元件修改value值需要通過觸發input事件並傳遞需要修改的值給父元件。

簡單的效果:

父元件Home.vue:

<template>
    <div class="home">
        <button @click="isShow=true">修改</button>
        <child v-model="isShow" title="修改暱稱"></child>
    </div>
</template>

<script>
    import child from '@/components/child.vue'
    export default {
        name: 'Home',
        components: {
            child
        },
        data() {
            return {
                isShow:true
            };
        },
        methods: {

        },
        mounted() {

        },
    }
</script>
<style lang="scss" scoped>
.home{
    position: absolute;
    width:100%;
    height:100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>

子元件Child.vue:

<template>
    <div>
        <div class="fullbg" v-if="value" @click="cannelPop()">
            <div class="fulltop" :class="{'bottom':type=='bottom','top':type!='bottom'}" @click.stop="">
                <div class="title" v-if="title">{{title}}</div>
                <slot></slot>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'child',
    components: {  },
    props:{
        //控制顯示與隱藏
        value:{
            type:Boolean,
            default:false
        },
        //彈窗型別,兩種:上和下
        type:{
            type:String,
            default:"top"
        },
        //彈窗標題,如果不給標題,那麼也不會顯示標題行
        title:{
            type:String,
            default:""
        }
    },
    data() {
        return {
        };
    },
    mounted() {
        
    },
    methods: {
        //點選黑色遮罩區域隱藏彈窗
        cannelPop(){
            this.$emit('input',false);    //通過觸發input去修改v-model的值
        }
    },
};
</script>

<style lang="scss" scoped>
.fullbg{
	position: fixed;
	z-index: 1000;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background: rgba(0,0,0,0.5);
}
.fulltop {
    position: fixed;
    z-index: 1001;
    left: 0;
    right: 0;
    margin: 0 auto;
    box-sizing: border-box;
    padding: 20px 10px 20px;
    background: #FFFFFF;
    max-height: 80vh;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}
.top{
	top:0;
}
.bottom{
	bottom:0;
}
.title{
    font-size: 16px;
    font-weight: bold;
    text-align: center;
}
</style>