创建Vue3项目

作者:qbadmin 2026-10-30 浏览:907
导读: 本文介绍创建Vue3项目的流程:首先通过npm create vue@latest命令执行项目创建,过程中可按需配置TypeScript、JSX、Vue Router、Pinia、Vitest等官方支持的配套工具,未配置的功能后续可补充添加,项目创建完成后,需执行npm install安装依赖,再通...
本文介绍创建Vue3项目的流程:首先通过npm create vue@latest命令执行项目创建,过程中可按需配置TypeScript、JSX、Vue Router、Pinia、Vitest等官方支持的配套工具,未配置的功能后续可补充添加,项目创建完成后,需执行npm install安装依赖,再通过npm run dev启动开发服务器,文中还说明了Vue3项目的目录结构,包括存放源码的src、存放静态资源的public等核心目录的作用,帮助开发者快速了解项目框架。

在区块链应用开发领域,数字钱包是用户管理链上数字资产的核心入口,imToken作为全球知名的多链数字钱包工具,其极简的界面设计、流畅的交互体验与严谨的隐私保护逻辑,一直是前端开发者搭建Web3应用的参考标杆,本文将详细分享如何基于现代前端技术栈,从零实现一个仿imToken的数字钱包界面,覆盖核心功能模块的设计思路、代码实现与体验优化方案。

技术选型与项目初始化

搭建仿imToken前端界面时,我们优先选择轻量、高效且生态完善的技术栈,兼顾开发效率与运行性能:

  • 框架:Vue3 + Vite(Vue3的组合式API提升代码可维护性,Vite的热更新能力大幅加快开发迭代速度)
  • 样式方案:Tailwind CSS(原子化CSS框架,通过预设类名快速构建响应式界面,减少自定义CSS代码量)
  • 状态管理:Pinia(轻量直观的状态管理库,用于统一管理钱包账户、资产数据、用户偏好等全局状态)
  • 路由管理:Vue Router(实现钱包首页、资产页、收款页、转账页等多页面的跳转与参数传递)
  • 工具库:qrcode(生成收款二维码)、@vueuse/core(提供触摸事件、剪贴板操作等通用工具函数)

项目初始化的完整步骤如下:

# 创建项目文件夹并进入
mkdir imtoken-clone && cd imtoken-clone
# 初始化npm项目
npm init -y
# 安装核心依赖
npm install vue vue-router pinia tailwindcss postcss autoprefixer qrcode @vueuse/core
# 安装Vite与Vue插件
npm install -D vite @vitejs/plugin-vue
# 初始化Tailwind CSS配置文件
npx tailwindcss init -p

初始化完成后,需在tailwind.config.js扫描路径,确保Tailwind能识别项目中的类名:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

核心界面模块实现

仿imToken的核心界面围绕用户资产管理流程设计,主要包含钱包首页、资产列表页、收款页、转账页四大模块,以下是各模块的关键实现细节:

钱包首页布局

钱包首页是用户打开应用的首屏,核心目标是快速展示资产概况与高频操作入口,我们采用「上下分层+左右分栏」的布局逻辑:顶部为账户切换与功能入口栏,中部为资产总览卡片,底部为快捷操作按钮组,整体遵循imToken的「信息层级优先」设计原则。

<!-- src/views/Home.vue -->
<template>
  <div class="min-h-screen bg-gray-50 pb-8">
    <!-- 顶部账户栏 -->
    <div class="bg-gradient-to-r from-blue-600 to-blue-500 text-white p-4 flex justify-between items-center shadow-sm">
      <div class="flex items-center cursor-pointer hover:opacity-90 transition-opacity">
        <img src="/assets/avatar.png" alt="用户头像" class="w-8 h-8 rounded-full mr-2 border border-white/20">
        <span class="font-medium">我的钱包</span>
        <svg class="ml-1 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
        </svg>
      </div>
      <svg class="w-6 h-6 cursor-pointer hover:opacity-90 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"></path>
      </svg>
    </div>
    <!-- 资产总览卡片 -->
    <div class="p-4 mt-2">
      <div class="bg-white rounded-xl p-6 shadow-sm border border-gray-100">
        <div class="flex items-center justify-between">
          <p class="text-gray-500 text-sm">总资产(CNY)</p>
          <button @click="toggleAssetVisibility" class="text-gray-400 hover:text-gray-600 transition-colors">
            <svg v-if="isAssetVisible" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
            </svg>
            <svg v-else class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"></path>
            </svg>
          </button>
        </div>
        <p class="text-3xl font-bold mt-2 text-gray-900">
          {{ isAssetVisible ? '¥ 12,345.67' : '¥ ****' }}
        </p>
        <div class="flex items-center mt-3 text-sm">
          <span class="text-green-500 font-medium">+ ¥ 123.45(1.01%)</span>
          <span class="text-gray-400 ml-2">近7日</span>
        </div>
      </div>
    </div>
    <!-- 快捷操作按钮组 -->
    <div class="px-4 mt-4">
      <div class="grid grid-cols-4 gap-3 bg-white rounded-xl p-4 shadow-sm border border-gray-100">
        <div class="flex flex-col items-center cursor-pointer hover:bg-gray-50 p-2 rounded-lg transition-colors">
          <svg class="w-7 h-7 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
          </svg>
          <span class="text-xs mt-1 text-gray-700">收款</span>
        </div>
        <div class="flex flex-col items-center cursor-pointer hover:bg-gray-50 p-2 rounded-lg transition-colors">
          <svg class="w-7 h-7 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path>
          </svg>
          <span class="text-xs mt-1 text-gray-700">转账</span>
        </div>
        <div class="flex flex-col items-center cursor-pointer hover:bg-gray-50 p-2 rounded-lg transition-colors">
          <svg class="w-7 h-7 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"></path>
          </svg>
          <span class="text-xs mt-1 text-gray-700">兑换</span>
        </div>
        <div class="flex flex-col items-center cursor-pointer hover:bg-gray-50 p-2 rounded-lg transition-colors">
          <svg class="w-7 h-7 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z"></path>
          </svg>
          <span class="text-xs mt-1 text-gray-700">更多</span>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref } from 'vue'
