阅读视图

发现新文章,点击刷新页面。

Vue以及ElementPlus学习

Vue常用指令

指令:HTML标签上带有v-前缀的特殊属性,不同的指令具有不同的含义,可以实现不同的功能

v-for

作用:列表渲染,遍历容器的元素或者对象的属性

语法:

<tr v-for="(item,index) in items":key="item.id">{{item}}</tr>

items:要遍历的数组

item:为遍历出来的元素

index:索引/下标,从0开始;

key:

作用:为元素添加唯一标识,便于vue进行列表项的正确排序复用,提升渲染性能

推荐使用id作为key(唯一)

v-bind

作用:动态为HTML标签绑定属性值,如设置href,src,style样式等

语法:v-bind:属性名="属性值"

简化::属性名=“属性值”

v-if &v-show

作用:这两类指令,都是用来控制元素的显示与隐藏的

v-if

  • 语法v-if="表达式",表达式的值为true,显示:false,隐藏
  • 原理:基于条件判断,来控制创建或移除元素节点
  • 场景:要么显示,要么不显示, 不频繁切换的场景

v-show

  • 语法:v-show="表达式",表达式的值为true,显示:false,隐藏
  • 原理:基于CSS样式display来控制显示与隐藏
  • 场景:频繁切换显示隐藏的场景

v-on

作用:为html标签绑定事件(添加事件监听)

语法:

v-on:事件名=“方法名”

简写为 @事件名="..."

v-model

  • v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定;
  • 它会根据控件类型自动选取正确的方法来更新元素;
  • 尽管如此, v-model 本质上是语法糖,它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理;

Ajax

作用:

数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据

异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想,用户名是否可用的校验等等

同步与异步

同步:客户端发起请求服务器,服务器处理,客户端等待,处理后返回客户端,客户端解除等待

异步:客户端发出请求后可以执行其他操作,服务器处理后返回

Axios

对原生的Ajax进行了封装,简化书写,快速开发

Ajax
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
    //发送GET请求
    document.querySelector('#btnGet').addEventListener('click',()=>{
        //axios发布异步请求
        axios({
            url:'https://mock.apifox.cn/m1/3083103-0-default/emps/list',
            method:'GET'
        }).then((result)=>{//成功回调函数
            console.log(result);
        }).catch((err)=>{//失败回调函数
            console.log(err);
        })

    })
    //发送POST请求
    document.querySelector('#btnPost').addEventListener('click',()=>{
        axios({
            url:'https://mock.apifox.cn/m1/3083103-0-default/emps/upda',
            method:'POST',
            data:{id:1}//Post请求方式
        }).then((result)=>{//成功回调函数
            console.log(result);
        }).catch((err)=>{//失败回调函数
            console.log(err);
        })
    })
</script>

项目结构

根组件

<script setup>

</script>

<template>
  <ElementDemo></ElementDemo>
  
</template>

<style scoped>

</style>

index.html

    • 这是项目的入口HTML文件
    • 包含基本的HTML结构和元信息
    • 通过 <script type="module" src="/src/main.js"></script> 引入了 main.js 文件
    • 提供了一个挂载点 <div id="app"></div> 用于渲染Vue应用
  1. src/main.js
    • 这是Vue应用的入口JavaScript文件
    • 使用 createApp 创建Vue应用实例
    • 导入并挂载 App.vue 组件到 #app 元素上
    • 导入全局样式文件 ./assets/main.css
  2. src/App.vue
    • 这是Vue应用的根组件
    • 使用 <script setup> 语法定义组件逻辑
    • 包含一个响应式数据 message
    • <template> 中显示 message 的值
    • 通过 main.js 被挂载到页面上

整体流程:index.html 加载 main.jsmain.js 创建Vue应用并挂载 App.vueApp.vue 组件被渲染到 index.html#app 容器中。

只有在需要字符串插值或换行时才会使用反引号(模板字符串)。

API

组合式API

<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ doubledCount }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'

// 响应式数据
const count = ref(0)
const message = ref('Hello')

// 计算属性
const doubledCount = computed(() => count.value * 2)

