angular九宫格ui

说明:angular九宫格ui

效果图:

step1:

C:\Users\wangrusheng\WebstormProjects\untitled4\src\app\order\order.component.ts

javascript 复制代码
import { Component } from '@angular/core';
import {NgForOf} from '@angular/common';

interface Order {
  title: string;
  price: string;
  requirementType: string;
  referenceUrl: string;
  options: string[];
  status: string;
  publishDate: string;
  paymentMode: string;
}

@Component({
  selector: 'app-order',
  imports: [
    NgForOf
  ],
  templateUrl: './order.component.html',
  styleUrl: './order.component.css'
})
export class OrderComponent {
  orders: Order[] = [];

  constructor() {
    // 生成测试数据
    for(let i = 1; i <= 8; i++) {
      this.orders.push({
        title: `网站定制开发项目 ${i}`,
        price: `${1200 + i * 100}元`,
        requirementType: '网站定制开发',
        referenceUrl: 'https://papermk.com/案例' + i,
        options: ['整站开发', '响应式', '后台管理', '多语言'],
        status: i % 2 === 0 ? '进行中' : '已结案',
        publishDate: `2024-03-${i.toString().padStart(2, '0')}发布`,
        paymentMode: i % 3 === 0 ? '项目付费' : '招标付费'
      });
    }
  }

  selectedOption: { [key: number]: string } = {};

  selectOption(orderIndex: number, option: string) {
    this.selectedOption[orderIndex] = option;
  }
}

step2:

C:\Users\wangrusheng\WebstormProjects\untitled4\src\app\order\order.component.html

xml 复制代码
<div class="grid-container">
  <div *ngFor="let order of orders; let i = index" class="card">
    <!-- Header Section -->
    <div class="header-section">
      <h1 class="title">{{ order.title }}</h1>
      <p class="price">{{ order.price }}</p>
    </div>

    <!-- Reference Section -->
    <div class="reference-section">
      <p class="section-label">需求类型</p>
      <p class="reference-text">{{ order.requirementType }}</p>
      <a class="reference-link" href="{{ order.referenceUrl }}" target="_blank">参考链接</a>
    </div>

    <!-- Options Section -->
    <div class="options-section">
      <button *ngFor="let option of order.options"
              class="option-button"
              [class.selected]="selectedOption[i] === option"
              (click)="selectOption(i, option)">
        {{ option }}
      </button>
    </div>

    <!-- Status Section -->
    <div class="status-section">
      <div class="status-group">
        <span class="status-badge">{{ order.status }}</span>
        <span class="publish-date">{{ order.publishDate }}</span>
        <span class="payment-mode">{{ order.paymentMode }}</span>
      </div>
    </div>
  </div>
</div>

step3:

C:\Users\wangrusheng\WebstormProjects\untitled4\src\app\order\order.component.css

css 复制代码
/* Grid布局 */
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  max-width: 1200px;
  margin: 20px auto;
  padding: 0 20px;
}

/* Card样式 */
.card {
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.08);
  padding: 20px;
  transition: transform 0.2s, box-shadow 0.2s;
  break-inside: avoid;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.12);
}

/* Header Section */
.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #f0f0f0;
}

.title {
  font-size: 16px;
  line-height: 1.3;
  margin: 0;
  color: #2d3748;
  font-weight: 600;
}

.price {
  font-size: 14px;
  color: #38a169;
  margin: 0;
  font-weight: 500;
}

/* Reference Section */
.reference-section {
  margin-bottom: 16px;
}

.section-label {
  font-size: 12px;
  color: #718096;
  margin: 0 0 4px 0;
}

.reference-text {
  font-size: 14px;
  color: #2d3748;
  margin: 6px 0;
}

.reference-link {
  color: #4299e1;
  font-size: 12px;
  text-decoration: none;
  display: block;
  margin-top: 8px;
  transition: color 0.2s;
}

.reference-link:hover {
  color: #3182ce;
}

/* Options Section */
.options-section {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: 16px;
}

.option-button {
  padding: 8px 12px;
  border: none;
  border-radius: 8px;
  background: #f8f9fa;
  color: #2d3748;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  font-weight: 500;
}

.option-button:hover {
  background: #e9ecef;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1);
}

.option-button.selected {
  background: #2d3748;
  color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Status Section */
.status-section {
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}

.status-group {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}

.status-badge,
.publish-date,
.payment-mode {
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 16px;
  background: #f8f9fa;
  color: #4a5568;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
}

.status-badge {
  background: #e9f5eb;
  color: #38a169;
}

/* 响应式布局 */
@media (max-width: 992px) {
  .grid-container {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .grid-container {
    grid-template-columns: 1fr;
  }

  .status-group {
    flex-wrap: wrap;
  }

  .options-section {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .card {
    padding: 16px;
  }

  .status-badge,
  .publish-date,
  .payment-mode {
    font-size: 11px;
    padding: 4px 8px;
  }
}

end

相关推荐
benben0441 小时前
Unity3D仿星露谷物语开发66之NPC存档
游戏·ui·unity·c#·游戏引擎
codingandsleeping7 小时前
重读《你不知道的JavaScript》(上)- this
前端·javascript
孩子 你要相信光9 小时前
前端如何通过 Blob 下载 Excel 文件
前端·javascript
喵喵侠w9 小时前
腾讯地图Web版解决热力图被轮廓覆盖的问题
前端·javascript
qq_27866728610 小时前
ros中相机话题在web页面上的显示,尝试js解析sensor_msgs/Image数据
前端·javascript·ros
烛阴11 小时前
JavaScript并发控制:从Promise到队列系统
前端·javascript
&活在当下&11 小时前
element plus 的树形控件,如何根据后台返回的节点key数组,获取节点key对应的node节点
javascript·vue.js·element plus
fanged12 小时前
Angular--Hello(TODO)
前端·javascript·angular.js
ui设计前端开发老司机13 小时前
数字孪生技术助力:UI前端设计的精准度与效率双提升
ui
实习生小黄14 小时前
基于扫描算法获取psd图层轮廓
前端·javascript·算法