// 资产显示状态
const isAssetVisible = ref(true)
const toggleAssetVisibility = () => {
  isAssetVisible.value = !isAssetVisible.value
}
</script>

资产列表页

资产列表页用于展示用户持有的所有代币详情,包括代币名称、余额、法币价值与涨跌幅,我们通过模拟数据渲染列表,并补充搜索、下拉刷新等交互,贴近真实钱包的使用场景。

<!-- src/views/Assets.vue -->
<template>
  <div class="min-h-screen bg-gray-50 p-4">
    <!-- 页面头部 -->
    <div class="flex justify-between items-center mb-4">
      <h2 class="text-lg font-bold text-gray-900">我的资产</h2>
      <div class="relative">
        <input 
          type="text" 
          placeholder="搜索代币" 
          class="pl-8 pr-3 py-1.5 rounded-lg border border-gray-200 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500"
          v-model="searchKeyword"
        >
        <svg class="w-4 h-4 text-gray-400 absolute left-2.5 top-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
        </svg>
      </div>
    </div>
    <!-- 资产列表 -->
    <div class="bg-white rounded-xl shadow-sm border border-gray-100 overflow-hidden">
      <div 
        v-for="asset in filteredAssetList" 
        :key="asset.symbol" 
        class="flex items-center justify-between p-4 border-b border-gray-100 last:border-b-0 hover:bg-gray-50 transition-colors cursor-pointer"
      >
        <div class="flex items-center">
          <img :src="asset.logo" :alt="asset.name" class="w-10 h-10 rounded-full mr-3">
          <div>
            <p class="font-medium text-gray-900">{{ asset.name }}</p>
            <p class="text-xs text-gray-500">{{ asset.balance }} {{ asset.symbol }}</p>
          </div>
        </div>
        <div class="text-right">
          <p class="font-medium text-gray-900">¥ {{ asset.value.toFixed(2) }}</p>
          <p :class="asset.change >= 0 ? 'text-green-500 text-xs' : 'text-red-500 text-xs'">
            {{ asset.change >= 0 ? '+' : '' }}{{ asset.change }}%
          </p>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, computed } from 'vue'
// 搜索关键词
const searchKeyword = ref('')
// 模拟资产数据
const assetList = ref([
  { name: '比特币', symbol: 'BTC', balance: 0.05, value: 14500, change: 2.3, logo: '/assets/btc.png' },
  { name: '以太坊', symbol: 'ETH', balance: 1.2, value: 9600, change: -1.2, logo: '/assets/eth.png' },
  { name: '泰达币', symbol: 'USDT', balance: 1000, value: 7200, change: 0.01, logo: '/assets/usdt.png' },
  { name: '币安币', symbol: 'BNB', balance: 2.5, value: 3125, change: 1.8, logo: '/assets/bnb.png' }
])
// 过滤后的资产列表
const filteredAssetList = computed(() => {
  if (!searchKeyword.value) return assetList.value
  return assetList.value.filter(asset => 
    asset.name.toLowerCase().includes(searchKeyword.value.toLowerCase()) ||
    asset.symbol.toLowerCase().includes(searchKeyword.value.toLowerCase())
  )
})
</script>

收款页实现

收款页的核心功能是展示用户的钱包地址与对应二维码,方便他人扫码转账,我们使用qrcode库生成高清二维码,并补充地址复制、二维码保存等实用功能,同时

转载请注明出处:qbadmin,如有疑问,请联系()。
本文地址:https://www.sdyyyy.net/swxk/8144.html

标签:

相关文章