Vue前端开发关键技术点整理
1. Vue相关指令
- {{模板语法}}:渲染数据到页面,示例:
<div>{{ message }}</div>,其中message为定义的响应式数据 - v-bind:数据的单向绑定,简写为
:,常用于绑定HTML属性。示例:<img :src="imgUrl" alt="图片"> - v-on:绑定事件,简写为
@,支持多种事件类型:// click:单击事件 ``<button @click="handleClick">点击</button> ``// dbclick:双击事件 ``<div @dbclick="handleDbClick">双击触发</div> ``// focus:获取焦点事件 ``<input @focus="handleFocus" placeholder="获取焦点触发"> ``// blur:失去焦点事件 ``<input @blur="handleBlur" placeholder="失去焦点触发">
v-for:数据的循环渲染,需配合key属性使用。示例:
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
v-show:判断显示/隐藏,通过修改display属性实现。示例:
<p v-show="isShow">v-show控制显示</p>
v-if:条件渲染,满足条件才会将元素挂载到DOM。示例:
<p v-if="isExist">v-if控制渲染</p>
v-model:数据的双向绑定,主要用于表单元素。示例:
<input v-model="username" placeholder="双向绑定用户名">
2. 基本Vue项目的创建与运行
- 执行初始化命令:
npm init vue@latest,执行后根据提示选择项目配置(如TypeScript、ESLint等) - 进入项目目录,执行
npm install下载项目所需依赖包 - 使用指令
npm run dev启动项目(部分项目可能为npm run serve,具体以package.json中scripts配置为准)
项目结构说明:
- src:项目核心代码目录
- src/components:存放自定义组件
- src/views:存放页面级组件
- src/App.vue:根组件
- src/main.js:项目入口文件
- public:静态资源目录
3. 自定义组件
3.1 自定义组件的定义与使用
在components目录中创建自定义组件(如MyHeader.vue),在其他界面使用步骤:
// 1. 在使用页面的script中导入
import MyHeader from '@/components/MyHeader.vue'
// 2. 在template中使用组件标签
<template>
<MyHeader />
</template>
3.2 父子组件之间的通信
3.2.1 父组件向子组件属性传值
// 子组件 MyHeader.vue 中接收属性
<script setup>
// 接收父组件传递过来的属性,可指定类型和默认值
const props = defineProps({
title: {
type: String,
required: true // 设为必填项
}
})
</script>
// 父组件中使用
<script setup>
import { ref } from 'vue'
import MyHeader from '@/components/MyHeader.vue'
// 声明要传递的变量
const title = ref('我是header部分...')
</script>
<template>
// 通过v-bind(简写:)传值
<MyHeader :title="title" />
</template>
3.2.2 子组件向父组件方法传值
// 父组件中定义事件处理方法
<script setup>
import MyChild from '@/components/MyChild.vue'
const handleChildData = (data) => {
console.log('接收子组件数据:', data)
}
</script>
<template>
<MyChild @childSend="handleChildData" />
</template>
// 子组件中触发父组件事件并传值
<script setup>
// 定义要触发的父组件事件
const emit = defineEmits(['childSend'])
const sendToParent = () => {
// 触发事件并传递参数
emit('childSend', '子组件的内容')
}
</script>
<template>
<button @click="sendToParent">向父组件传值</button>
</template>
语法糖:在script标签中添加setup语法糖(<script setup>)后,定义的变量或者方法无需return就可直接在template中使用,简化代码编写。
4. 组合式API和响应式API
4.1 组合式API
它是一种基于函数的 API,允许你通过逻辑关注点来组织代码,而不是通过选项类型(如 data、methods、created 等)。例如将用户相关的状态、方法放在同一函数中管理:
<script setup>
import { ref, onMounted } from 'vue'
// 用户相关逻辑
const user = ref({ name: '', age: 0 })
const fetchUser = async () => {
// 模拟请求用户数据
const res = await fetch('/api/user')
user.value = await res.json()
}
// 生命周期钩子与逻辑放在一起
onMounted(() => {
fetchUser()
})
</script>
4.2 响应式API
- ref():支持任何类型,创建的响应式数据需通过
.value修改值。示例:
import { ref } from 'vue'
const count = ref(0)
count.value++ // 修改值需加.value
console.log(count.value) // 访问值也需加.value
- reactive():仅支持对象类型,调用时不用.value修改。示例:
import { reactive } from 'vue'
const user = reactive({ name: '张三' })
user.name = '李四' // 直接修改属性即可
- 为避免记忆混乱可以全部用ref(),此外ref()内部是通过reactive()实现的。
4.3 watch()监听器
侦听一个或者多个数据的变化,数据变化时执行回调函数。支持侦听单个数据、多个数据及深度侦听:
import { watch, ref, reactive } from 'vue'
// 侦听单个ref数据
const count = ref(0)
watch(count, (newV, oldV) => {
console.log("侦听count变化,新值为:"+newV,"旧值为:"+oldV)
})
// 侦听多个数据
const name = ref('')
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log('count或name变化了')
})
// 侦听reactive对象(深度侦听)
const user = reactive({ age: 18 })
watch(user, (newUser) => {
console.log('user属性变化:', newUser.age)
}, { deep: true }) // 深度侦听需配置deep: true
5. Element-Plus组件库
5.1 下载与导入
// 下载依赖
npm install element-plus --save
// 在main.js中全局导入
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
导入后即可在组件中直接使用Element-Plus组件,示例:<el-button type="primary">主要按钮</el-button>
6. HTML组件和CSS样式
6.1 常用HTML标签
- div:布局块级元素,支持宽高设置,独占一行;默认宽度为屏幕宽度,默认高度为内容高度
- br:换行标签
- p:段落标签,自动换行且上下有边距
- :转义字符,代表一个空格; :转义字符,代表一个tab缩进
- hr:水平线标签,用于分隔内容区域
- 标题h1-h6:h1字号最大,h6最小,语义化标签
6.2 表单元素示例
<form action="" method="post">
用户名<input type="text" name="username" placeholder="请输入..." value="admin"> <br>
密码<input type="password" name="password" value="123456" > <br>
男<input type="radio" name="sex" value="男" checked/>
女<input type="radio" name="sex" value="女"/> <br>
学习 <input type="checkbox" name="hobby" value="学习">
睡觉 <input type="checkbox" name="hobby" value="睡觉" checked>
打游戏 <input type="checkbox" name="hobby" value="打游戏" checked> <br>
<select name="province">
<option value="beijing">北京</option>
<option value="shanghai" selected>上海</option>
<option value="hangzhou">杭州</option>
</select>
<select name="city" multiple>
<option value="beijing">北京</option>
<option value="shanghai" selected>上海</option>
<option value="hangzhou">杭州</option>
</select>
<br>
备注:<textarea name="beizhu" cols="30" rows="10">我是默认值</textarea> <br>
<input type="submit" value="提交" />
<input type="button" value="按钮" />
<input type="reset" value="重置" />
<input type="image" src="/public/favicon.ico" alt="图片按钮">
</form>
6.3 CSS多元素选择器
/* 同时选中多个元素设置相同样式 */
元素1, 元素2, 元素3{
margin: 0;
padding: 0;
box-sizing: border-box;
}
7. 路由
7.1 核心概念
- Router实例:路由实例,基于createRouter函数创建,维护了应用的路由信息。创建示例:
import { createRouter, createWebHistory } from 'vue-router'
import routes from './routes'
const router = createRouter({
history: createWebHistory(), // HTML5历史模式
routes // 路由规则数组
})
export default router
- :路由链接组件,浏览器会解析成标签,示例:
<router-link to="/home">首页</router-link>
- :动态视图组件,用来渲染展示与路由路径对应的组件,示例:
<router-view></router-view>
7.2 路由配置类型
- 一级路由:
const routes = [{
path: '/', // 路由路径
name: 'index', // 路由名称(可选)
component: () => import('../views/IndexView.vue'), // 路由对应组件
},]
- 二级路由(嵌套路由):通过children属性配置,父组件需包含:
const routes = [{
path: '/home',
name: 'home',
component: () => import('../views/HomeView.vue'),
children: [{ // 子路由配置
path: 'user', // 子路由路径无需加/
name: 'user',
// 路由懒加载:访问时才加载组件
component: () => import('../views/UserView.vue'),
}]
}]
- 路由重定向:设置默认跳转路由:
const routes = [{
path: '/',
// 方式1:通过name重定向
redirect: { name: "user" },
// 方式2:通过path重定向
// redirect: '/home/user'
},]
8. Axios与前后端交互
8.1 下载axios依赖
npm install axios
8.2 发起网络请求
import axios from 'axios'
// GET请求(带参数)
axios.get('/api/data', {
params: {
id: 123
}
}).then(response => {
console.log('请求成功', response.data)
}).catch(error => {
console.error('请求失败', error)
})
// POST请求(提交数据)
axios.post('/api/submit', {
username: 'test',
password: '123456'
}).then(response => {
console.log('提交成功', response.data)
})
8.3 跨域访问
跨域原因:1、协议不同 2、域名或者ip不同 3、端口不同,三者任意一个不同,都会产生跨域访问问题,即’CORS’跨域访问问题。
解决跨域访问方法:
- 针对特定接口的跨域访问:@CrossOrigin注解(局部有效),示例:
@RestController
@RequestMapping("/api")
public class TestController {
@CrossOrigin // 该接口允许跨域
@GetMapping("/data")
public String getData() {
return "test data";
}
}
- 跨域访问过滤器(全局有效):
package com.confg;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 对所有路径应用跨域策略
.allowedOriginPatterns("*") // 允许的源(生产环境建议指定具体域名)
.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
.allowedHeaders("*") // 允许的请求头
.allowCredentials(true) // 是否发送Cookie
.maxAge(3600); // 预检请求的缓存时间(秒)
}
}
8.4 前后端交互异步操作
- async/await: async:用于声明异步函数,其返回值会自动包装为Promise对象。
- await:只能在async函数内使用,用于暂停执行并等待Promise完成后获取其结果。
- 使用示例:
const fetchData = async () => {
try {
const response = await axios.get('/api/data')
console.log('请求结果', response.data)
return response.data
} catch (error) {
console.error('请求失败', error)
throw error
}
}
// 调用异步函数
fetchData()
Promise:JavaScript中用于处理异步操作的对象,代表一个异步操作的最终完成(或失败)及其结果值。 三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),状态一旦改变就不会再变。
通过.then()处理成功结果,.catch()处理失败结果,.finally()处理无论成功失败都要执行的逻辑,有效解决回调地狱问题。示例:
new Promise((resolve, reject) => {
axios.get('/api/data')
.then(res => resolve(res.data))
.catch(err => reject(err))
}).then(data => {
console.log('成功获取数据', data)
}).catch(err => {
console.error('获取数据失败', err)
}).finally(() => {
console.log('请求结束')
})
6458

被折叠的 条评论
为什么被折叠?



