美文网首页
Vue3/2 组件宽高比固定时基于宽度自适应的一种思路

Vue3/2 组件宽高比固定时基于宽度自适应的一种思路

作者: 跟着Damon写代码 | 来源:发表于2022-05-05 22:58 被阅读0次

    现实问题

    我们在写Vue组件时,我们希望当组件的父级宽度一定时,组件能根据固定的宽高比例进行自适应,或者一些背景的自适应,以提高组件的复用性。

    实现思路

    1. 在当前组件最外层元素设置ref
    2. 组件Props中传入参数width(当传入值为100% 父级组件存在宽度时,高度即是自适应。),并通过一个computed变量和v-bind方法绑定至最外层元素CSSwidth中。
    3. 在组件的onMounted生命周期中通过ref获取当前组件的clientWidth(此生命周期中,组件已渲染完毕)。再通过ref去修改style中的height达到一个宽高比固定的自适应。
    4. Vue2无法使用v-bind绑定CSS变量,但是可通过一个computed计算出样式和 :style绑定样式中。

    Vue3 + TS 实现代码

    此样例中的background也是通过传入的两个变量计算渐变获得。

    组件代码如下:

    <template>
    <!-- ref绑定 -->
    <div ref="card" class="card-container">
    
    </div>
    </template>
    
    <style lang="scss" scoped>
    .card-container {
        width: v-bind(width);  // 绑定width
        border-radius: 8px;
        background: v-bind(background);  // 绑定background
    }
    </style>
    
    <script lang="ts" setup>
    import { ref, onMounted, Ref, computed } from 'vue';
    
    const props = defineProps({
        // 传入高度
        width: {
            type: String,
            default: '200px'
        },
        // 背景渐变开始的颜色
        beginColor: {
            type: String,
            default: '#4996FF'
        },
        // 背景渐变结束的颜色,用于linear-gradient
        endColor: {
            type: String,
            default: '#358CFF'
        }
    })
    
    // 绑定HTML元素
    const card: Ref<null> | Ref<HTMLElement> = ref(null);
    
    // computed绑定传入宽度
    const width =  computed(() => {
        return props.width;
    })
    
    // computed 计算背景
    const background = computed(() => {
        return `linear-gradient(104.37deg,${props.beginColor} 4.7%, ${props.endColor} 100%)`;
    })
    
    onMounted(() => {
        if(!card.value ) return
        // 获取渲染完成的元素宽度
        const nowWidth = (card as Ref<HTMLElement>).value.clientWidth;
        // 更改元素高度,此处比例 16 : 9
        (card as Ref<HTMLElement>).value.style.height = `${nowWidth / 16 * 9}px`;
    })
    
    </script>
    

    代码效果

    测试代码:

    <template>
    <div class="width-fit-cards">
        <div v-for="(item,index) in 4" :style="{width: `${(index + 1) * 100}px`}" class="width-card" >
            <width-fit-card width="100%"/>
        </div>
    </div>
    </template>
    
    <style lang="scss" scoped>
    .width-fit-cards {
        display: flex;
        .width-card + .width-card {
            margin-left: 20px;
        }
    }
    </style>
    
    <script lang="ts" setup>
    // 引入组件
    import widthFitCard from './widthFitCard.vue';
    
    </script>
    

    测试效果

    测试效果.png

    Vue2

    Vue2通过以下代码绑定CSS样式:

     computed: {
            getCardStyle() {
                return {
                    width: this.width
                }
            }
        }
    
    <div :style="getCardStyle" ref="card" class="card-container">
    </div>
    

    具体可以自行实现

    相关文章

      网友评论

          本文标题:Vue3/2 组件宽高比固定时基于宽度自适应的一种思路

          本文链接:https://www.haomeiwen.com/subject/phxayrtx.html