当前位置: 首页 > news >正文

Vue 基础(实战模板与命名指南)

Vue 基础(实战模板与命名指南)

聚焦三件事:模板化写法、ref/reactive 使用选择、变量与函数命名规范。配合可复制的代码模板,快速搭建可靠页面。

1. 组件标准模板

<template><section class="user-list-page"><header class="page-header"><h2>用户列表</h2><div class="actions"><el-input v-model="query.keyword" placeholder="关键字" class="mr-8" /><el-button type="primary" :loading="isLoading" @click="fetchUsers">查询</el-button><el-button @click="resetQuery">重置</el-button></div></header><el-table :data="rows" v-loading="isLoading"><el-table-column prop="id" label="ID" width="80" /><el-table-column prop="name" label="姓名" /><el-table-column prop="phone" label="手机" /><el-table-column label="操作" width="160" align="center"><template #default="{ row }"><el-button size="small" @click="onEdit(row)">编辑</el-button></template></el-table-column></el-table><el-paginationclass="mt-12"backgroundlayout="prev, pager, next, sizes, total":current-page="pagination.page":page-size="pagination.pageSize":total="pagination.total"@update:current-page="onPageChange"@update:page-size="onPageSizeChange"/></section></template><script setup lang="ts">
import { ref, reactive, computed } from 'vue'// 查询条件:对象推荐用 reactive(可读性强,字段集中)
const query = reactive({ keyword: '', dateRange: [] as [string, string] | [] })// 列表数据:数组通常用 ref,便于整体替换(分页、筛选场景)
const rows = ref<any[]>([])
const isLoading = ref(false)// 分页:对象一次性传递,使用 ref 包裹以便整体更新
const pagination = ref({ page: 1, pageSize: 10, total: 0 })// 计算属性:派生状态(示例)
const hasKeyword = computed(() => query.keyword.trim().length > 0)// 事件处理:动作动词开头 + 语义对象(handle/on 均可,保持一致)
function fetchUsers() {isLoading.value = truetry {const total = 42const start = (pagination.value.page - 1) * pagination.value.pageSizeconst end = start + pagination.value.pageSizeconst all = Array.from({ length: total }).map((_, i) => ({ id: i + 1, name: `用户${i + 1}`, phone: '13800000000' }))rows.value = hasKeyword.value ? all.filter(u => u.name.includes(query.keyword)) .slice(start, end) : all.slice(start, end)pagination.value.total = hasKeyword.value ? all.filter(u => u.name.includes(query.keyword)).length : total} finally {isLoading.value = false}
}function resetQuery() {query.keyword = ''query.dateRange = []pagination.value.page = 1fetchUsers()
}function onPageChange(p: number) {pagination.value.page = pfetchUsers()
}function onPageSizeChange(s: number) {pagination.value.pageSize = spagination.value.page = 1fetchUsers()
}function onEdit(row: any) {console.log('edit', row)
}// 初始化
fetchUsers()
</script><style scoped>
.page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.actions { display: flex; align-items: center; }
.mr-8 { margin-right: 8px; }
.mt-12 { margin-top: 12px; }
</style>

