Vue笔记(三)--用户交互

这一节了解一下Vue3中的处理用户交互,处理用户交互实际就是对用户操作事件的监听和处理。在Vue中,使用v-on指令来进行事件的监听和处理,简单总结如下:

API

  1. @click / v-on:click

含义:点击事件绑定 作用:监听用户单击操作

javascript 复制代码
<template>
  <button @click="handleClick">点击测试</button>
</template>
<script setup>
const handleClick = () => uni.showToast({ title: '点击了' })
</script>
  1. 事件对象 $event /e

含义:系统自动传入事件对象 作用:获取输入值、鼠标位置、按键信息等

javascript 复制代码
<template>
  <input @input="onInput" placeholder="输入查看" />
</template>
<script setup>
const onInput = (e) => console.log(e.target.value)
</script>
  1. @dblclick 双击事件

含义:鼠标快速双击 作用:编辑、打开、快速操作

javascript 复制代码
<template>
  <view @dblclick="handleDblClick">双击我</view>
</template>
<script setup>
const handleDblClick = () => uni.showToast({ title: '双击触发' })
</script>
  1. @mousedown / @mouseup

含义:鼠标按下 / 抬起 作用:拖拽、长按、按钮按下效果

javascript 复制代码
<template>
  <view @mousedown="down" @mouseup="up">按下/抬起测试</view>
</template>
<script setup>
const down = () => console.log('按下')
const up = () => console.log('抬起')
</script>
  1. @mousemove 鼠标移动

含义:鼠标在元素内移动 作用:跟随效果、画板、坐标获取

javascript 复制代码
<template>
  <view class="box" @mousemove="move"></view>
