前端开发基础
参考资料
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>标题</title>
<link
href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300|Sonsie+One"
rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css?family=ZCOOL+KuaiLe"
rel="stylesheet" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<!-- 内容 -->
</body>
</html>
CSS
- 选择器
.classname/标签名/通配符/... {属性: 值; 属性: 值;}
- 属性: 尺寸 / 背景 / 颜色 / 文本 / 布局 / 过渡 / 变换 / 动画
- 选择器后加
:name 伪类选择器 (某个状态下, 如光标悬浮)
- 加
::name 伪元素选择器 (为标签添加元素, 如对号 / 只选中第一行)
VUE 3
createApp(App).mount('#app')
- 响应式系统
ref(initValue): 针对基本类型 (数字/字符串), JS 中修改/读取必须加 .value, 模版中自动解包 (不用加)
reactive(obj): 针对对象/数组, JS 中不需要加 .value, 直接读写
- 生命周期,
onMounted(() => {}) (组件挂载后), onUnmounted (卸载后)
- 计算与侦听
computed(() => result): 只有依赖变化时才重新计算, 有缓存
watch(source, (newVal, oldVal) => {}): 监控数据变化执行副作用 (如请求 API)
- 模版指令
{{ var }}: 插值显示
:prop="val" (v-bind): 动态绑定属性
@event="fun" (v-on): 绑定事件
v-model="var": 双向绑定 (输入框值与变量同步)
v-if="bool" / v-else: 条件渲染 (真则存在, 假则移除 DOM)
v-for="(item, index) in list" :key="item.id": 循环渲染
VUE 3 组件化
- 单文件组件:
.vue 文件包含 <template> (结构), <script setup> (逻辑), <style scoped> (样式)
- 父传子:
- 子组件:
const props = defineProps({ msg: String }) 或 TS写法 defineProps<{ msg: string }>()
- 父组件:
<Child msg="hello" />
- 子传父:
- 子组件:
const emit = defineEmits(['change']) -> 调用 emit('change', data)
- 父组件:
<Child @change="handleUpdate" />
- 插槽:
- 子组件:
<slot /> 占位
- 父组件: 在子组件标签内部填充 HTML 内容
VUE Router
- 监听 URL 变化, 切换页面组件
- 核心组件
<router-link to="/path">: 跳转链接 (类似 <a> 标签)
<router-view />: 路由出口, 页面组件会显示在这里
- JS 操作:
const router = useRouter(): 拿到路由实例, 执行跳转 router.push('/home')
const route = useRoute(): 拿到当前信息, 获取参数 route.params.id 或 route.query.keyword
Pinia
- 定义
defineStore('id', () => { ... }): 内部写法和 <script setup> 一样
ref 是 state (数据)
computed 是 getters (计算数据)
function 是 actions (修改方法)
- 使用 Store:
const store = useUserStore()
- 直接读写:
store.count++
- 解构注意: 直接
const { count } = store 会丢失响应式, 需用 storeToRefs(store)
React
- 组件写法
- Vue:
<template> + <script setup>
- React:
function App() { return ( <div> HTML写在这里 </div> ) } + export default
- JSX
- HTML 中插入变量: 使用
{} (Vue 是 {{}} 和 :)
class 属性写为 className (因为 class 是 JS 关键字)
- 必须只有一个根节点 (或使用
<> ... </> 空标签包裹)
- 状态
- 写法:
const [count, setCount] = useState(0)
- 精髓: React 数据是不可变的
- 区别: 绝不能写
count++必须调用 setCount(newVal) 才能触发更新
- 副作用
- 写法:
useEffect(() => { 逻辑 }, [依赖数组])
[] 空数组: 等同于 onMounted (只执行一次)
[count]: 等同于 watch(count) (依赖变化时执行)
return () => {}: 等同于 onUnmounted (清理副作用)
React 生态
- React Router
- 状态管理
- Zustand 类比 Pinia, 写法几乎一样:
create((set) => ({ count: 0, inc: () => set(...) }))
包管理器
fnm
npm
corepack
- node 自带的包管理器管理器
corepack enable 启用
pnpm
yarn
bun
其他工具
Vite
- 开发期使用原生 ESM 和按需转换
- 生产期调用 Rollup 打包
- 处理 TS / JSX / CSS / 静态资源 / env / source map / HMR (热替换)
pnpm create vite@latest
常见模板
vanilla-ts: 原生 Web + TypeScript
react-ts: React + TypeScript
vue-ts: Vue + TypeScript
svelte-ts: Svelte + TypeScript
preact-ts: Preact + TypeScript
格式化与检查
测试
客户端
Tauri
- 前端负责 UI 交互, 后端负责系统级操作 (文件 / 网络 / 硬件), 两者通过 IPC 桥接
- 前端调后端
- 前端:
import { invoke } from '@tauri-apps/api/core'
- 调用:
await invoke('command_name', { key: value }) 返回 Promise
- 后端接前端
- 位置:
src-tauri/src/lib.rs 或 main.rs
- 定义:
#[tauri::command] 宏修饰函数 fn command_name(key: String) -> String { ... }
- 注册: 必须在
Builder 中添加 .invoke_handler(tauri::generate_handler![command_name])
- 事件
- 后端主动推:
app.emit("event_name", payload)
- 前端被动收:
import { listen } from '@tauri-apps/api/event', listen('event_name', (e) => { ... })
- 常用能力与权限
- API:
fs (读写文件), dialog (原生打开/保存弹窗), shell (执行命令/打开浏览器), http (绕过 CORS 的请求)
- 安全配置: 必须在
src-tauri/capabilities 中显式开启相应 API 的权限 , 否则静默失败