04_事件监听、条件判断及循环的使用

  • 事件监听 v-on:
    • 语法糖形式:@
    • 参数:event
    • 作用:绑定事件监听器
    • 注意事项:在传入参数时,有以下几种情况需要特别注意(见代码中的注释部分)并且在传入 event 作为参数的时候,要加$,即$event
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="container">
        <!-- 1.本身不需要传参时  加不加() 结果都一样 -->
        <button @click="btn1()">按钮一</button>
        <button @click="btn1">按钮一</button>

        <!-- 2.本身需要传参时 1).只写了()没传参 显示undefined  2). ()都没写 会把event打印出来-->
        <button @click="btn2()">按钮二</button>
        <button @click="btn2">按钮二</button>

        <!-- 3.本身既需要传入event 又需要传入其它参数  1)只写了()没传参 显示两个undefined 2).()都没写 会把event打印出来
                另一个显示undefined 3).只写了data那个参数,event没写 报错显示两个undefined  4).只写了$event 会显示event
                和undefined -->
        <button @click="btn3()">按钮三</button>
        <button @click="btn3">按钮三</button>
        <button @click="btn3($event)">按钮三</button>

    </div>
    <script src="./vue.js"></script>
    <script>
        const app = new Vue({
            el: '#container',
            methods: {
                btn1() {
                    console.log('btn1 start');
                },
                btn2(data) {
                    console.log(data);
                },
                btn3(data, event) {
                    console.log(data, event);
                }
            }
        })
    </script>
</body>

</html>
  • 修饰符:修饰符主要有以下四种 1. .strop:阻止冒泡,例如在一个 div 中包含一个 button,并且在 div 和 button 上都绑定有点击事件,当点击 button 时 div 中的点击事件也相应的触发,如果我们不希望它触发,可以使用本修饰符,详情可以见下面例子 2. .prevent:阻止默认事件,一般是阻止表单中的 submit,由自己的方法进行提交时使用,详情可以见下面例子 3. .{keyCode|keyAlias}:阻止键盘事件,阻止键盘事件,并且以自己希望的某一个按键触发,详情可以见下面例子 4. .once:只触发一次回调 详情可以见下面例子
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="container">
        <div @click='div' id="box">
            <!-- 1. .stop 阻止冒泡 -->
            <button @click.stop='btn1' id="btn1">按钮一</button>
        </div>
        <br />
        <form>
            <!-- 2. .prevent 阻止默认事件 -->
            <input type='submit' @click.prevent='btn2'>
        </form>
        <!-- 3. .{keyCode|keyAlias} 阻止键帽只对设置的起作用 -->
        <input type="text" @keyup.enter='btn3'>
        <!-- 4. .once 只触发一次回调 -->
        <button @click.once='btn4'>按钮4</button>
    </div>
    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#container',
            methods: {
                btn1() {
                    console.log('btn1');
                },
                div() {
                    console.log('div');
                },
                btn2() {
                    console.log('submit');
                },
                btn3() {
                    console.log('阻止键帽')
                },
                btn4() {
                    console.log('btn4');
                }
            }
        })
    </script>
</body>

</html>
  • 条件判断,由于这个和以前的 if 语句差不多,就直接看案例吧 1. v-if 2. v-else 3. v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="container">
        <h1 v-if='score>90'>优秀</h1>
        <h1 v-else-if='score>=70'>良好</h1>
        <h1 v-else-if='score>=60'>及格</h1>
        <h1 v-else>不及格</h1>

    </div>
    <script src="./vue.js"></script>
    <script>
        const app = new Vue({
            el: '#container',
            data: {
                score: 50
            }
        })
    </script>
</body>
</html>

当然我们一般不会这么写,只是为了体现 v-if 的使用,一般都会另写函数进行判断。 案例一:实现点击切换登录按钮,将默认的账号登陆变为邮箱登录,见代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="container">
        <span v-if='isUser'>
            <label for="username">账号登陆</label>
            <input type="text" placeholder="账号登陆" id="username" key='username'>
        </span>
        <span v-else>
            <label for="username">邮箱登陆</label>
            <input type="text" placeholder="邮箱登陆" id="email" key='email'>
        </span>
        <button @click='isUser = !isUser'>切换登录</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        const app = new Vue({
            el: '#container',
            data: {
                isUser: true
            }
        })
    </script>