// 方法
const increment = () => {
  count.value++
}

const decrement = () => {
  count.value--
}

// 生命周期
onMounted(() => {
  console.log('组件已挂载')
})

// 监听器
watch(count, (newVal, oldVal) => {
  console.log(`count从${oldVal}变为${newVal}`)
})
</script>

选项式API

<template>
  <div>
    <p>{{ count }}</p>
    <p>{{ doubledCount }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

<script>
export default {
  // 数据选项
  data() {
    return {
      count: 0,
      message: 'Hello'
    }
  },
  
  // 计算属性
  computed: {
    doubledCount() {
      return this.count * 2
    }
  },
  
  // 方法
  methods: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    }
  },
  
  // 生命周期
  mounted() {
    console.log('组件已挂载')
  },
  
  // 监听器
  watch: {
    count(newVal, oldVal) {
      console.log(`count从${oldVal}变为${newVal}`)
    }
  }
}
</script>

为了避免出现域名问题,需要在配置文件中指定访问的IP和端口号,且需要在请求路径前加前缀,避免访问到静态资源

server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        secure: false,
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      }
    }
  }

发送请求和响应请求的逻辑以及结构

  1. 请求发送流程

  • 使用 axios 创建 request 实例,设置基础URL为 /api
  • 通过 request 实例的 HTTP 方法(get/post/put/delete)发送请求
  • 请求会自动加上 /api 前缀,例如 request.get('/depts') 实际访问 /api/depts
  1. 响应处理流程

  • request.interceptors.response.use() 设置了响应拦截器
  • 成功响应时,拦截器直接返回 response.data,即只返回实际数据部分
  • 失败响应时,拦截器将错误通过 Promise.reject(error) 向上抛出
  1. API 调用示例

queryAllApi 为例:

  • 调用 request.get('/depts') 发送 GET 请求

  • 请求地址实际为 /api/depts

  • 响应拦截器处理后,只返回数据部分给调用方

    处理数据部分时,在代码中采用async和await进行数据接收,对接受过来的数据进行处理,如果返回状态吗正确,输出相应提示信息

ElementPlus组件

参考文档

一个 Vue 3 UI 框架 | Element Plus

表格组件

<el-table :data="tableData" border style="width: 100%">
    <el-table-column prop="date" label="Date" width="180" align="center" />
    <el-table-column prop="name" label="Name" width="180" align="center" />
    <el-table-column prop="address" label="Address" align="center"/>
  </el-table>

prop为列属性,label为标签名字

弹窗表格

<div class="button-row">
    <el-button plain @click="dialogVisible = true"> Click to open the Dialog</el-button>
    <el-dialog v-model="dialogVisible" title="收获表格" width="800">
    <el-table :data="tableData">
      <el-table-column property="date" label="Date" width="150" />
      <el-table-column property="name" label="Name" width="200" />
      <el-table-column property="address" label="Address" />
    </el-table>
  </el-dialog>

分页组件

<div class="button-row">
    <el-pagination
      v-model:current-page="currentPage4"
      v-model:page-size="pageSize4"
      :page-sizes="[100, 200, 300, 400]"
      
      :background="background"
      layout="total, sizes, prev, pager, next, jumper"
      :total="400"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
   </div>

Vue Router

Vue Router 是 Vue 官方的客户端路由解决方案。

客户端路由的作用是在单页应用 (SPA) 中将浏览器的 URL 和用户看到的内容绑定起来。当用户在应用中浏览不同页面时,URL 会随之更新,但页面不需要从服务器重新加载。

Vue Router 基于 Vue 的组件系统构建,你可以通过配置路由来告诉 Vue Router 为每个 URL 路径显示哪些组件。

  1. Route
    • route 指的是单个路由规则,即你在 routes 数组里定义的对象
    • 每个 route 包含 path(路径)、name(名称)、component(对应渲染的组件) 等属性
    • 例如 {path: '/login', name: 'login', component: LoginView} 就是一个具体的 route 配置
  2. Router View
    • <router-view> 是一个 Vue 组件,作为路由出口,用来显示当前路由匹配到的组件
    • 当 URL 改变时,<router-view> 会自动更新为对应的组件内容
    • 在嵌套路由中(如你配置中的 children),子组件也会渲染在父级的 <router-view>
  3. Router Link
    • <router-link> 是一个特殊的组件,用于创建导航链接
    • 使用它可以在不重新加载整个页面的情况下切换不同的路由
    • 典型用法是设置 to 属性指向目标路由的路径或命名路由,例如 <router-link to="/login">Login</router-link>

