Vue3列表(List)

news2024/9/22 10:24:40

效果如下图:在线预览

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

APIs

List

参数说明类型默认值
bordered是否展示边框booleanfalse
vertical是否使用竖直样式booleanfalse
split是否展示分割线booleantrue
size列表尺寸‘small’ | ‘middle’ | ‘large’‘middle’
loading是否加载中booleanfalse
hoverable是否显示悬浮样式booleanfalse
header列表头部string | slotundefined
footer列表底部string | slotundefined
spinPropsSpin 组件属性配置,参考 Spin Props,用于配置列表加载中样式object{}
emptyPropsEmpty 组件属性配置,参考 Empty Props,用于配置暂无数据样式object{}
showPagination是否显示分页booleanfalse
paginationPagination 组件属性配置,参考 Pagination Props,用于配置分页功能object{}

ListItem

参数说明类型默认值
avatar列表元素的图标字符string | slotundefined
avatarPropsAvatar 组件属性配置,参考 Avatar Props,用于配置列表图标样式object{}
title列表元素的标题string | slotundefined
description列表元素的描述内容string | slotundefined
actions列表操作组slotundefined
extra额外内容,展示在列表右侧string | slotundefined
avatarStyle设置图标的样式CSSProperties{}
titleStyle设置标题的样式CSSProperties{}
descriptionStyle设置描述内容的样式CSSProperties{}
contentStyle设置内容的样式CSSProperties{}
actionsStyle设置操作区域的样式CSSProperties{}
extraStyle设置额外内容的样式CSSProperties{}

创建 List.vue 组件

