Vue前端开发——从入门到放弃

simple is best

最近开始试着学习vue来开发前端页面,因为之前的flaredrive网盘项目中就是用vue前端,所以对一些页面状态修改还是有所了解。这次开发的页面也很简单,有一个表单,提交后进入一个瀑布流显示,每一步运行都有状态显示,运行完成后就将背景变成蓝色已完成,并且更改步骤的描述。于是我把需求描述扔给Deepseek和chatgpt,让它们帮忙实现。虽然中间有一些问题需要自己慢慢更改,但最终还是可以用的。甚至可以直接让它们帮你设计SVG图标。

创建项目

因为我想把页面最终托管到cloudflare上,所以可以用wrangler构建。首先安装依赖

npm install -g wrangler
wrangler init my-worker-vue
cd my-worker-vue

创建时选择typescript和vue,然后就会自动生成文件和目录。其中包含一个server/index.ts文件,内容如下:

export default {
	fetch(request) {
		const url = new URL(request.url);

		if (url.pathname.startsWith("/api/")) {
			return Response.json({
				name: "Cloudflare",
			});
		}
		return new Response(null, { status: 404 });
	},
} satisfies ExportedHandler<Env>;

定义了异步请求的相应,在访问/api/路径时会返回一个json的对象。其它静态资源返回(Vue 页面)在main.tsrouter/index.ts中定义。一些vue文件中可以导入其他vue文件作为该页面的一个组件。

页面跳转

因为页面设计中包含一个带参数的跳转,这里简单总结一下useRouter的用法。

发起请求

首先是依赖导入:

import { useRouter } from 'vue-router'

const router = useRouter()

然后在需要提交的地方调用和提交参数:

router.push({
  path: '/token',
  query: { key:value }
})

就是这么简单。页面元素和文本框输入获取比较简单,不赘述。

目标页面处理

目标页面/token获取到请求和参数后,可以通过下面的代码进行处理

<script setup lang="ts">
import { useRoute } from 'vue-router'

const route = useRoute()

const value = route.query[key]

console.log('value:', value)
</script>

template和slot

一句话,<template> 是 “不会被渲染成 DOM 的结构容器”。它本身不显示,只是用来包住结构或内容。

Slot 是 父组件“往子组件指定位置塞内容”的机制。

❌ 误区:不能“直接操作 slot DOM”

原因:

  • Slot 内容属于 父组件
  • 子组件不能直接改

ref变量和defineProps有什么区别?

为了在提交后的瀑布流中更改各个状态的描述,我需要用ref变量来存储和修改。

对比点 ref defineProps
属于谁 当前组件自己的状态 父组件传进来的只读数据
能不能改 ✅ 可以 ❌ 不能(只读)
用途 状态、交互、响应式逻辑 接收外部配置
数据流 组件内部 父 → 子(单向)

最终实现的方案如下:

...
const description = ref('Create a Solana wallet, private key:')
...

// 需要修改时
description.value = "Creating token..."
...

// 初始状态
<WelcomeItem  :isActive="isActive(2)"
    :isCompleted="isDone(2)">
    <template #icon>
        <TokenIcon />
    </template>
    <template #heading>Token</template>
    <p class="break-text" v-html="description"></p>
</WelcomeItem>

这里用v-html可以使description能渲染html元素

自动换行

使用css样式来实现,定义如下:

.break-key {
  word-break: break-all;        /* 强制任意字符换行 */
  overflow-wrap: anywhere;     /* 现代浏览器推荐 */
  white-space: normal;
}

❌ 不要在 setup 顶层 await

典型报错:

Component <TheWelcome>: setup function returned a promise, but no <Suspense> boundary was found in the parent component tree. A component with async setup() must be nested in a <Suspense> in order to be rendered. 

需要将await部分放进异步函数中,或者放进onMounted,如下:

<script setup lang="ts">
import { onMounted } from 'vue'
import { Connection } from '@solana/web3.js'

const connection = new Connection('https://api.devnet.solana.com')

onMounted(async () => {
  const sig = await connection.requestAirdrop(pubkey, 1e9)
  await connection.confirmTransaction(sig)
})
</script>

🧠 为什么 Vue 要这么设计?

Vue 的理念是:

setup 应该是“同步地建立响应式关系”,而不是做 IO。

所以:

顶层 await = IO 阻塞渲染。Vue 强制你用 <Suspense> 承担这个状态。

浏览器环境报错处理

报错内容如下:

Uncaught ReferenceError: global is not defined
    at index.mjs:657:16
一、为什么会报这个错?

原因只有一个:

你在浏览器环境(Vite)里用了“默认假设 Node.js 环境”的库 而这些库里写了类似:

global.Buffer
global.process

但——

👉 浏览器里没有 global,只有 window / globalThis

二、最终解决方案

你可以为浏览器环境提供 stream 模块的 polyfill。例如,使用 stream-browserify 作为浏览器的 polyfill。

如果您觉得该文章对您有用,欢迎打赏作者,激励创作!
Welcome to tip the author!

微信(WeChat Pay) 支付宝(AliPay)
比特币(Bitcoin) 以太坊(Ethereum)
以太坊(Base) 索拉纳(Solana)