Vue.js 构建高级卡片式界面

应用场景介绍

卡片式界面是一种流行的设计模式,广泛应用于电子商务、社交媒体和数据可视化等领域。它允许用户轻松浏览和管理信息,并提供交互式体验。

代码基本功能介绍

本文中的代码使用 Vue.js 框架构建了一个高级卡片式界面,具有以下功能:

  • 创建和管理卡片
  • 使用 ECharts 库绘制图表
  • 集成百度地图组件
  • 使用 WangEditor 富文本编辑器
  • 使用 v-calendar 库创建日历

功能实现步骤及关键代码分析说明

创建卡片

<template>
  <div class="bg-gray-100 h-screen">
    <div class="bg-white shadow-md rounded-lg p-4 max-w-sm mx-auto mt-10">
      <div class="flex justify-between items-center">
        <h1 class="text-2xl font-semibold text-gray-700">New Card</h1>
        <a-back-top />
      </div>
      <div class="mt-4">
        <div class="w-full">
          <div class="relative">
            <div class="absolute inset-0 rounded-lg shadow-sm" :style="{ 'background-image': `url(https://source.unsplash.com/random/300x150)` }"></div>
            <div class="absolute inset-0 rounded-lg bg-green-400 opacity-75"></div>
            <div class="relative px-5 py-3 flex items-center space-x-3">
              <div>
                <img src="https://source.unsplash.com/random/50x50" alt="" class="w-10 h-10 rounded-full" />
              </div>
              <div class="text-white">
                <h2 class="text-sm font-semibold">MoCard</h2>
                <p class="text-xs">Amazon</p>
              </div>
            </div>
          </div>
          <div class="mt-6">
            <div class="grid grid-cols-2 gap-4">
              <div>
                <label for="name" class="text-sm font-medium text-gray-700">Cardholder name</label>
                <input type="text" id="name" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" />
              </div>
              <div>
                <label for="card-number" class="text-sm font-medium text-gray-700">Card number</label>
                <input type="text" id="card-number" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" />
              </div>
              <div>
                <label for="expiry-date" class="text-sm font-medium text-gray-700">Expiry date</label>
                <input type="text" id="expiry-date" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" />
              </div>
              <div>
                <label for="cvv" class="text-sm font-medium text-gray-700">CVV</label>
                <input type="text" id="cvv" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-green-500 focus:border-green-500" />
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="mt-6 flex justify-end">
        <a-button type="primary" class="px-4 py-2 rounded-md shadow-sm">Add New Card</a-button>
      </div>
    </div>
  </div>
</template>
<script>
import { createComponent } from 'echarts-for-vue';
import { Calendar } from 'v-calendar';
import { BMap } from 'vue3-baidu-map-gl';
import { default as MessageOutlined } from '@ant-design/icons-vue/es/icons/MessageOutlined';
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { onBeforeUnmount, ref, shallowRef } from 'vue';

const ECharts = createComponent({echarts});

const editorConfig = ref({
  placeholder: '请输入内容...'
});
const editor = shallowRef();

const handleEditorCreated = (editorInstance) => {
  // Attach the editor instance to the ref
  editor.value = editorInstance;
  console.log("editor.value", editor.value, editorInstance)
};

onBeforeUnmount(() => {
  // Destroy the editor instance before the component is unmounted
  editor.value.destroy();
  editor.value = null;
});

const listData = [
  {
    title: 'Ant Design Title 1',
  },
  {
    title: 'Ant Design Title 2',
  },
  {
    title: 'Ant Design Title 3',
  },
];
</script>

绘制图表

<script>
import * as echarts from 'echarts';
import { h } from "vue";
import { createComponent } from 'echarts-for-vue';

const ECharts = createComponent({echarts, h});
</script>
<template>
  <div class="bg-gray-100 h-screen">
    <div class="bg-white shadow-md rounded-lg p-4 max-w-sm mx-auto mt-10">
      <div class="flex justify-between items-center">
        <h1 class="text-2xl font-semibold text-gray-700">ECharts Example</h1>
        <a-back-top />
      </div>
      <div class="mt-4">
        <div class="w-full">
          <ECharts
            :options="options"
            style="width: 100%; height: 300px;"
          />
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import * as echarts from 'echarts';
import { h } from "vue";
import { createComponent } from 'echarts-for-vue';

const ECharts = createComponent({echarts, h});

export default {
  components: { ECharts },
  data() {
    return {
      options: {
        title: {
          text: 'ECharts Example',
        },
        xAxis: {
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: [{
          data: [120, 200, 150, 80, 70, 110, 130],
          type: 'line',
        }],
      },
    };
  },
};
</script>

集成百度地图

<script>
import { BMap } from 'vue3-baidu-map-gl';
</script>
<template>
  <div class="bg-gray-100 h-screen">
    <div class="bg-white shadow-md rounded-lg p-4 max-w-sm mx-auto mt-10">
      <div class="flex justify-between items-center">
        <h1 class="text-2xl font-semibold text-gray-700">百度地图示例</h1>
        <a-back-top />
      </div>
      <div class="mt-4">
        <div class="w-full">
          <BMap
            style="width: 100%; height: 300px;"
            :ak="ak"
            :center="center"
            :zoom="zoom"
          />
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { BMap } from 'vue3-baidu-map-gl';

export default {
  components: { BMap
Login
ECHO recommendation
ScriptEcho.ai
User Annotations

卡片管理