其中引入使用了以下组件:

  • [Vue3加载中(Spin)]((https://blog.csdn.net/Dandrose/article/details/129989730)
  • Vue3空状态(Empty)
  • Vue3分页(Pagination)
<script setup lang="ts">
import { computed, useSlots } from 'vue'
import Spin from '../spin'
import Empty from '../empty'
import Pagination from '../pagination'
interface Props {
  bordered?: boolean // 是否展示边框
  vertical?: boolean // 是否使用竖直样式
  split?: boolean // 是否展示分割线
  size?: 'small' | 'middle' | 'large' // 列表尺寸
  loading?: boolean // 是否加载中
  hoverable?: boolean // 是否显示悬浮样式
  header?: string // 列表头部 string | slot
  footer?: string // 列表底部 string | slot
  spinProps?: object // Spin 组件属性配置,参考 Spin Props,用于配置列表加载中样式
  emptyProps?: object // Empty 组件属性配置,参考 Empty Props,用于配置暂无数据样式
  showPagination?: boolean // 是否显示分页
  pagination?: object // Pagination 组件属性配置,参考 Pagination Props,用于配置分页功能
}
const props = withDefaults(defineProps<Props>(), {
  bordered: false,
  vertical: false,
  split: true,
  size: 'middle',
  loading: false,
  hoverable: false,
  header: undefined,
  footer: undefined,
  spinProps: () => ({}),
  emptyProps: () => ({}),
  showPagination: false,
  pagination: () => ({})
})
const slots = useSlots()
const showHeader = computed(() => {
  const headerSlots = slots.header?.()
  return Boolean(headerSlots && headerSlots?.length) || props.header
})
const showDefault = computed(() => {
  const defaultSlots = slots.default?.()
  return Boolean(defaultSlots && defaultSlots?.length && defaultSlots[0].children?.length)
})
const showFooter = computed(() => {
  const footerSlots = slots.footer?.()
  return Boolean(footerSlots && footerSlots?.length) || props.footer
})
</script>
<template>
  <Spin :spinning="loading" size="small" v-bind="spinProps">
    <div
      class="m-list"
      :class="{
        'list-bordered': bordered,
        'list-vertical': vertical,
        'list-split': split,
        'list-small': size === 'small',
        'list-large': size === 'large',
        'list-hoverable': hoverable
      }"
    >
      <div class="m-list-header" v-if="showHeader">
        <slot name="header">{{ header }}</slot>
      </div>
      <slot v-if="showDefault"></slot>
      <div class="m-list-empty" v-else>
        <Empty image="outlined" v-bind="emptyProps" />
      </div>
      <div class="m-list-footer" v-if="showFooter">
        <slot name="footer">{{ footer }}</slot>
      </div>
      <div class="m-list-pagination" v-if="showPagination">
        <Pagination placement="right" v-bind="pagination" />
      </div>
    </div>
  </Spin>
</template>
<style lang="less" scoped>
.m-list {
  margin: 0;
  position: relative;
  color: rgba(0, 0, 0, 0.88);
  font-size: 14px;
  line-height: 1.5714285714285714;
  .m-list-header,
  .m-list-footer {
    background: transparent;
    padding: 12px 0;
    transition: all 0.3s;
  }
  .m-list-empty {
    padding: 16px;
  }
  .m-list-pagination {
    margin-top: 24px;
  }
}
.list-bordered {
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  .m-list-header,
  :deep(.m-list-item),
  .m-list-footer {
    padding-inline: 24px;
  }
  .m-list-pagination {
    margin: 16px 24px;
  }
}
.list-vertical {
  :deep(.m-list-item) {
    align-items: initial;
    .m-list-item-main {
      display: block;
      .m-list-item-meta {
        margin-bottom: 16px;
        .m-list-item-content {
          .list-item-title {
            margin-bottom: 12px;
            color: rgba(0, 0, 0, 0.88);
            font-size: 16px;
            font-weight: 700;
            line-height: 1.5;
          }
        }
      }
      .list-item-actions {
        margin-top: 16px;
        margin-left: auto;
        & > * {
          padding: 0 16px;
          &:first-child {
            padding-left: 0;
          }
        }
      }
    }
  }
}
.list-split {
  .m-list-header {
    border-bottom: 1px solid rgba(5, 5, 5, 0.06);
  }
  :deep(.m-list-item) {
    &:not(:last-child) {
      border-bottom: 1px solid rgba(5, 5, 5, 0.06);
    }
  }
}
.list-small {
  :deep(.m-list-item) {
    padding: 8px 16px;
  }
}
.list-bordered.list-small {
  .m-list-header,
  :deep(.m-list-item),
  .m-list-footer {
    padding: 8px 16px;
  }
}
.list-large {
  :deep(.m-list-item) {
    padding: 16px 24px;
  }
}
.list-bordered.list-large {
  .m-list-header,
  :deep(.m-list-item),
  .m-list-footer {
    padding: 16px 24px;
  }
}
.list-hoverable {
  :deep(.m-list-item) {
    &:hover {
      background-color: rgba(0, 0, 0, 0.02);
    }
  }
}
</style>

创建 ListItem.vue 组件

其中引入使用了以下组件:

  • Vue3头像(Avatar)
<script setup lang="ts">
import { computed, useSlots } from 'vue'
import type { CSSProperties, Slot } from 'vue'
import Avatar from '../avatar'
interface Props {
  avatar?: string // 列表元素的图标字符 string | slot
  avatarProps?: object // Avatar 组件属性配置,参考 Avatar Props,用于配置列表图标样式
  title?: string // 列表元素的标题 string | slot
  description?: string // 列表元素的描述内容 string | slot
  actions?: Slot // 列表操作组 slot
  extra?: string // 额外内容,额外内容,展示在列表右侧 string | slot
  avatarStyle?: CSSProperties // 设置图标的样式
  titleStyle?: CSSProperties // 设置标题的样式
  descriptionStyle?: CSSProperties // 设置描述内容的样式
  contentStyle?: CSSProperties // 设置内容的样式
  actionsStyle?: CSSProperties // 设置操作区域的样式
  extraStyle?: CSSProperties // 设置额外内容的样式
}
const props = withDefaults(defineProps<Props>(), {
  avatar: undefined,
  avatarProps: () => ({}),
  title: undefined,
  description: undefined,
  actions: undefined,
  extra: undefined,
  avatarStyle: () => ({}),
  titleStyle: () => ({}),
  descriptionStyle: () => ({}),
  contentStyle: () => ({}),
  actionsStyle: () => ({}),
  extraStyle: () => ({})
})
const slots = useSlots()
const showAvatar = computed(() => {
  const avatarSlots = slots.avatar?.()
  return Boolean(avatarSlots && avatarSlots?.length) || props.avatar || JSON.stringify(props.avatarProps) !== '{}'
})
const showContent = computed(() => {
  const titleSlots = slots.title?.()
  const descriptionSlots = slots.description?.()
  let n = 0
  if (titleSlots && titleSlots?.length) {
    n++
  }
  if (descriptionSlots && descriptionSlots?.length) {
    n++
  }
  return Boolean(n) || props.title || props.description
})
const showDefault = computed(() => {
  const defaultSlots = slots.default?.()
  return Boolean(defaultSlots && defaultSlots?.length)
})
const showActions = computed(() => {
  const actionsSlots = slots.actions?.()
  return Boolean(actionsSlots && actionsSlots?.length)
})
const showExtra = computed(() => {
  const extraSlots = slots.extra?.()
  return Boolean(extraSlots && extraSlots?.length) || props.extra
})
</script>
<template>
  <div class="m-list-item">
    <div class="m-list-item-main">
      <div class="m-list-item-meta" v-if="showAvatar || showContent">
        <div class="m-list-item-avatar" v-if="showAvatar" :style="avatarStyle">
          <slot name="avatar">
            <Avatar v-bind="avatarProps">{{ avatar }}</Avatar>
          </slot>
        </div>
        <div class="m-list-item-content" v-if="showContent">
          <p class="list-item-title" :style="titleStyle">
            <slot name="title">{{ title }}</slot>
          </p>
          <div class="list-item-description" :style="descriptionStyle">
            <slot name="description">{{ description }}</slot>
          </div>
        </div>
      </div>
      <div v-if="showDefault" :style="contentStyle">
        <slot></slot>
      </div>
      <div class="list-item-actions" v-if="showActions" :style="actionsStyle">
        <slot name="actions"></slot>
      </div>
    </div>
    <div class="list-item-extra" v-if="showExtra" :style="extraStyle">
      <slot name="extra">{{ extra }}</slot>
    </div>
  </div>
</template>
<style lang="less" scoped>
.m-list-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 24px;
  color: rgba(0, 0, 0, 0.88);
  max-width: 100%;
  transition: all 0.3s;
  .m-list-item-main {
    display: flex;
    align-items: center;
    flex: 1;
    .m-list-item-meta {
      display: flex;
      flex: 1;
      align-items: flex-start;
      max-width: 100%;
      .m-list-item-avatar {
        margin-right: 16px;
      }
      .m-list-item-content {
        flex: 1 0;
        width: 0;
        color: rgba(0, 0, 0, 0.88);
        .list-item-title {
          margin-bottom: 4px;
          color: rgba(0, 0, 0, 0.88);
          font-size: 14px;
          font-weight: 700;
          line-height: 1.5714285714285714;
          :deep(a) {
            font-weight: 700;
            color: rgba(0, 0, 0, 0.88);
            transition: all 0.3s;
            &:hover {
              color: @themeColor;
            }
          }
        }
        .list-item-description {
          color: rgba(0, 0, 0, 0.45);
          font-size: 14px;
          line-height: 1.5714285714285714;
        }
      }
    }
    .list-item-actions {
      flex: 0 0 auto;
      margin-left: 48px;
      font-size: 0;
      & > * {
        // 选择所有直接子元素,不包括深层的后代
        position: relative;
        display: inline-flex;
        align-items: center;
        padding: 0 8px;
        color: rgba(0, 0, 0, 0.45);
        font-size: 14px;
        line-height: 1.5714285714285714;
        text-align: center;
        &:first-child {
          padding-left: 0;
        }
        &:not(:last-child) {
          &::after {
            position: absolute;
            top: 50%;
            right: 0;
            width: 1px;
            height: 14px;
            transform: translateY(-50%);
            background-color: rgba(5, 5, 5, 0.06);
            content: '';
          }
        }
      }
      & > :deep(a) {
        // 选择所有直接子元素且是 a 标签
        color: @themeColor;
        transition: color 0.3s;
        &:hover {
          color: #4096ff;
        }
      }
    }
  }
  .list-item-extra {
    margin-left: 24px;
  }
}
</style>

