手摸手之JSX card卡片组件

162 阅读1分钟

card 卡片

  • 相对其他一些组件比较简单,但是也有一些内在天地。

前置知识

开始

  • 新建一个card.tsx 文件 jsx 也可以大差不差
  • 我们考虑下一个card组件有什么? 需要什么? 这里直接看 element-plus card组件的参数。如下图所示,接收了三个参数,也就意味着组件的 props 有三个 分别是
    • header 设置 header
    • body-styl 设置 body 的样式
    • shadow 设置阴影显示时机

image.png

  • 然后可以看出 组件实际接收两个插槽, 一个是默认插槽, 一个是 header 插槽。

实现

  • 比较简单 直接上代码了
import { defineComponent, computed } from 'vue'
import './indenx.scss'

export default defineComponent({
  name: 'card',
  props: {
    shadow: {
      type: String,
      default: 'always'
    },
    header: { // title
      type: String,
      default: ''
    },
    bodyStyle: {
      type: [String, Object, Array],
      default: ''
    }
  },
  setup (props, { slots }) {
    const boxClass = `card-box is-${props.shadow}-shadow`

    const isHeader = computed(() => {
      return props.header || slots.header
    })

    return () => (
      <div class={ boxClass }>
        <div class='card-header' v-show={isHeader}>
          { (slots.header && slots.header()) || props.header /* title 具名插槽 */}
        </div>
        <div class='card-body' style={ props.bodyStyle }>
          { slots.default && slots.default()/* 默认插槽 */ },
        </div>
      </div>
    )
  }
})
  • css
// 练习组件样式 以组件名字-类型开头
.card-box {
  background: white;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  overflow: hidden;
  color: #303133;
  transition: .3s;

  .card-header{
    padding: 18px 20px;
    border-bottom: 1px solid #ebeef5;
    box-sizing: border-box;
  }

  .card-body{
    padding: 20px;
  }
}

.is-always-shadow{
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%)
}

.is-hover-shadow:hover{
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%)
}

.is-always-shadow{}

总结

  • 原来 style 可以是数组 长知识的一天😁