Vue表单事件、数据绑定、事件修饰符、箭头函数

Vue表单事件、数据绑定、事件修饰符、箭头函数

表单事件

有一些事件使input标签特有的,有:

  • input --- 进行输入时触发
  • blur --- 失去焦点时触发
  • change --- 失去焦点并相较获取焦点时的值发生变化时触发
  • focus --- 获取焦点时触发
<div class="app">
    <h1>失去焦点</h1>
    <input type="text" @blur="handleBlur">
    <h1>input事件,只要输入,就会触发</h1>
    <input type="text" @input="handleInput">
    <h1>change事件</h1>
    <input type="text" @change="handleChange">
    <h1>focus事件</h1>
    <input type="text" @focus="handleFocus">
</div>

v-model双向数据绑定

在vue的一般数据绑定其实是单向的,因为大部分场景是由后端获取数据后实时的渲染到前端,所以默认检测vue._data中的变量值发生变化时让页面上对应的数据重新渲染即可。

而在表单场景中,标签获取用户的输入得到的数据是需要往数据层传输的,这时就需要用到双向数据绑定了,只需要在input标签中添加v-mode属性,v-mode的值与对应的数据层变量的数据就会建立双向绑定。

<div class="app">
    <h1>单向数据绑定</h1>
    <input type="text" :value="username">
    <h1>双向数据绑定</h1>
    <input type="password" v-model="password">
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            username: '请输入用户名',
            password:'请输入密码',
        },
    })
</script>

js箭头函数

箭头函数

  1. function(形参)
  2. 形参=>{函数子代码} --- 如果有形参,侧重于代码执行
  3. 形参=>函数返回值 --- 如果有形参,侧重于返回结果(返回结果可以是表达式)
  4. (形参1,形参2)=>函数返回值 --- 多个形参则用括号括起来即可

练习

利用表单要求用户输入,并根据输入内容过滤数组信息

要完成上述的请求,需要先了解过滤的方法,我们可以采取:

  • 数组.filter(元素=>true/false) 对数组的元素进行筛选

    内部为匿名函数,自动传入数组的每一个元素,当函数结果为true时保留元素。

  • 字符串.indexof(检索字符串) 对字符串的进行索引检索

    检索字符串与字符串做比较,返回检索到首字符位置,如果没有结果则返回-1

<div id="app">
    <input type="text" v-model="inputText" @input="getFilterArray">
    <p v-for="word in filterWord" :key="word">
        {{word}}
    </p>
</div>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            inputText: '',
            hotWord: [
                "怎么装机","怎么装一台机器","怎么养鸡",
                "怎会如此","鸡你太美","现有鸡还是现有蛋",
            ],
            filterWord: this.hotWord,
        },
        methods: {
            getFilterArray() {
                this.filterWord = this.hotWord.filter(word => word.indexOf(this.inputText)>=0)
            }
        },
    })
</script>

事件修饰符

常见修饰符

事件修饰符 释义
.stop 只处理自己的事件,父控件冒泡的事件不处理(阻止事件冒泡)
.self 只处理自己的事件,子控件冒泡的事件不处理
.prevent 阻止a链接的跳转
.once 事件只会触发一次(适用于抽奖页面)
点击查看事件修饰符演示代码
<div>
    <div class="app">
        <h1>事件修饰符stop,子控件不再冒泡给父控件</h1>
        <ul @click='handleUl'>
            <li @click.stop="handleLi">第一</li>
            <li>第二</li>
        </ul>

        <h1>事件修饰符self:只处理自己的事件,子控件的冒泡,不处理</h1>
        <ul @click.self='handleUl'>
            <li @click="handleLi">第一</li>
            <li>第二</li>
        </ul>

        <h1>prevent阻止a的跳转</h1>
        <a href="http://www.baidu.com" @click.prevent="handleA">点我看美女</a>

        <h1>once 只响应一次</h1>
        <button @click.once="handleClick">点我抽奖</button>
    </div>

</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {},
        methods: {
            handleLi() {
                console.log('li被点击了')
            },
            handleUl() {
                console.log('ul被点击了')
            },
            handleA() {
                console.log('a标签被点了')
                // 阻止a的跳转,自己决定要不要跳
                // 手动指定跳,这里可以增加确认框做一些简单的逻辑判断
                location.href = 'http://www.cnblogs.com'

            },
            handleClick() {
                console.log('我被点了')
            }
        }

    })
</script>

按键修饰符

按键事件:按键盘上的某个键,就会触发函数执行@keyup

按键修饰符:当某个按键被按下时触发

  • 预设的一些按键:@keyup.enter
  • 键盘按键对应数字码:@keyup.13

应用:按enter时向后端发送请求

<div id="app">
    <input type="text" v-model="text" @keyup.enter="handleKeyUp(1,$event)">
