二、Vue基础语法学习笔记——事件监听v-on、条件判断(v-if、v-else-if、v-else、v-show)、循环遍历(v-for遍历数组对象,key属性、检测数组更新)、图书案例、双向绑定

四、事件监听

在前端开发中,我们需要经常和用于交互。
这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等
在Vue中如何监听事件呢?使用v-on指令

v-on介绍
作用:绑定事件监听器
缩写:@
预期:Function | Inline Statement | Object
参数:event

下面,我们就具体来学习v-on的使用。

1.v-on基础

这里,我们用一个监听按钮的点击事件,来简单看看v-on的使用
下面的代码中,
我们使用了v-on:click="counter++”
另外,我们可以将事件指向一个在methods中定义的函数
在这里插入图片描述
在这里插入图片描述

注:v-on也有对应的语法糖:
v-on:click可以写成@click

2.v-on参数

当通过methods中定义方法,以供@click调用时,需要注意参数问题:

  • 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
    但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去

  • 情况二:如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

3.v-on修饰符

在某些情况下,我们拿到event的目的可能是进行一些事件处理。

Vue提供了修饰符来帮助我们方便的处理一些事件:

  1. stop - 调用 event.stopPropagation()。
  2. prevent - 调用 event.preventDefault()。
  3. {keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  4. native - 监听组件根元素的原生事件。
  5. once - 只触发一次回调。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

五、条件判断

1. v-if、v-else-if、v-else

v-if、v-else-if、v-else

  • 这三个指令与JavaScript的条件语句if、else、else if类似。
  • Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

简单的案例演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
v-if的原理:

  • v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
  • 也就是根本没有不会有对应的标签出现在DOM中。

条件渲染案例:
我们来做一个简单的小案例:
用户再登录时,可以切换使用用户账号登录还是邮箱地址登录。
类似如下情景:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
案例中存在的小问题:

小问题:
如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容。
但是按道理讲,我们应该切换到另外一个input元素中了。
在另一个input元素中,我们并没有输入内容。
为什么会出现这个问题呢?

问题解答:
这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。
在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。

解决方案:

  • 如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key
  • 并且我们需要保证key的不同
    在这里插入图片描述

2. v-show

v-show的用法和v-if非常相似,也用于决定一个元素是否渲染

v-if和v-show对比

v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢?

  • v-if当条件为false时,压根不会有对应的元素在DOM中。
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已。

开发中如何选择呢?

  • 当需要在显示与隐藏之间切片很频繁时,使用v-show
  • 当只有一次切换时,通过使用v-if

六、循环遍历

1.v-for遍历数组

当我们有一组数据需要进行渲染时,我们就可以使用v-for来完成。

v-for的语法类似于JavaScript中的for循环。
格式如下:item in items的形式。

我们来看一个简单的案例:

  • 如果在遍历的过程中不需要使用索引值
    v-for="item in names"
    依次从names中取出item,并且在元素的内容中,我们可以使用Mustache语法,来使用item

  • 如果在遍历的过程中,我们需要拿到元素在数组中的索引值呢?
    语法格式:v-for=(item, index) in items
    其中的index就代表了取出的item在原数组的索引值。
    在这里插入图片描述
    在这里插入图片描述

2.v-for遍历对象

v-for可以用户遍历对象:
比如某个对象中存储着你的个人信息,我们希望以列表的形式显示出来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.组件的key属性

key的作用主要是为了高效的更新虚拟DOM
在这里插入图片描述

4.检测数组更新

因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。

  1. push() :在数组最后面添加元素,可传入1个或者多个参数
  2. pop():删除数组中的最后一个元素
  3. shift():删除数组中的第一个元素
  4. unshift():在数组最前面添加元素
  5. splice():删除元素/插入元素/替换元素
  6. sort():正序排列
  7. reverse():倒序排列
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <ul>
        <li v-for="item in letters">{
   
   {item}}</li>
    </ul>

    <button @click="btnClick">按钮</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
     
     
        el: '#app',
        data: {
     
     
            letters: ['A','B','C','D','E']
        },
        methods:{
     
     
            btnClick() {
     
     
                // 0注意:通过索引值修改数组中的元素(无法做到响应式,数组的内容改变时页面内容不会响应式变化)
                // this.letters[0] = 'bbbb'

                /*以下几种改变数组的方法是响应式的*/
                // 1.push方法
                // this.letters.push('AAA');
                // this.letters.push('AAA','bbbb');

                // 2.pop():删除数组中的最后一个元素
                // this.letters.pop();

                // 3.shift():删除数组中的第一个元素
                // this.letters.shift();

                // 4.unshift():在数组最前面添加元素
                // this.letters.unshift('aaaa');
                // this.letters.unshift('aaaa','BBBB');

                // 5.
                // splice的作用:删除元素/插入元素/替换元素
                // 删除元素:第二个参数传入 你要删除几个元素(如果没有传参数,就删除后面所有的元素)
                // 替换元素:第二个参数,表示我们要替换几个元素,后面的参数是用来替换前面的元素
                // 插入元素:第二个参数,传入0,并且后面跟上要插入的元素
                // splice(start):
                // this.letters.splice(2,2,'ab','cz');
                // this.letters.splice(2,0,'X','Y')

                // 6.sort()
                // this.letters.sort()

                // 7.reverse()
                // this.letters.reverse()

                // set(要修改的对象,索引值,修改后的值)
                Vue.set(this.letters,0,'bbbbbbbb')
            }
        }
    })
