基于vue3.2 语法糖 <script setup> 仿 flutter Card 组件封装

158 阅读1分钟

1. 需求来源

业务中需要类似 flutter Card 的效果插件,基于 vue3.2 的学习自之后,基本达到高复用,低耦合的需求,支持:

const props = defineProps({
    /// 标题
    headerTitle: {
        type: String,
        default: undefined
    },
    /// 标题字体 css font
    headerFont: {
        type: String,
        default: "large PingFangSC-Regular"
    },
    /// 标题颜色 css color
    headerColor: {
        type: String,
        default: "#000000",
    },
    /// 标尾
    footerTitle: {
        type: String,
        default: undefined
    },

    /// 标尾 css font
    footerFont: {
        type: String,
        default: "smaller PingFangSC-Regular"
    },
    /// 标尾颜色 css color
    footerColor: {
        type: String,
        default: "#000000",
    },

    /// css margin
    margin: {
        type: String,
        default: "8px"
    },
    /// css padding
    padding: {
        type: String,
        default: "8px"
    },
    /// css border-radius
    borderRadius: {
        type: String,
        default: "4px"
    },
    /// css background-color
    backgroundColor: {
        type: String,
        default: "white",
    },
    /// css box-shadow
    boxShadow: {
        type: String,
        default: "0px 4px 18px 0px rgba(0,0,0,0.08)",
    },
    ///裁剪 css overflow
    overflow: {
        type: String,
        default: "hidden",
    },
})

实现效果如下:

vcard.png

2. 效果图使用示例:

<template>
  <div class='container'>
    <vcard
      :margin="'12px'" 
      :padding="'19px 8px 19px'" 
      :borderRadius="'8px'"
      :headerTitle="'headerTitle'"
      :footerTitle="'footerTitle'"
    >
      <!-- <template #header>
          <h2>VCard slot header: template #header</h2>
      </template> -->
      <template #default>
          <p>VCard slot: template #default</p>
      </template>
      <!-- <template #footer>
          <p>VCard slot footer: template #footer</p>
      </template> -->
  </vcard>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue';
import vcard from '@/components/VCard.vue';

</script>

3. 源码文件: VCard.vue

<template>
    <div class="card">
        <div>
            <slot name="header">
                <div class="header" v-if="headerTitle">{{headerTitle}}</div>
            </slot>
        </div>
        <div>
            <slot></slot>
        </div>
        <div>
            <slot name="footer">
                <div class="footer" v-if="footerTitle">{{footerTitle}}</div>
            </slot>
        </div>
    </div>
</template>


<script setup>
import { ref, getCurrentInstance, defineProps } from 'vue';

const props = defineProps({
    /// 标题
    headerTitle: {
        type: String,
        default: undefined
    },
    /// 标题字体 css font
    headerFont: {
        type: String,
        default: "large PingFangSC-Regular"
    },
    /// 标题字体 css color
    headerColor: {
        type: String,
        default: "#000000",
    },
    /// 标尾
    footerTitle: {
        type: String,
        default: undefined
    },

    /// 标尾 css font
    footerFont: {
        type: String,
        default: "smaller PingFangSC-Regular"
    },
    /// 标尾 css color
    footerColor: {
        type: String,
        default: "#000000",
    },

    /// css margin
    margin: {
        type: String,
        default: "8px"
    },
    /// css padding
    padding: {
        type: String,
        default: "8px"
    },
    /// css border-radius
    borderRadius: {
        type: String,
        default: "4px"
    },
    /// css background-color
    backgroundColor: {
        type: String,
        default: "white",
    },
    /// css box-shadow
    boxShadow: {
        type: String,
        default: "0px 4px 18px 0px rgba(0,0,0,0.08)",
    },
    ///裁剪 css overflow
    overflow: {
        type: String,
        default: "hidden",
    },
})

</script>


<style scoped>
.card{
    /* background-color: green;; */
    background-color: v-bind(backgroundColor);
    border-radius: v-bind(borderRadius);

    margin: v-bind(margin);
    padding: v-bind(padding);

    /* box-shadow: 0px 4px 8px 0px rgba(0,0,0,0.08); */
    box-shadow: v-bind(boxShadow);

    overflow: v-bind(overflow);
}

.header{
    color: v-bind(headerColor);
    font: v-bind(headerFont);
}

.footer{
    color: v-bind(footerColor);
    font: v-bind(footerFont);
}

</style>

最后:props 属性 也是来自 css, 一目了然;