</body>

</html>

问题:当我们点击切换登录按钮时,虽然它确实切换成邮箱登录,但是如果已经在 input 标签中写有内容,这时候内容并不会清空,这是为什么? :很显然,vue 在处理整个页面的时候,并没有重新渲染整个页面,而是出于性能考虑,会尽可能的服用已经存在的元素,而不是重新创建新的元素,vue 中通过 diff 算法,会比较两次的不同再进行渲染,所以我们只需在 input 标签中添加 key,并且保证两个 input 标签中的 key 不相同即可,vue 就会帮助我们重新渲染这个标签。 这里同时引出了另一个知识点,就是 v-show 的使用,大致和 v-if 是差不多的,都是用来控制一个元素是否进行显示的下面介绍一下两者的区别

 - v-if:当条件为false时,根本就不会存在与dom中
 - v-show:当条件为false时,v-show只是给元素增加了 display:none ,从而使其隐藏

这些我们可以通过开发者模式中看出来,那么如何选择呢? 当我们的显示与隐藏的频率特别高时,使用 v-show; 当我们的频率特别低时,使用 v-if

  • 循环,这部分内容也较简单,直接贴代码了
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="container">
        <!-- 1.遍历数组 格式:(index,attr)-->
        <p v-for='(attr,index)  in books'>{{index}}-{{attr}}</p>
        <!-- 2.遍历对象 格式: (value,key,index)-->
        <p v-for='(attr,value,index) in students'>{{attr}}-{{value}}-{{index}}</p>
    </div>
    <script src="./vue.js"></script>
    <script>
        const app = new Vue({
            el: '#container',
            data:{
                books: ['php开发教程','java开发教程','c语言开发教程','python开发教程'],
                students: {
                    name: 'beanBag',
                    age: 22
                }
            }
        })
    </script>
</body>
</html>

这里有几点值得注意的就是,官方推荐我们在使用 v-for 的时候,最好是添加 :key,这样可以是我们更高效的更新虚拟 DOM,key 值和后面跟着的数据的名称相同 例如

`<li v-for='attr in books' :key='attr'>{{attr}}</li> `;

至于为什么,我的理解是当我们进行例如插入的操作时,如果没有指定 key 值,那么原来的 key 和 value 之间的配对关系会被重新分配,从而增加了开销,如果指定了 key 值,那么 key 和 value 之间的配对关系不会重新分配,而是只增加插入元素的配对关系,节约了开销。


最后补充一个知识点,数组中有些方法即使你改变了数组中的值,页面上也不会马上渲染出来,比如通过索引值直接修改数组中的元素,这点在下面那个购物车案例中,体现尤为明显。那么哪些方法是响应式的呢?

  1. push 在数组当中的末尾增加元素
  2. pop 删除数组中的末尾元素
  3. shift 删除数组中的首位元素
  4. unshift 在数组当中的首位添加元素
  5. splice 可以对数组进行删除/替换/插入操作,较为强大
  6. sort 对数组进行排序 d
  7. reverse 翻转数组

这里对 splice 方法进行一下说明,因为使用的较多

  1. 删除:第一个参数表示从哪一个元素开始,第二个参数表示你要删除几个元素,第三个参数如果没传则删除后面的所有元素;
  2. 替换:第一个参数表示从哪一个元素开始,第二个参数表示你哟啊替换几个元素,第三个参数是用来替换的元素;
  3. 插入:第一个参数表示从哪一个元素开始,第二个参数为 0,第三个参数为要的元素。

在 vue 中还有一个方法可以是响应式的修改数组中的数据 Vue.set(要修改的对象,索引值,修改后的值)

学完以上的知识后,可以实现一个案例,就是购物车案例,这里我另贴一篇博客好了,见链接( https://blog.csdn.net/qq_43709292/article/details/104240962 )。

Last Updated:
Contributors: hqchqc