</script>

</body>
</html>

七、阶段案例

图书购物车
在这里插入图片描述
代码实现:HTML、CSS:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

<div id="app">
    <div v-if="books.length">
        <table>
            <thead>
            <tr>
                <th></th>
                <th>书籍名称</th>
                <th>出版日期</th>
                <th>价格</th>
                <th>购买数量</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(item,index) in books">
                <td>{
   
   {item.id}}</td>
                <td>{
   
   {item.name}}</td>
                <td>{
   
   {item.date}}</td>
                <!--                <td>{
    
    {'¥' + item.price.toFixed(2)}}</td>-->
                <!--                <td>{
    
    {getFinalPrice(item.price)}}</td>-->
                <td>{
   
   {item.price | showPrice}}</td>
                <td>
                    <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
                    {
   
   {item.count}}
                    <button @click="increment(index)">+</button>
                </td>
                <td>
                    <button @click="removeHandle(index)">移除</button>
                </td>
            </tr>

            </tbody>
        </table>
        <h2>总价格:{
   
   {totalPrice | showPrice}}</h2>
    </div>
    <h2 v-else>购物车为空!</h2>
</div>

<script src="../js/vue.js"></script>
<script src="main.js"></script>
</body>
</html>
table {
    
    
    border: 1px solid #e9e9e9;
    border-collapse: collapse;
    border-spacing: 0;
}

th, td {
    
    
    padding: 8px 16px;
    border: 1px solid #e9e9e9;
    text-align: center;
}

th {
    
    
    background-color: #f7f7f7;
    color: #5c6b77;
    font-weight: 600;
}
const app = new Vue({
    
    
    el:'#app',
    data:{
    
    
        books: [
            {
    
    
                id: 1,
                name: '《Python入门》',
                date: '2020-10',
                price: 85.00,
                count: 36
            },
            {
    
    
                id: 2,
                name: '《Vue从入门到精通》',
                date: '2020-10',
                price: 99.00,
                count: 22
            },
            {
    
    
                id: 3,
                name: '《算法导论》',
                date: '2020-08',
                price: 32.00,
                count: 10
            },
            {
    
    
                id: 4,
                name: '《软件工程》',
                date: '2020-02',
                price: 105.00,
                count: 50
            }
        ]
    },
    methods: {
    
    
        getFinalPrice(price) {
    
    
            return '¥' + price.toFixed(2);
        },
        increment(index) {
    
    
            console.log('increment',index);
            this.books[index].count++;

        },
        decrement(index) {
    
    
            console.log('decrement',index);

            this.books[index].count--;
        },
        removeHandle(index) {
    
    
            this.books.splice(index,1);
        }
    },
    filters: {
    
    
        showPrice(price) {
    
    
            return '¥' + price.toFixed(2);
        }
    },
    computed: {
    
    
        totalPrice() {
    
    
            /*// 1. 普通的for循环
            let totalPrice = 0;
            for (let i = 0; i < this.books.length; i++) {
                totalPrice += this.books[i].price * this.books[i].count;
            }
            return totalPrice;*/

            /*// 2. for(let i in this..books)
            let totalPrice = 0;
            for (let i in this.books) {
                totalPrice += this.books[i].price * this.books[i].count;
            }
            return totalPrice;*/

            /*// 3. for(let item of this.books)
            let totalPrice = 0;
            for (let item of this.books) {
                totalPrice += item.price * item.count;
            }
            return totalPrice;*/

            // 4.reduce
            return this.books.reduce(function (preValue,book) {
    
    
                return preValue + book.price * book.count
            },0)

        }
    }

})


