ContactCard 聯絡人卡片 - Vant 4
📇 ContactCard 聯絡人卡片
📋 介紹
ContactCard 就像是你手機通訊錄裡的一張精美名片!✨ 它以優雅的卡片形式展示聯絡人資訊,不僅顏值在線,功能也超級貼心。無論是新增新朋友的聯絡方式,還是編輯老朋友的資訊,都能讓你的聯絡人管理變得如絲般順滑。就像有了一個貼心的通訊錄管家,讓每一次聯絡人操作都充滿儀式感!🎭
📦 引入
透過以下方式來全域註冊元件,更多註冊方式請參考元件註冊。
js
import { createApp } from'vue'; import { ContactCard } from'vant'; const app = createApp(); app.use(ContactCard);🎯 程式碼演示
➕ 新增聯絡人 - 新朋友入駐通訊錄
想要為通訊錄新增新成員?ContactCard 的新增模式就像是為新朋友準備的專屬邀請函!🎉 一鍵點擊,輕鬆開啟聯絡人錄入之旅。
html
js
import { showToast } from'vant';
export default {
setup() {
const onAdd = () => showToast('新增');
return { onAdd, };
},
};✏️ 編輯聯絡人 - 老朋友資訊更新
朋友換了新號碼?搬了新家?ContactCard 的編輯模式就像是聯絡人資訊的貼心管家!📝 讓你輕鬆更新好友的最新動態,確保每次聯絡都能第一時間找到對的人。
html
js
import { ref } from'vue';
import { showToast } from'vant';
export default {
setup() {
const tel = ref('13000000000');
const name = ref('张三');
const onEdit = () => showToast('edit');
return { tel, name, onEdit, };
},
};🔒 不可編輯 - 唯讀模式展示
有些聯絡人資訊需要保持穩定?ContactCard 的唯讀模式就像是給重要聯絡人加了一層保護罩!🛡️ 既能清晰展示資訊,又能防止誤操作,讓重要聯絡人資訊安全無憂。
html
API
Props
| 參數 | 說明 | 類型 | 預設值 |
|---|---|---|---|
| type | 卡片類型,可選值為 edit | string | add |
| name | 聯絡人姓名 | string | - |
| tel | 聯絡人手機號 | string | - |
| add-text | 新增時的文案提示 | string | 新增聯絡人 |
| editable | 是否可以編輯聯絡人 | boolean | true |
Events
| 事件名 | 說明 | 回調參數 |
|---|---|---|
| click | 點擊時觸發 | event: MouseEvent |
類型定義
元件匯出以下類型定義:
ts
importtype { ContactCardType, ContactCardProps } from'vant';🎨 主題定制
樣式變數
元件提供了下列 CSS 變數,可用於自定義樣式,使用方法請參考 ConfigProvider 元件。
| 名稱 | 預設值 | 描述 |
|---|---|---|
| --van-contact-card-padding | var(--van-padding-md) | - |
| --van-contact-card-add-icon-size | 40px | - |
| --van-contact-card-add-icon-color | var(--van-primary-color) | - |
| --van-contact-card-title-line-height | var(--van-line-height-md) | - |
🎯 最佳實踐
📱 行動端適配建議
- 觸控友好 - 確保卡片區域足夠大,方便手指點擊
- 視覺層次 - 使用合適的字體大小和顏色對比度
- 載入狀態 - 為網路請求新增載入提示
- 錯誤處理 - 優雅處理聯絡人資訊取得失敗的情況
🎨 介面設計技巧
vue
<template>
<!-- 推薦:新增過渡動畫 -->
<transition name="contact-card" mode="out-in">
<ContactCard
:key="contactKey"
:type="cardType"
:name="contactName"
:tel="contactTel"
@click="handleCardClick"
class="smooth-card"
/>
</transition>
</template>
<style>
.contact-card-enter-active,
.contact-card-leave-active {
transition: all 0.3s ease;
}
.contact-card-enter-from {
opacity: 0;
transform: translateY(20px);
}
.contact-card-leave-to {
opacity: 0;
transform: translateY(-20px);
}
.smooth-card {
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}
</style>🔄 狀態管理建議
javascript
// 推薦:使用響應式資料管理聯絡人狀態
const contactState = reactive({
isEditing: false,
isLoading: false,
contactInfo: {
name: '',
tel: '',
id: null
}
})
// 切換編輯狀態
const toggleEditMode = () => {
contactState.isEditing = !contactState.isEditing
}
// 儲存聯絡人資訊
const saveContact = async () => {
contactState.isLoading = true
try {
await updateContactAPI(contactState.contactInfo)
showSuccessToast('儲存成功')
contactState.isEditing = false
} catch (error) {
showFailToast('儲存失敗,請重試')
} finally {
contactState.isLoading = false
}
}💡 使用技巧
🎭 動態卡片類型
vue
<template>
<ContactCard
:type="dynamicType"
:name="contactName"
:tel="contactTel"
:editable="canEdit"
@click="handleClick"
/>
</template>
<script setup>
// 根據使用者權限動態設定卡片類型
const dynamicType = computed(() => {
if (!contactName.value && !contactTel.value) {
return 'add'
}
return hasEditPermission.value ? 'edit' : 'add'
})
// 智慧點擊處理
const handleClick = () => {
if (dynamicType.value === 'add') {
// 跳轉到新增聯絡人頁面
router.push('/contact/add')
} else {
// 跳轉到編輯聯絡人頁面
router.push(`/contact/edit/${contactId.value}`)
}
}
</script>🔍 聯絡人搜尋整合
vue
<template>
<div class="contact-search-container">
<Search
v-model="searchKeyword"
placeholder="搜尋聯絡人"
@search="handleSearch"
/>
<div class="contact-list">
<ContactCard
v-for="contact in filteredContacts"
:key="contact.id"
type="edit"
:name="contact.name"
:tel="contact.tel"
@click="selectContact(contact)"
/>
<!-- 空狀態 -->
<Empty
v-if="filteredContacts.length === 0"
description="暫無符合的聯絡人"
/>
</div>
</div>
</template>
<script setup>
const searchKeyword = ref('')
const contacts = ref([])
// 過濾聯絡人
const filteredContacts = computed(() => {
if (!searchKeyword.value) return contacts.value
return contacts.value.filter(contact =>
contact.name.includes(searchKeyword.value) ||
contact.tel.includes(searchKeyword.value)
)
})
</script>📞 快捷操作整合
vue
<template>
<ContactCard
type="edit"
:name="contactName"
:tel="contactTel"
@click="showActionSheet"
/>
<ActionSheet
v-model:show="showActions"
:actions="contactActions"
@select="handleAction"
/>
</template>
<script setup>
const showActions = ref(false)
const contactActions = [
{ name: '撥打電話', icon: 'phone-o' },
{ name: '傳送簡訊', icon: 'chat-o' },
{ name: '編輯聯絡人', icon: 'edit' },
{ name: '刪除聯絡人', icon: 'delete-o', color: '#ee0a24' }
]
const showActionSheet = () => {
showActions.value = true
}
const handleAction = (action) => {
switch (action.name) {
case '撥打電話':
window.location.href = `tel:${contactTel.value}`
break
case '傳送簡訊':
window.location.href = `sms:${contactTel.value}`
break
case '編輯聯絡人':
router.push(`/contact/edit/${contactId.value}`)
break
case '刪除聯絡人':
confirmDelete()
break
}
}
</script>❓ 常見問題解決
🔧 卡片點擊無回應?
問題:ContactCard 點擊事件不觸發 解決方案:
- 檢查是否正確綁定了
@click事件 - 確認父容器沒有阻止事件冒泡
- 驗證 CSS 樣式是否影響了點擊區域
📱 行動端顯示異常?
問題:在行動裝置上卡片顯示不正常 解決方案:
css
/* 確保行動端適配 */
.van-contact-card {
min-height: 60px;
touch-action: manipulation;
}
/* 防止長按選擇文字 */
.van-contact-card * {
user-select: none;
-webkit-user-select: none;
}🎨 自訂樣式不生效?
問題:CSS 變數修改後樣式沒有變化 解決方案:
- 確保在正確的作用域內設定 CSS 變數
- 使用
!important提高優先級(謹慎使用) - 檢查是否有其他樣式覆蓋
🎨 設計靈感
🌈 主題風格建議
商務風格 - 簡潔線條 + 深色配色
css--van-contact-card-padding: 20px; --van-contact-card-add-icon-color: #2c3e50;活潑風格 - 圓潤邊角 + 亮色配色
css--van-contact-card-padding: 16px; --van-contact-card-add-icon-color: #ff6b6b;極簡風格 - 留白設計 + 單色配色
css--van-contact-card-padding: 24px; --van-contact-card-add-icon-color: #666;
🎯 互動設計建議
- 微動畫 - 新增懸停和點擊動畫效果
- 狀態回饋 - 清晰的載入和成功狀態提示
- 手勢支援 - 支援滑動刪除等手勢操作
- 無障礙 - 新增適當的 ARIA 標籤和鍵盤導航
📚 相關文件
- Contact 聯絡人 - 聯絡人選擇元件
- Card 卡片 - 基礎卡片元件
- Cell 單元格 - 單元格元件
- ConfigProvider 全域配置 - 了解主題定製方法
🔗 延伸閱讀
- 行動端聯絡人管理最佳實務 - MDN 聯絡人選擇器 API
- 無障礙設計指南 - WCAG 2.1 快速參考
- 行動端觸控互動設計 - Material Design 手勢指南
- Vue 3 組合式 API - Vue 3 官方文件