</template>
<script setup>
const move = (e) => console.log('x:', e.clientX, 'y:', e.clientY)
</script>
<style>.box{width:300px;height:200px;background:#f5f5f5;}</style>
  1. @mouseover / @mouseout

含义:鼠标移入 / 移出 作用:悬浮显示、提示框

javascript 复制代码
<template>
  <view @mouseover="over" @mouseout="out">悬浮测试</view>
</template>
<script setup>
const over = () => console.log('移入')
const out = () => console.log('移出')
</script>
  1. @focus 输入框聚焦

含义:输入框被激活 作用:聚焦动画、清空提示、键盘弹出

javascript 复制代码
<template>
  <input @focus="onFocus" placeholder="点我聚焦" />
</template>
<script setup>
const onFocus = () => uni.showToast({ title: '已聚焦' })
</script>
  1. @blur 输入框失焦

含义:输入框失去焦点 作用:校验输入、隐藏键盘

javascript 复制代码
<template>
  <input @blur="onBlur" placeholder="失焦测试" />
</template>
<script setup>
const onBlur = () => uni.showToast({ title: '已失焦' })
</script>
  1. @change 内容改变

含义:输入完成后内容变化 作用:选择器、输入完成校验

javascript 复制代码
<template>
  <input @change="change" placeholder="输完离开触发" />
</template>
<script setup>
const change = (e) => console.log('改变:', e.target.value)
</script>
  1. @keyup 按键抬起

含义:键盘按键松开 作用:搜索、回车提交、快捷键

javascript 复制代码
<template>
  <input @keyup="keyup" placeholder="按键测试" />
</template>
<script setup>
const keyup = (e) => console.log('按键:', e.key)
</script>
  1. @keyup.enter 回车

含义:按下回车键 作用:表单提交、搜索、发送消息

javascript 复制代码
<template>
  <input @keyup.enter="enter" placeholder="按回车提交" />
</template>
<script setup>
const enter = () => uni.showToast({ title: '回车提交' })
</script>
  1. @keyup.esc 退出键

含义:按下 ESC 作用:关闭弹窗、取消操作

javascript 复制代码
<template>
  <input @keyup.esc="esc" placeholder="按ESC关闭" />
</template>
<script setup>
const esc = () => uni.showToast({ title: 'ESC 关闭' })
</script>
  1. .stop 阻止冒泡

含义:阻止事件向上传递 作用:子点击不触发父点击

javascript 复制代码
<template>
  <view @click="parent">
    父区域
    <view @click.stop="child">子区域(不冒泡)</view>
  </view>
</template>
<script setup>
const parent = () => console.log('父')
const child = () => console.log('子')
</script>
  1. .prevent 阻止默认行为

含义:阻止浏览器 / 系统默认动作 作用:阻止页面跳转、表单默认提交

javascript 复制代码
<template>
  <view @click.prevent="click">阻止默认行为</view>
</template>
<script setup>
const click = () => console.log('自定义处理')
</script>
  1. .capture 捕获模式

含义:事件由外向内先触发 作用:父优先拦截事件

javascript 复制代码
<template>
  <view @click.capture="parent">父捕获</view>
</template>
<script setup>
const parent = () => console.log('父优先触发')
</script>
  1. .once 只执行一次

含义:事件只触发一次作用:红包、首次引导、防重复

javascript 复制代码
<template>
  <button @click.once="once">只触发一次</button>
</template>
<script setup>
const once = () => uni.showToast({ title: '触发成功' })
</script>
  1. .self 仅点击自身触发

含义:只有点击元素本身才执行 作用:点击遮罩关闭、点击空白关闭

javascript 复制代码
<template>
  <view @click.self="self">点击空白有效</view>
</template>
<script setup>
const self = () => console.log('点击自身才触发')
</script>
  1. 多事件触发

含义:一次动作执行多个函数 作用:同时做两件事

javascript 复制代码
<template>
  <button @click="fn1(), fn2()">多事件</button>
</template>
<script setup>
const fn1 = () => console.log('事件1')
const fn2 = () => console.log('事件2')
</script>
  1. 点击节流(防重复)

含义:限制频繁点击 作用:防重复提交、防重复请求

javascript 复制代码
<template>
  <button @click="submit" :disabled="lock">提交</button>
</template>
<script setup>
import { ref } from 'vue'
const lock = ref(false)
const submit = () => {
  if (lock.value) return
  lock.value = true
  setTimeout(() => lock.value = false, 1000)
}
</script>
  1. 长按事件

含义:按住不动触发 作用:删除、多选、菜单

javascript 复制代码
<template>
  <view @longpress="long">长按测试</view>
</template>
<script setup>
const long = () => uni.showToast({ title: '长按触发' })
</script>

栗子:

javascript 复制代码
<template>
  <view class="p-4">
    <button @click="add" :disabled="lock">点击计数(节流){{ count }}</button>
    <view @click="parent" class="mt-4 p-2 border">
      父区域
      <view @click.stop="child" class="p-2 bg-gray-100">子区域(不冒泡)</view>
    </view>
    <input @keyup.enter="enter" placeholder="按回车提交" class="mt-4 border p-2" />
    <input @focus="focus" @blur="blur" placeholder="焦点测试" class="mt-2 border p-2" />
    <button @click.once="once" class="mt-4">只触发一次</button>
  </view>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
const lock = ref(false)

const add = () => {
  if (lock.value) return
  lock.value = true
  count.value++
  setTimeout(() => lock.value = false, 800)
}
const parent = () => console.log('父触发')
const child = () => console.log('子触发')
const enter = () => uni.showToast({ title: '回车提交' })
const focus = () => console.log('聚焦')
const blur = () => console.log('失焦')
const once = () => uni.showToast({ title: '成功触发一次' })
</script>

<style>
.p-4{padding:30rpx;}
.mt-4{margin-top:30rpx;}
.mt-2{margin-top:20rpx;}
.p-2{padding:20rpx;}
.border{border:1rpx solid #eee;}
.bg-gray-100{background:#f5f5f5;}
</style>
javascript 复制代码
<template>
  <view class="container">
    <view class="title">Demo</view>

    <view class="section">
      <text class="label">1. 点击计数</text>
      <button 
        type="primary" 
        @click="handleAdd" 
        :disabled="isLocked"
      >
        点击 +1 ({{ count }})
      </button>
    </view>

    <view class="section">
      <text class="label">2. 事件冒泡 </text>
      <view class="box-parent" @click="handleParentClick">
        父容器 (点击我)
        <view class="box-child" @click.stop="handleChildClick">
          子容器 (不冒泡)
        </view>
      </view>
    </view>

    <view class="section">
      <text class="label">3. 移动跟踪</text>
      <view 
        class="move-area" 
        @mousemove="handleMouseMove" 
        @touchmove="handleMouseMove"
      >
        <view 
          class="dot" 
          :style="{ left: x + 'px', top: y + 'px' }"
        ></view>
      </view>
      <text>X: {{x}}, Y: {{y}}</text>
    </view>

    <view class="section">
      <text class="label">4. 输入框交互</text>
      <input 
        v-model="inputText"
        class="input"
        placeholder="测试焦点/失焦/改变"
        @focus="handleFocus"
        @blur="handleBlur"
        @change="handleChange"
      />
      <text class="tip">{{ focusTip }}</text>
    </view>

    <view class="section">
      <text class="label">5. 键盘回车 (.enter)</text>
      <input 
        class="input"
        placeholder="按回车提交"
        @keyup.enter="handleEnter"
      />
    </view>

    <view class="section">
      <text class="label">6. 只触发一次 (.once)</text>
      <button @click.once="handleOnce">领取奖励</button>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
const isLocked = ref(false)
const handleAdd = () => {
  if (isLocked.value) return 
  isLocked.value = true
  count.value++
  setTimeout(() => isLocked.value = false, 800) 
}

const handleParentClick = () => uni.showToast({ title: '父容器触发', icon: 'none' })
const handleChildClick = () => uni.showToast({ title: '子容器触发', icon: 'none' })

const x = ref(150)
const y = ref(100)
const handleMouseMove = (e) => {
  x.value = e.clientX || e.touches[0].clientX
  y.value = e.clientY || e.touches[0].clientY
}

const inputText = ref('')
const focusTip = ref('请输入内容')
const handleFocus = () => focusTip.value = '已聚焦'
const handleBlur = () => focusTip.value = ' 已失焦'
const handleChange = () => uni.showToast({ title: '内容已修改', icon: 'none' })

const handleEnter = () => uni.showToast({ title: '回车提交成功!' })
const handleOnce = () => uni.showToast({ title: '奖励领取成功!', icon: 'success' })
</script>

<style scoped>
.container {
  padding: 30rpx;
}
.title {
  font-size: 36rpx;
  font-weight: bold;
  text-align: center;
  margin-bottom: 40rpx;
}
.section {
  margin-bottom: 40rpx;
}
.label {
  font-size: 28rpx;
  font-weight: bold;
  margin-bottom: 15rpx;
  display: block;
}
.box-parent {
  width: 100%;
  height: 200rpx;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10rpx;
}
.box-child {
  width: 200rpx;
  height: 100rpx;
  background-color: #42b983;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10rpx;
}
.move-area {
  width: 100%;
  height: 300rpx;
  background-color: #f9f9f9;
  position: relative;
  border-radius: 10rpx;
  overflow: hidden;
}
.dot {
  width: 40rpx;
  height: 40rpx;
  background-color: red;
  border-radius: 50%;
  position: absolute;
  transform: translate(-50%, -50%);
}
.input {
  border: 1rpx solid #eee;
  padding: 20rpx;
  border-radius: 10rpx;
  font-size: 28rpx;
}
.tip {
  font-size: 24rpx;
  color: #666;
  margin-top: 10rpx;
  display: block;
}
button {
  margin-top: 10rpx;
}
</style>
相关推荐
Martin -Tang1 小时前
uniapp 实现录音操作,长按录音,放开取消
前端·javascript·vue.js·uni-app·css3·录音
网络工程小王1 小时前
【大模型vLLM 使用】学习笔记
笔记·学习·llama
Genevieve_xiao2 小时前
【xjtuse】【数学建模】课程笔记(四)种群模型(微分方程稳定性)、随机模型、贝叶斯
笔记·数学建模
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_58:(构建行星数据表——HTML表格高级实战指南)
前端·javascript·ui·html·音视频
kyriewen2 小时前
用户打开飞行模式都能打开你的网站?Service Worker 做离线缓存,PWA 实战
前端·javascript·面试
栉甜2 小时前
APIs学习
前端·javascript·css·学习·html
羊群智妍2 小时前
2026企业GEO优化:AI搜索优化工具实测对比
笔记
Hello_Embed2 小时前
USB 学习指南+软硬件框架
网络·笔记·stm32·嵌入式·ai编程
zithern_juejin2 小时前
ES6——Symbol
javascript