// 编程范式:命令式编程/声明式编程
// 编程范式:面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)
// filter /map /reduce
// filter 中的回调函数有一个要求:必须返回一个boolean值
// true :当返回true时,函数内部会自动将这次回调的n加入到心得数组中
// false:当返回false时,函数内部会过滤掉这次的n
const nums = [10,20,111,222,444,40,50]

/*let total = nums.filter(function (n) {
    return n < 100;
}).map(function (n) {
    return n * 2;
}).reduce(function (preValue,n) {
    return preValue + n;
},0)
console.log(total);*/
let total = nums.filter(n => n < 100)
    .map(n => n * 2)
    .reduce((preValue,n) => preValue + n)
console.log(total);
/*
// 1. filter函数的使用
// 10, 20, 40, 50
let newNums = nums.filter(function (n) {
    return n < 100;
})
console.log(newNums);

// 2. map函数的使用
// 20,40,80,100
let new2Nums = newNums.map(function (n) {
    return n*2;
})
console.log(new2Nums);

// 3. reduce函数的使用
//    educe函数的作用:对数组中所有的内容进行汇总
/!*
// new2Nums.reduce(function (preValue,n) {
//     return 100;
// },0)
// 第一次:preValue=0,n=20
// 第二次:preValue=100,n=40
// 第三次:preValue=100,n=80
// 第四次:preValue=100,n=100
*!/

let total = new2Nums.reduce(function (preValue,n) {
    return preValue + n;
},0)
// 第一次:preValue=0,n=20
// 第二次:preValue=20,n=40
// 第三次:preValue=60,n=80
// 第四次:preValue=140,n=100
// 第五次:preValue + n=240
console.log(total);
*/

八、双向绑定v-model

1.表单绑定v-model

表单控件在实际开发中是非常常见的。
特别是对于用户信息的提交,需要大量的表单。
Vue中使用v-model指令来实现表单元素和数据的双向绑定。

案例的解析:

  • 当我们在输入框输入内容时
    因为input中的v-model绑定了message,所以会实时将输入的内容传递给message,message发生改变。
  • 当message发生改变时,因为上面我们使用Mustache语法,将message的值插入到DOM中,所以DOM会发生响应的改变。
  • 所以,通过v-model实现了双向的绑定。

在这里插入图片描述
在这里插入图片描述

  • 当然,我们也可以将v-model用于textarea元素
    在这里插入图片描述

2.v-model原理

v-model其实是一个语法糖,它的背后本质上是包含两个操作:

  1. v-bind绑定一个value属性
  2. v-on指令给当前元素绑定input事件
  • 也就是说下面的代码:等同于下面的代码:
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" 
	v-on:input="message = $event.target.value">

在这里插入图片描述
在这里插入图片描述

3.v-model:radio

  • 当存在多个单选框时
    在这里插入图片描述
    在这里插入图片描述

4.v-model:checkbox

复选框分为两种情况:单个勾选框和多个勾选框

  1. 单个勾选框:
    v-model即为布尔值。
    此时input的value并不影响v-model的值。

  2. 多个复选框:
    当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
    当选中某一个时,就会将input的value添加到数组中。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

5.v-model:select

和checkbox一样,select也分单选和多选两种情况。
单选:只能选中一个值。

  • v-model绑定的是一个值。
    当我们选中option中的一个时,会将它对应的value赋值到mySelect中
  • 多选:可以选中多个值。
    v-model绑定的是一个数组。
    当选中多个值时,就会将选中的option对应的value添加到数组mySelects中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.值绑定

初看Vue官方值绑定的时候,我很疑惑:what the hell is that?
但是仔细阅读之后,发现很简单,就是动态的给value赋值而已:
我们前面的value中的值,可以回头去看一下,都是在定义input的时候直接给定的。
但是真实开发中,这些input的值可能是从网络获取或定义在data中的。

所以我们可以通过v-bind:value动态的给value绑定值。
这不就是v-bind吗?

这不就是v-bind在input中的应用吗?搞的我看了很久,搞不清他想讲什么。
这里不再给出对应的代码,因为会用v-bind,就会值绑定的应用了。
在这里插入图片描述
在这里插入图片描述

7.修饰符

  1. lazy修饰符:

默认情况下,v-model默认是在input事件中同步输入框的数据的。 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。

lazy修饰符可以让数据在失去焦点或者回车时才会更新

  1. number修饰符:

默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。

number修饰符可以让在输入框中输入的内容自动转成数字类型

  1. trim修饰符:

如果输入的内容首尾有很多空格,通常我们希望将其去除

trim修饰符可以过滤内容左右两边的空格

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44827418/article/details/112969697