其中引入使用了以下组件:

  • Vue3头像(Avatar)
  • Vue3开关(Switch)
  • Vue3单选框(Radio)
  • Vue3弹性布局(Flex)
  • Vue3栅格(Grid)
  • Vue3间距(Space)
  • Vue3输入框(Input)

在要使用的页面引入

<script setup lang="ts">
import List from './List.vue'
import ListItem from './ListItem.vue'
import { ref, reactive } from 'vue'
const listData = ref([
  {
    title: 'Vue Amazing UI Title 1',
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content: 'content'
  },
  {
    title: 'Vue Amazing UI Title 2',
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content: 'content'
  },
  {
    title: 'Vue Amazing UI Title 3',
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content: 'content'
  },
  {
    title: 'Vue Amazing UI Title 4',
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content: 'content'
  }
])
const bordered = ref(true)
const simpleList = ref([
  'Vue Amazing UI is developed using TypeScript',
  'An Amazing Vue3 UI Components Library',
  'Streamline web development with Vue Amazing UI',
  'Incredible Vue components for modern web design',
  'Transform your Vue interface with Vue Amazing UI'
])
const sizeOptions = [
  {
    label: 'small',
    value: 'small'
  },
  {
    label: 'middle',
    value: 'middle'
  },
  {
    label: 'large',
    value: 'large'
  }
]
const size = ref('middle')
const loading = ref(true)
const allListData = ref<any[]>([])
for (let i = 1; i <= 8; i++) {
  allListData.value.push({
    href: 'https://themusecatcher.github.io/vue-amazing-ui/',
    title: `Vue Amazing UI part ${i}`,
    avatar: 'https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg',
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content:
      'Vue Amazing UI supplies streamline web development, incredible Vue components for modern web design and transform your Vue interface completely.'
  })
}
const paginationListData = ref<any[]>([])
paginationListData.value = allListData.value.slice(0, 3)
const pagination = {
  page: 1,
  pageSize: 3,
  total: 8,
  onChange: (page: number, pageSize: number) => {
    console.log('change page', page)
    console.log('change pageSize', pageSize)
    const start = (page - 1) * pageSize + 1
    const end = page * pageSize > 8 ? 8 : page * pageSize
    paginationListData.value = allListData.value.slice(start - 1, end)
  }
}
const allConfigListData = ref<ang[]>([])
for (let i = 1; i <= 30; i++) {
  allConfigListData.value.push({
    href: 'https://themusecatcher.github.io/vue-amazing-ui/',
    title: `Vue Amazing UI Title ${i}`,
    description: 'Vue Amazing UI, An Amazing Vue3 UI Components Library.',
    content: 'Incredible Vue components for modern web design'
  })
}
const configListData = ref<any[]>([])
configListData.value = allConfigListData.value.slice(0, 5)
const state = reactive({
  bordered: true,
  vertical: false,
  split: true,
  size: 'middle',
  loading: false,
  hoverable: true,
  header: 'list header',
  footer: 'list footer',
  extra: 'extra',
  showPagination: true,
  pagination: {
    page: 1,
    pageSize: 5,
    total: 30,
    showTotal: (total: number, range: number[]) => `${range[0]}-${range[1]} of ${total} items`,
    showSizeChanger: true,
    showQuickJumper: true,
    onChange: (page: number, pageSize: number) => {
      console.log('change page', page)
      console.log('change pageSize', pageSize)
      const start = (page - 1) * pageSize + 1
      const end = page * pageSize > state.pagination.total ? state.pagination.total : page * pageSize
      configListData.value = allConfigListData.value.slice(start - 1, end)
    }
  }
})
</script>
<template>
  <div>
    <h1>{{ $route.name }} {{ $route.meta.title }}</h1>
    <h2 class="mt30 mb10">基本使用</h2>
    <List>
      <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
        <template #avatar>
          <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
        </template>
        <template #description>
          {{ data.description }}
        </template>
      </ListItem>
    </List>
    <h2 class="mt30 mb10">隐藏分割线</h2>
    <List :split="false">
      <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
        <template #avatar>
          <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
        </template>
        <template #description>
          {{ data.description }}
        </template>
      </ListItem>
    </List>
    <h2 class="mt30 mb10">带边框列表</h2>
    <Flex vertical>
      <Space>
        <Switch v-model="bordered" />
      </Space>
      <List :bordered="bordered">
        <template #header>
          <div>Header</div>
        </template>
        <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
          <template #avatar>
            <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
          </template>
          <template #description>
            {{ data.description }}
          </template>
        </ListItem>
        <template #footer>
          <div>Footer</div>
        </template>
      </List>
    </Flex>
    <h2 class="mt30 mb10">三种尺寸</h2>
    <Flex vertical>
      <Radio :options="sizeOptions" v-model:value="size" button button-style="solid" />
      <Row :gutter="32">
        <Col :span="12">
          <List bordered :size="size">
            <ListItem v-for="(data, index) in listData" :key="index">
              <template #avatar>
                <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
              </template>
              <template #title>
                <a href="https://themusecatcher.github.io/vue-amazing-ui/">{{ data.title }}</a>
              </template>
              <template #description>
                {{ data.description }}
              </template>
            </ListItem>
          </List>
        </Col>
        <Col :span="12">
          <List bordered :size="size">
            <template #header>
              <div>Header</div>
            </template>
            <ListItem v-for="(data, index) in simpleList" :key="index">
              {{ data }}
            </ListItem>
            <template #footer>
              <div>Footer</div>
            </template>
          </List>
        </Col>
      </Row>
    </Flex>
    <h2 class="mt30 mb10">加载中</h2>
    <Flex vertical>
      <Space> Loading state:<Switch v-model="loading" /> </Space>
      <Row :gutter="32">
        <Col :span="12">
          <List bordered :loading="loading">
            <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
              <template #avatar>
                <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
              </template>
              <template #description>
                {{ data.description }}
              </template>
            </ListItem>
          </List>
        </Col>
        <Col :span="12">
          <List bordered :loading="loading" :spin-props="{ indicator: 'dynamic-circle' }">
            <template #header>
              <div>Header</div>
            </template>
            <ListItem v-for="(data, index) in simpleList" :key="index">
              {{ data }}
            </ListItem>
            <template #footer>
              <div>Footer</div>
            </template>
          </List>
        </Col>
      </Row>
    </Flex>
    <h2 class="mt30 mb10">暂无数据</h2>
    <List>
      <ListItem v-for="(data, index) in []" :key="index"></ListItem>
    </List>
    <h2 class="mt30 mb10">显示悬浮样式</h2>
    <Row :gutter="32">
      <Col :span="12">
        <List bordered hoverable>
          <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
            <template #avatar>
              <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
            </template>
            <template #description>
              {{ data.description }}
            </template>
          </ListItem>
        </List>
      </Col>
      <Col :span="12">
        <List bordered hoverable>
          <template #header>
            <div>Header</div>
          </template>
          <ListItem v-for="(data, index) in simpleList" :key="index">
            {{ data }}
          </ListItem>
          <template #footer>
            <div>Footer</div>
          </template>
        </List>
      </Col>
    </Row>
    <h2 class="mt30 mb10">列表添加操作项</h2>
    <List>
      <ListItem v-for="(data, index) in listData" :key="index" :title="data.title">
        <template #avatar>
          <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
        </template>
        <template #description>
          {{ data.description }}
        </template>
        {{ data.content }}
        <template #actions>
          <a>edit</a>
          <a>more</a>
        </template>
      </ListItem>
    </List>
    <h2 class="mt30 mb10">自定义样式</h2>
    <List>
      <ListItem
        :avatar-props="{
          src: 'https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg',
          size: 60
        }"
        :avatar-style="{ alignSelf: 'center' }"
        :title-style="{ fontSize: '20px' }"
        :description-style="{ fontSize: '16px' }"
        :content-style="{ fontSize: '18px', color: '#f50', marginLeft: '16px' }"
        :extra-style="{ overflow: 'hidden', borderRadius: '12px' }"
        v-for="(data, index) in listData"
        :key="index"
        :title="data.title"
      >
        <template #description>
          {{ data.description }}
        </template>
        {{ data.content }}
        <template #actions>
          <a>edit</a>
          <a>more</a>
        </template>
        <template #extra>
          <img
            class="u-img"
            width="200"
            alt="extra"
            src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/2.jpg"
          />
        </template>
      </ListItem>
    </List>
    <h2 class="mt30 mb10">竖排分页列表</h2>
    <List vertical size="large" show-pagination :pagination="pagination">
      <ListItem v-for="(data, index) in paginationListData" :key="index">
        <template #title>
          <a :href="data.href" target="_blank">{{ data.title }}</a>
        </template>
        <template #avatar>
          <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
        </template>
        <template #description>
          {{ data.description }}
        </template>
        {{ data.content }}
        <template #actions>
          <span>
            <svg
              class="u-svg"
              focusable="false"
              data-icon="star"
              width="1em"
              height="1em"
              fill="currentColor"
              aria-hidden="true"
              viewBox="64 64 896 896"
            >
              <path
                d="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3zM664.8 561.6l36.1 210.3L512 672.7 323.1 772l36.1-210.3-152.8-149L417.6 382 512 190.7 606.4 382l211.2 30.7-152.8 148.9z"
              ></path>
            </svg>
            156
          </span>
          <span>
            <svg
              class="u-svg"
              focusable="false"
              data-icon="like"
              width="1em"
              height="1em"
              fill="currentColor"
              aria-hidden="true"
              viewBox="64 64 896 896"
            >
              <path
                d="M885.9 533.7c16.8-22.2 26.1-49.4 26.1-77.7 0-44.9-25.1-87.4-65.5-111.1a67.67 67.67 0 00-34.3-9.3H572.4l6-122.9c1.4-29.7-9.1-57.9-29.5-79.4A106.62 106.62 0 00471 99.9c-52 0-98 35-111.8 85.1l-85.9 311H144c-17.7 0-32 14.3-32 32v364c0 17.7 14.3 32 32 32h601.3c9.2 0 18.2-1.8 26.5-5.4 47.6-20.3 78.3-66.8 78.3-118.4 0-12.6-1.8-25-5.4-37 16.8-22.2 26.1-49.4 26.1-77.7 0-12.6-1.8-25-5.4-37 16.8-22.2 26.1-49.4 26.1-77.7-.2-12.6-2-25.1-5.6-37.1zM184 852V568h81v284h-81zm636.4-353l-21.9 19 13.9 25.4a56.2 56.2 0 016.9 27.3c0 16.5-7.2 32.2-19.6 43l-21.9 19 13.9 25.4a56.2 56.2 0 016.9 27.3c0 16.5-7.2 32.2-19.6 43l-21.9 19 13.9 25.4a56.2 56.2 0 016.9 27.3c0 22.4-13.2 42.6-33.6 51.8H329V564.8l99.5-360.5a44.1 44.1 0 0142.2-32.3c7.6 0 15.1 2.2 21.1 6.7 9.9 7.4 15.2 18.6 14.6 30.5l-9.6 198.4h314.4C829 418.5 840 436.9 840 456c0 16.5-7.2 32.1-19.6 43z"
              ></path>
            </svg>
            156
          </span>
          <span>
            <svg
              class="u-svg"
              focusable="false"
              data-icon="message"
              width="1em"
              height="1em"
              fill="currentColor"
              aria-hidden="true"
              viewBox="64 64 896 896"
            >
              <path
                d="M464 512a48 48 0 1096 0 48 48 0 10-96 0zm200 0a48 48 0 1096 0 48 48 0 10-96 0zm-400 0a48 48 0 1096 0 48 48 0 10-96 0zm661.2-173.6c-22.6-53.7-55-101.9-96.3-143.3a444.35 444.35 0 00-143.3-96.3C630.6 75.7 572.2 64 512 64h-2c-60.6.3-119.3 12.3-174.5 35.9a445.35 445.35 0 00-142 96.5c-40.9 41.3-73 89.3-95.2 142.8-23 55.4-34.6 114.3-34.3 174.9A449.4 449.4 0 00112 714v152a46 46 0 0046 46h152.1A449.4 449.4 0 00510 960h2.1c59.9 0 118-11.6 172.7-34.3a444.48 444.48 0 00142.8-95.2c41.3-40.9 73.8-88.7 96.5-142 23.6-55.2 35.6-113.9 35.9-174.5.3-60.9-11.5-120-34.8-175.6zm-151.1 438C704 845.8 611 884 512 884h-1.7c-60.3-.3-120.2-15.3-173.1-43.5l-8.4-4.5H188V695.2l-4.5-8.4C155.3 633.9 140.3 574 140 513.7c-.4-99.7 37.7-193.3 107.6-263.8 69.8-70.5 163.1-109.5 262.8-109.9h1.7c50 0 98.5 9.7 144.2 28.9 44.6 18.7 84.6 45.6 119 80 34.3 34.3 61.3 74.4 80 119 19.4 46.2 29.1 95.2 28.9 145.8-.6 99.6-39.7 192.9-110.1 262.7z"
              ></path>
            </svg>
            6
          </span>
        </template>
        <template #extra>
          <img
            class="u-img"
            width="272"
            alt="extra"
            src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
          />
        </template>
      </ListItem>
      <template #footer>
        <div>
          <b>Vue Amazing UI</b>
          footer part
        </div>
      </template>
    </List>
    <h2 class="mt30 mb10">列表配置器</h2>
    <Flex gap="large" vertical>
      <Row :gutter="[24, 12]">
        <Col :span="6">
          <Space gap="small" vertical> bordered:<Switch v-model="state.bordered" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> vertical:<Switch v-model="state.vertical" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> split:<Switch v-model="state.split" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical>
            size:<Radio :options="sizeOptions" v-model:value="state.size" button button-style="solid" />
          </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> loading:<Switch v-model="state.loading" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> hoverable:<Switch v-model="state.hoverable" /> </Space>
        </Col>
        <Col :span="6">
          <Flex gap="small" vertical> header:<Input v-model:value="state.header" placeholder="header" /> </Flex>
        </Col>
        <Col :span="6">
          <Flex gap="small" vertical> footer:<Input v-model:value="state.footer" placeholder="footer" /> </Flex>
        </Col>
        <Col :span="6">
          <Flex gap="small" vertical> extra:<Input v-model:value="state.extra" placeholder="extra" /> </Flex>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> showPagination:<Switch v-model="state.showPagination" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> showSizeChanger:<Switch v-model="state.pagination.showSizeChanger" /> </Space>
        </Col>
        <Col :span="6">
          <Space gap="small" vertical> showQuickJumper:<Switch v-model="state.pagination.showQuickJumper" /> </Space>
        </Col>
      </Row>
      <List
        :bordered="state.bordered"
        :vertical="state.vertical"
        :split="state.split"
        :size="state.size"
        :loading="state.loading"
        :hoverable="state.hoverable"
        :header="state.header"
        :footer="state.footer"
        :showPagination="state.showPagination"
        :pagination="state.pagination"
      >
        <ListItem v-for="(data, index) in configListData" :key="index" :extra="state.extra">
          <template #title>
            <a :href="data.href" target="_blank">{{ data.title }}</a>
          </template>
          <template #avatar>
            <Avatar src="https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/1.jpg" />
          </template>
          <template #description>
            {{ data.description }}
          </template>
          {{ data.content }}
        </ListItem>
      </List>
    </Flex>
  </div>