2. ref vs reactive 使用选择

  • 基础类型(数值、字符串、布尔)用 ref
    • 示例:const count = ref(0)const isLoading = ref(false)
  • 复杂对象/表单状态用 reactive
    • 示例:const form = reactive({ name: '', age: 0 })
  • 数组在分页/筛选场景常用 ref<any[]>([]),便于整体替换
    • 赋值:rows.value = newRows
    • 变更:rows.value.push(item)(注意 .value
  • 嵌套对象:reactive 自动深层代理;若需要整体替换用 ref<{...}>()

常见陷阱:

  • 模板中 ref 会自动解包;脚本中需 .value
  • reactive 使用解构会失去响应式,改用 toRefs 或在模板直接访问字段

3. 命名规范(变量、函数、计算属性、事件)

  • 状态布尔:isLoadingisVisiblehasErrorisDisabled
  • 数据集合:usersrowsitems;单项用 userrowitem
  • 查询与表单:queryfiltersform
  • 计算属性:用派生语义,如 filteredUsersselectedCount
  • 事件处理:统一前缀 onhandle,如 onSubmithandleDelete
  • 接口函数:动作 + 资源,如 fetchUserscreateUserupdateUser
  • 组件 props:语义清晰,避免缩写;双向绑定使用 modelValue

4. 模板语法常用模式

<div><!-- 插值 --><div>当前计数:{{ count }}</div><!-- 属性绑定 --><img :src="imgUrl" :alt="altText" /><button :disabled="isDisabled">保存</button><!-- class/style 绑定 --><div :class="{ active: isActive }" :style="{ color: textColor }">样式示例</div><!-- 事件绑定 --><button @click="onClick">点击</button><!-- 条件/列表 --><p v-if="isShow">显示内容</p><ul><li v-for="user in users" :key="user.id">{{ user.name }}</li></ul>
</div>

5. 计算属性与侦听器模板

import { computed, watch } from 'vue'// 计算属性:依赖数据变化自动更新
const isAllChecked = computed(() => items.value.every(i => i.checked))// 侦听:响应变化执行副作用
watch(() => query.keyword, (newVal, oldVal) => {// 节流/防抖可在此接入fetchUsers()
})// 深度与立即选项
watch(form, (val) => { console.log('form changed', val) }, { deep: true })
watch(() => route.path, () => init(), { immediate: true })

6. 组件通信模板(props / emits / v-model)

<!-- 子组件 Child.vue -->
<script setup lang="ts">
import type { PropType } from 'vue'const props = defineProps({modelValue: { type: String, default: '' },maxLength: { type: Number, default: 20 }
})const emit = defineEmits<{(e: 'update:modelValue', v: string): void(e: 'change', v: string): void
}>()function onInput(v: string) {emit('update:modelValue', v)emit('change', v)
}
</script><template><el-input :model-value="props.modelValue" :maxlength="props.maxLength" @input="onInput" />
</template><!-- 父组件使用 -->
<Child v-model="name" @change="handleNameChange" />

补充:

  • 子组件事件示例:const emit = defineEmits(['change']); emit('change', newVal)
  • 父组件监听:<Child @change="handleChildChange" />

7. 可复用逻辑(Composable)模板

分页:

import { ref } from 'vue'export function usePagination(initial = { page: 1, pageSize: 10, total: 0 }) {const pagination = ref(initial)const onPageChange = (p: number) => (pagination.value.page = p)const onPageSizeChange = (s: number) => { pagination.value.pageSize = s; pagination.value.page = 1 }return { pagination, onPageChange, onPageSizeChange }
}

数据获取:

import { ref } from 'vue'
import http from '@/api/http'export function useFetchUsers() {const rows = ref<any[]>([])const isLoading = ref(false)async function fetch(params: { page: number; pageSize: number; keyword?: string }) {isLoading.value = truetry {const res = await http.get('/users', { params })rows.value = res.items} finally {isLoading.value = false}}return { rows, isLoading, fetch }
}

8. 表单状态与校验(简单版)

<script setup lang="ts">
import { reactive, ref } from 'vue'
const formRef = ref()
const form = reactive({ name: '', age: 18 })
const rules = {name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],age: [{ type: 'number', required: true, message: '请输入年龄', trigger: 'blur' }]
}async function onSubmit() {await formRef.value.validate()// 调用接口提交
}
</script><template><el-form ref="formRef" :model="form" :rules="rules" label-width="80px"><el-form-item label="姓名" prop="name"><el-input v-model="form.name" /></el-form-item><el-form-item label="年龄" prop="age"><el-input-number v-model="form.age" :min="0" /></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">提交</el-button></el-form-item></el-form></template>

9. 小结与实践建议

  • 页面数据结构优先:query(reactive)+ rows(ref)+ pagination(ref)
  • 动作统一:fetchXxxresetXxxonXxxChange 保持一致命名
  • 组件通信明确:props 提数据,emits 发事件,双向绑定用 v-model
  • 抽象通用:将分页/获取/表单校验封装为 composable 或通用组件
http://www.dtcms.com/a/445792.html

相关文章:

  • 葫芦岛建设信息网站营销专业就业前景
  • 保定网站推广哪家好专业团队张伟图片
  • leetcode 1219 黄金矿工
  • 【Camera】MTK平台的一些基础认识(待补充)
  • Go基础:用Go语言操作MySQL详解
  • 数字短链接生成郑州seo优化
  • 网站排版尺寸安装好的字体怎么用wordpress
  • 如何利用企业微信SCRM打造精准客户营销策略?
  • AI 编程 Trae 如何去 AI 味(以用户管理系统为例子)
  • 【National Treasure2】
  • 【LLM4EDA】: Part 9--LLM4EDA的优化与建模
  • 用parser_tools插件来解析SQL语句
  • 湖北住房和城乡建设厅网站phpmysql做网站
  • 《量子计算》学习笔记:量子计算的基本定义(续)
  • 哈尔滨网站建设价位上海有名的猎头公司
  • 手写MyBatis第94弹:完整架构回顾与核心技术深度解析
  • 汽车电子Autosar架构BSW层学习路线·附录章节
  • 织梦 网站设计做网站竟然不知道cms
  • Linex操作系统-Shell脚本(六)
  • 2025年ASOC SCI2区TOP,基于动态模糊系统的改进灰狼算法FGWO,深度解析+性能实测
  • Go基础:输入与输出格式化详解
  • Go语言:数据压缩与解压详解
  • Odoo 前端控制器:构建无缝集成的网站页面
  • Go基础:json文件处理详解(标准库`encoding/json`)
  • 网站页头尺寸网站建设实物实训目的
  • RegNet:高效可扩展网络
  • 软考 系统架构设计师系列知识点之杂项集萃(169)
  • 大数据毕业设计选题推荐-基于大数据的人口普查收入数据分析与可视化系统-Hadoop-Spark-数据可视化-BigData
  • 实验室网站制作数据交易网站源码
  • 【Kubernetes】(二十)Gateway