watch

Watch监听函数主要用于:

  • 在数据变化时执行异步操作
  • 在数据变化时执行开销较大的操作
  • 监听特定数据的变化并执行相应逻辑
  • 实现数据验证、数据联动等复杂业务逻辑

基本语法

// 选项式API
watch: {
  // 简单监听
  被监听的数据(newValue, oldValue) {
    // 响应数据变化的逻辑
  },
  
  // 深度监听
  被监听的数据: {
    handler(newValue, oldValue) {
      // 响应数据变化的逻辑
    },
    deep: true, // 深度监听对象内部值的变化
    immediate: true // 立即执行一次handler
  }
}

// 组合式API
import { watch } from 'vue'

watch(
  被监听的数据,
  (newValue, oldValue) => {
    // 响应数据变化的逻辑
  },
  {
    deep: true,
    immediate: true
  }
)

1. Vue 3 Composition API 核心概念

setup 语法糖

javascript

<script setup>
// 所有内容都在setup中,无需return
import { ref, watch, onMounted } from 'vue'
  • 原理<script setup> 是编译时语法糖,内部声明的变量、函数自动暴露给模板
  • 优势:代码更简洁,无需手动返回响应式数据

响应式系统

javascript

const empList = ref([])
const searchEmp = ref({ name: '', gender: '' })

原理分析

  • ref() 将基本类型包装为响应式对象,通过 .value 访问
  • 在模板中自动解包,无需 .value
  • Vue 3 使用 Proxy 实现响应式,比 Vue 2 的 Object.defineProperty 更强大

2. 生命周期管理

javascript

onMounted(() => {
  search()           // 初始化数据
  queryAllDepts()    // 加载部门数据
  getToken()         // 获取认证token
})

生命周期流程

  1. onMounted → 组件挂载完成后执行
  2. 异步加载初始数据
  3. 确保DOM已渲染,可以安全操作DOM

3. 数据侦听器 (Watch)

简单侦听

javascript

watch(() => searchEmp.value.date, (newValue, oldValue) => {
  // 处理日期范围变化
})

深度侦听

javascript

watch(() => employee.value.exprList, (newValue, oldValue) => {
  // deep: true 启用深度侦听
  employee.value.exprList.forEach(item => {
    item.begin = item.exprDate[0]
    item.end = item.exprDate[1]
  })
}, { deep: true })

侦听器原理

  • 第一个参数:要侦听的响应式数据
  • 第二个参数:回调函数,数据变化时执行
  • 第三个参数:配置选项(deep, immediate等)

4. 异步编程与 API 调用

async/await 模式

javascript

const search = async () => {
  const result = await queryPageApi(
    searchEmp.value.name, 
    searchEmp.value.gender,
    searchEmp.value.begin,
    searchEmp.value.end,
    currentPage.value,
    pageSize.value
  )
  if (result.code) {
    empList.value = result.data.rows
    total.value = result.data.total
  }
}

异步编程知识点

  • async 函数返回 Promise
  • await 暂停异步函数执行,等待 Promise 完成
  • 错误处理通过 try-catch 或条件判断

5. 数组操作与函数式编程

数组方法应用

javascript

// 1. map - 数据转换
selectIds.value = val.map((item) => item.id)

// 2. forEach - 遍历操作
employee.value.exprList.forEach(item => {
  item.begin = item.exprDate[0]
  item.end = item.exprDate[1]
})

// 3. splice - 删除数组元素
employee.value.exprList.splice(index, 1)

// 4. push - 添加数组元素
employee.value.exprList.push({company:'', job:'', begin:'', end:'', exprDate:[]})