</template>
<style lang="less" scoped>
.u-img {
  display: inline-block;
  vertical-align: bottom;
}
.u-svg {
  margin-right: 8px;
  fill: rgba(0, 0, 0, 0.45);
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2042054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql写个分区表

因为表量已经达到1个亿了。现在想做个优化&#xff0c;先按照 create_time 时间进行分区吧。 create_time 是varchar类型。 CREATE TABLE orders (id varchar(40) NOT NULL ,order_no VARCHAR(20) NOT NULL,create_time VARCHAR(20) NOT NULL,amount DECIMAL(10,2) NOT NULL,…

Unity如何使用Spine动画导出的动画

Unity如何使用Spine动画导出的动画 介绍使用版本Spine导出源文件修改Spine3.8.75版本导入Unity的3.8版本Spine的报错Unity辅助修改Json中版本号方式总结 介绍 最近公司在做抖音小程序的小游戏&#xff0c;我们这边动画部分使用的是spine动画&#xff0c;所以会有spine导入的问…

IDEA使用LiveTemplate快速生成方法注释

本文目标&#xff1a;开发人员&#xff0c;在了解利用Live Template动态获取方法输入输出参数、创建日期时间方法的条件下&#xff0c;进行自动生成方法注释&#xff0c;达到自动添加方法注释的程度&#xff1b; 文章目录 1 场景2 要点2.1 新增LiveTemplate模版2.2 模版内容填写…

FFMPEG推流器讲解

FFMPEG重要结构体的讲解 FFMPEG中有六个比较重要的结构体&#xff0c;分别是AVFormatContext、AVOutputFormat、 AVStream、AVCodec、AVCodecContext、AVPacket、AVFrame、AVIOContext结构体&#xff0c;这几个结构体是贯穿着整个FFMPEG核心功能。 AVFormatContext 这个结构…

基于web的大学生一体化服务平台的设计与实现

TOC springboot209基于web的大学生一体化服务平台的设计与实现 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人…

1、.Net UI框架:WinUI - .Net宣传系列文章

WinUI(Windows UI Library)是微软提供的一个用于构建Windows应用程序的本机UI平台组件。它与Windows应用SDK紧密相关&#xff0c;允许开发者创建适用于Windows 10及更高版本的应用程序&#xff0c;并且可以发布到Microsoft Store。WinUI 3是最新的一代&#xff0c;它提供了与操…

C# 中 Tuple 与 ValueTuples 之间的区别

在 C# 中&#xff0c;元组和值元组都用于在单个变量中存储多个值。但它们在语法、功能和性能方面存在一些关键差异。 一.Tuples(元组) 元组是一种引用类型&#xff0c;长期以来一直是 .NET 的一部分。它们是使用 System.Tuple 类创建的。 例子 using System; class Program…

养猫家庭必备好物?希喂、霍尼韦尔宠物空气净化器真实测评

随着宠物空气净化器的讨论度越来越高&#xff0c;我也被种草了这款产品。对养宠家庭来说&#xff0c;十分需要这样一款转专门针对宠物毛发清理的工具。准备入手前我在网上做了许多功课&#xff0c;经过一番筛选后&#xff0c;最后希喂、霍尼韦尔两个品牌成功晋级决赛。 在对比…

代理IP为什么不能使用免费代理IP地址?

在跨境业务中&#xff0c;营销人员、广告投手经常利用代理IP防止账号关联与封禁&#xff0c;并且在访问网站时可以隐匿真实 IP 地址&#xff0c;定位目标市场。代理服务器充当中间人掩盖真实的数字足迹&#xff0c;这不仅增强了隐私&#xff0c;也会跨境业务提效提供保障。但是…

基于STM32开发的智能语音助手系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 智能家居控制个人语音助理常见问题及解决方案 常见问题解决方案结论 1. 引言 随着人工智能技术的发展&#xff0c;智能语音助手已经逐渐进入了人们的日常生活。…

【轨物推荐】创新有规律,发明有方法

原创 赵敏 发明方法研究 2020年03月11日 10:38 各位业内朋友&#xff0c;大家好&#xff01; 今年的疫情&#xff0c;对所有的企业都会有冲击&#xff0c;给企业的业务开展带来很多困扰。详细很多企业都在出主意、想办法&#xff0c;设法把疫情造成的损失降到最低。即使在平时…

行业原型:智慧制造:注塑云管工厂

行业原型预览链接&#xff1a;&#xff08;请与班主任联系获取原型文档&#xff09; 文件类型&#xff1a;.rp 支持版本&#xff1a;Axrure RP 8 文档名称&#xff1a;智慧制造&#xff1a;注塑云管工厂 文件大小&#xff1a;1.80 MB 目录内容介绍 文档内容介绍 回复 “211…

均数(mean±SD)与RR/OR值可以合并进行Meta分析吗?

经常有小伙伴问&#xff1a;在做危险因素的Meta分析时&#xff0c;遇到一些文献比较的是病例组和对照组某一指标的均值差异&#xff0c;数据以meanSD形式呈现&#xff0c;而另一些文献则是以OR或RR (95%CI)的形式描述该指标与疾病的关联。这两种数据形式可以一起进行Meta分析吗…

每周心赏|用AI真的可以开挂式求职

马上就要到2024年的金九银十了&#xff0c;正是求职的好时机啊&#xff01; 万事开头难&#xff0c;找工作第一步自然是离不开制作简历了&#xff01; 都说简历是面试的敲门砖&#xff0c;所以大家都很重视。 你不是也曾游走在各大网站中搜寻模板、寻找“大能们”的简历来修…

海运如何实时了解货物的物流轨迹?有什么系统可以实现?

物流轨迹在散货集拼业务中扮演着至关重要的角色&#xff0c;它不仅让客户可以实时掌握货物动态&#xff0c;确保了货物的安全无虞与准时送达&#xff0c;还为企业提供了灵活调整运输策略的依据&#xff0c;有益于运输效率与可靠性的双重提升。同时&#xff0c;通过物流轨迹的即…

RC电路里,电容多久可以充满电

时间常数 τR*C&#xff0c;那么电容需要多久能充满电呢&#xff1f; 例如下图仿真&#xff0c;R1KΩ&#xff0c;C1uF&#xff0c;那么τR*C1ms。 2个时间常数2ms的时间&#xff0c;电容电压充到86% 3个时间常数3ms的时间&#xff0c;电容电压充到95% 通常定义95为充满电。…

前端实现视频流播放:封装一个可复用的HlsPlayer组件

简介 在前端开发中&#xff0c;播放视频流是一个常见的需求&#xff0c;尤其是在需要实时监控或直播的场景中。本文将分享如何封装一个基于hls.js库的Vue组件&#xff0c;以便在任何需要的地方快速引用和播放视频流。 环境准备 首先&#xff0c;确保你的项目中已经安装了Vue…

【整数规划】+【0—1规划】解决优化类问题(Matlab代码)

目录 文章目录 前言 一、整数规划 分类&#xff1a; 二、典例讲解 1.背包问题 2.指派问题 总结 前言 如果觉得本篇文章还不错的话&#xff0c;给作者点个赞鼓励一下吧&#x1f601;&#x1f601;&#x1f601; 在规划问题中&#xff0c;有些最优解可能是分数或小数&am…

SpringBoot教程(二十二) | SpringBoot实现分布式定时任务之elastic-job

SpringBoot教程&#xff08;二十二&#xff09; | SpringBoot实现分布式定时任务之elastic-job 简介前置条件&#xff1a;需要ZooKeeper配合1、引入相关依赖2、application.yml中配置注册中心和作业调度巨坑&#xff08;配置修改无效&#xff09;3、job实例4、ElasticJob-UI监控…

Ansible自动化运维中剧本角色(roles)来完成apache服务操作

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; Ansible…