</div>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            text: ''
        },
        methods: {
            handleKeyUp2(a, event) {  // 可以定义一个形参接收事件对象
                console.log(event)
                console.log('向后端发送请求了')
            }
        }
    })

补充:事件触发函数时会自动传入事件对象,也可以自己编辑$event自己传入实参(这样可以自己选择传入位置)

v-model修饰符

  • lazy:等待input框的数据绑定时区焦点之后再变化
    用于减少没有必要的数据同步,相当于原本input事件触发同步,现在用失去焦点事件
  • number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留
  • trim:去除首尾的空格
    防止用户对输入空白时不自知

使用方式如下:

<input type="text" v-model.lazy="myText">

选项input标签

radio单选

type为radio的input标签的v-model对应键,value对应值

多个v-model相同的radio对应一个变量。

<p>性别:
    男<input type="radio" v-model="gender" value="1">
    女<input type="radio" v-model="gender" value="2">
</p>
----------------
data: {gender:''}   // radio单选,多个radio绑定同一个变量,选中某个,就对应value值

checkbox单选

type为checkbox的input标签的v-model对应键,value对应值,没有value则是bool值对应选中状态

<p>记住密码:<input type="checkbox" v-model="remember"></p>
------------------
data: {remember:false}    // checkbox的键定义为不可变类型则为单选结果

checkbox多选

type为checkbox的input标签的v-model对应键,value对应值。

多个v-model相同的checkbox对应一个变量,由数组存储多个选择值。

 <p>爱好:
     篮球:<input type="checkbox" v-model="hobby" value="篮球">
     足球:<input type="checkbox" v-model="hobby" value="足球">
     排球:<input type="checkbox" v-model="hobby" value="排球">
</p>
------------------
data: {hobby:[]}   // checkbox的键定义为数组则为多选结果

购物车结算案例

image

点击查看Vue代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
    <table class="table table-hover table-condensed">
        <thead>
        <tr>
            <th>商品名</th>
            <th>价格(元)</th>
            <th>购买数量</th>
            <th>
                <input type="checkbox" v-model="allSelect" @change="dispatchSelectAll">全选/全不选
            </th>
            <th>移除商品</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(shopping,index) in shoppingList" :key="shopping.id">
            <td>{{shopping.name}}</td>
            <td>{{shopping.price}}</td>
            <td>
                <button @click="numLose(shopping)">-</button>
                {{shopping.num}}
                <button @click="numAdd(shopping)">+</button>
                <span class="text-danger" style="position: absolute">{{upperLimitTip(shopping)}}</span>
            </td>
            <td><input type="checkbox" v-model="selectList" :value="shopping" @change="handlerSelectOne"></td>
            <td>
                <button @click="deleteShopping(index,shopping)">移除商品</button>
            </td>
        </tr>
        </tbody>
    </table>
    <br>
    <br>
    <p style="font-size: 50px;font-weight: bold;text-align: center">
        总和:{{getSum()}}元
    </p>
</div>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            allSelect: false,
            selectList: [],
            shoppingList: [
                {id: 1, name: "忘崽牛奶", price: 5.99, num: 2, storage: 15},
                {id: 2, name: "可口可乐", price: 3.80, num: 3, storage: 4},
                {id: 3, name: "乐事薯片", price: 8.50, num: 1, storage: 5},
            ],
            summary: 0
        },
        methods: {
            // 全选和全不选
            dispatchSelectAll() {
                this.selectList = this.allSelect ? this.shoppingList : []
            },
            // 选项发生变化的时候,让allSelect判断一下
            handlerSelectOne() {
                this.allSelect = this.selectList.length === this.shoppingList.length
            },
            // 当函数()被插值到界面中时,只要函数用到的数据发生了改变,它就会重新执行一次。
            getSum() {
                let total = 0
                for (let shop of this.selectList) {
                    total += shop.price * shop.num
                }
                return total
            },
			// 数字加减
            numAdd(shopping) {
                shopping.num < shopping.storage ? shopping.num++ : null
            },
            numLose(shopping) {
                shopping.num > 1 ? shopping.num-- : null
            },
			// 对数字的增加设置一个上限
            upperLimitTip(shopping) {
                return shopping.num === shopping.storage ? '库存只有这么多啦' : ''
            },
			// 移除商品时,注意两个数组都需要操作
            deleteShopping(index, shopping) {
                if (confirm('确定要移除这件商品吗?')) {
                    this.shoppingList.splice(index, 1)
                    let deleteNum = this.selectList.indexOf(shopping)
                    deleteNum >= 0 ? this.selectList.splice(deleteNum, 1) : 0
                }
            },
        },
    })
</script>

</body>
</html>
posted @ 2023-02-15 17:09  leethon  阅读(239)  评论(0编辑  收藏  举报