6. 表单处理与验证

Element Plus 表单验证

javascript

const rules = ref({
  username: [
    { required: true, message: '用户名是必填项', trigger: 'blur' },
    { min: 2, max: 10, message: '用户名的长度应该在2-10位之间', trigger: 'blur' },
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号', trigger: 'blur' },
  ]
})

验证规则详解

  • required: 必填字段
  • min/max: 长度限制
  • pattern: 正则表达式验证
  • trigger: 触发时机(blur、change)

表单提交验证

javascript

const save = async () => {
  empFormRef.value.validate(async (valid) => {
    if (valid) {
      // 验证通过,提交数据
      let result = employee.value.id 
        ? await updateApi(employee.value)
        : await addApi(employee.value)
      
      if (result.code) {
        ElMessage.success('保存成功')
        dialogVisible.value = false
        search()
      }
    } else {
      ElMessage.error('请填写必要的表单数据!')
    }
  })
}

7. 文件上传处理

javascript

// 上传成功回调
const handleAvatarSuccess = (response) => {
  employee.value.image = response.data
}

// 上传前验证
const beforeAvatarUpload = (rawFile) => {
  // 文件类型验证
  if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
    ElMessage.error('只支持上传图片')
    return false
  }
  // 文件大小验证
  else if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error('只能上传10M以内图片')
    return false
  }
  return true
}

8. 条件渲染与列表渲染

动态样式类

vue

<el-icon class="avatar-uploader-icon">
  <Plus />
</el-icon>

条件渲染

vue

<img v-if="employee.image" :src="employee.image" class="avatar">
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>

列表渲染

vue

<el-option v-for="g in genders" :key="g.value" :label="g.name" :value="g.value"></el-option>

<el-row v-for="(expr, index) in employee.exprList" :key="index">
  <!-- 动态生成工作经历表单项 -->
</el-row>

9. 事件处理

方法定义与调用

javascript

// 方法定义
const remove = (index) => {
  employee.value.exprList.splice(index, 1)
}

// 事件绑定
<el-button @click="remove(index)">- 删除</el-button>

事件修饰符

  • @click - 点击事件
  • @change - 值变化事件
  • @success - 成功事件(上传组件)

10. 组件通信与引用

模板引用

javascript

const empFormRef = ref()  // 创建引用

<el-form ref="empFormRef">  // 绑定引用

通过 ref 操作子组件

javascript

empFormRef.value.validate((valid) => {
  // 调用子组件方法
})

11. 本地存储操作

javascript

const getToken = async () => { 
  const loginToken = JSON.parse(localStorage.getItem('loginUser'))
  if (loginToken && loginToken.token) { 
    token.value = loginToken.token
  }
}

localStorage 操作

  • getItem(key) - 获取存储数据
  • setItem(key, value) - 设置存储数据
  • JSON.parse() - 解析JSON字符串
  • JSON.stringify() - 转换为JSON字符串

12. 弹窗与用户交互

确认对话框

javascript

const deleteID = async (id) => { 
  ElMessageBox.confirm(
    '您确认删除该部门吗?',
    '提示',
    {
      confirmButtonText: 'OK',
      cancelButtonText: 'Cancel',
      type: 'warning',
    }
  ).then(async () => {
    // 用户确认
    const result = await deleteApi(id)
    if (result.code) {
      ElMessage.success("删除成功")
      search()
    }
  }).catch(() => {
    // 用户取消
    ElMessage.info('您已经取消删除')
  })
}

关键 JavaScript 知识点总结

  1. ES6+ 语法:箭头函数、解构赋值、模板字符串
  2. 模块化:import/export 模块导入导出
  3. Promise 和异步编程:async/await 错误处理
  4. 数组方法:map、forEach、splice、push
  5. 对象操作:属性访问、方法调用
  6. 条件判断:if/else、三元运算符
  7. 函数作用域:闭包、this 指向
  8. 事件循环:宏任务、微任务执行顺序

这个组件展示了现代前端开发的典型模式:响应式数据绑定、组件化开发、异步数据流、表单处理等核心概念。

❌