Vue入门(一)之作用域、v-on事件监听、条件判断、书籍购物车、高阶函数(filter、map、reduce)

上一篇文章> Vue入门与安装

一、块级作用域(let和var)


1、块级作用域问题(ES5)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
    var btns = document.getElementsByTagName('button');
    for (var i=0;i<btns.length; i++) {
        // 闭包可以解决,但是太麻烦,函数一个作用域
        btns[i].addEventListener('click', function () {
            console.log('第'+ i + '个按钮被点击')
        })
    }
</script>
</body>
</html>

2、作用域解决(ES6)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
//    var btns = document.getElementsByTagName('button');
//    for (var i=0;i<btns.length; i++) {
          // 闭包可以解决,但是太麻烦,函数一个作用域
//        btns[i].addEventListener('click', function () {
//            console.log('第'+ i + '个按钮被点击')
//        })
//    }
    const btns = document.getElementsByTagName('button');
    for (let i = 0; i < btns.length; i++){
        btns[i].addEventListener('click', function () {
            console.log('第'+ i + '个按钮被点击')
        })
    }
</script>
</body>
</html>

3、const使用

使用const修饰的标识符为常量,不可以再次赋值,只有需要改变标识符的时候才使用let

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
//    1、不可以修改
//    const name = 'yyy';
//    name = 'abc'
//
//    2、const定义标识符,必须赋值
//    const name;

//    3、 常量的含义是指向的对象不能修改,但是可以改变对象内部的属性
    const obj = {
        name: 'yyy',
        age: 18,
        height: 180
    };
    obj.name = 'kobe';
    obj.age = 30;
    obj.height = 1.70;
    console.log(obj);
</script>
</body>
</html>

在这里插入图片描述

4、对象字面量的增强写法

<1> 属性增强写法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
//    const obj = {
//        name: 'yyy',
//        age: 18,
//        run: function () {
//            console.log('run')
//        }
//    }
    // 属性的增强写法
    const name  = 'yyy';
    const age = 18;
    const height = 1.88;

    // ES5写法
//    const obj = {
//        name: name,
//        age: age,
//        height: height
//    }
    
    // ES6写法
    const obj = {
        name,
        age,
        height
    };

    console.log(obj);
</script>
</body>
</html>
<2> 函数增强写法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
//    const obj = {
//        name: 'yyy',
//        age: 18,
//        run: function () {
//            console.log('run')
//        }
//    }

    // 函数的增强写法
    //ES5写法
//    const obj = {
//        run: function () {
//            
//        },
//        eat: function () {
//            
//        }
//    }
    
    // ES6写法
    const obj = {
        run() {
            
        },
        eat() {
            
        }
    }
</script>
</body>
</html>

二、v-on事件监听


1、v-on的基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{counter}}</h1>
    <!--<button v-on:click="counter++">+</button>-->
    <!--<button v-on:click="counter--">-</button>-->
    <button v-on:click="increment">+</button>
    <!--语法糖写法-->
    <button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            counter: 0
        },
        methods: {
            increment() {
                this.counter++
            },
            decrement() {
                this.counter--
            }
        }
    })
</script>
</body>
</html>

在这里插入图片描述

2、v-on参数问题

如果该方法不需要额外参数,那么方法后的()可以不添加
如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--事件调用的方法没有参数-->
    <button @click="btn1Click">按钮1</button>
    <button @click="btn1Click()">按钮1</button>

    <!--在事件定义时,写方法时省略了小括号,但是本身是需要一个参数,这个时候,
    Vue会默认将浏览器生成的event事件对象作为参数传入到方法中-->
    <button @click="btn2Click('btn2Click')">按钮2</button>
    <button @click="btn2Click()">按钮2</button>
    <!--这样会传入event事件-->
    <button @click="btn2Click">按钮2</button>

    <!--同时需要event对象,又需要参数, 需要手动获取event对象:$event-->
    <button @click="btn3Click">按钮3</button>
    <button @click="btn3Click('abc', $event)">按钮3</button>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        },
        methods: {
            btn1Click() {
                console.log('btn1Click');
            },
            btn2Click(event) {
                console.log('----------',event);
            },
            btn3Click(abc, event) {
                console.log('@@@@@@@@@@',abc, event)
            }
        }
    })
</script>
</body>
</html>

3、v-on的修饰符

(1).stop

阻止事件冒泡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<div>
    <div @click="divClick">
        aaa
        <button @click.stop="btnClick">按钮</button>
    </div>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        },
        methods: {
            btnClick() {
                console.log("btnClick");
            },
            divClick() {
                console.log('divClick')
            }
        }
    })
</script>
</body>
</html>

在这里插入图片描述

(2).prevent

阻止默认行为

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<div>
    <form action="baidu">
        <input type="submit" value="提交" @click.prevent="submitClick">
    </form>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        },
        methods: {
            submitClick() {
                console.log('submitClick');
            }
        }
    })
</script>
</body>
</html>
(3).键别名

这里用enter键做演示,不加.enter时,只要松开按键,都会打印console.log,加入.enter后只有松开enter键才会

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<div>
    <!--监听某个键盘键点击-->
    <input type="text" @keyup.enter="keyUp">
</div>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        },
        methods: {
            keyUp() {
                console.log('keyup');
            }
        }
    })
</script>
</body>
</html>
(4).once

只能调用一次

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
<div>
    <!--.once-->
    <button @click.once="btn2Click">按钮2</button>
</div>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        },
        methods: {
            btn2Click() {
                console.log('btn2Click');
            }
        }
    })
</script>
</body>
</html>

三、条件判断


1、v-if使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1 v-if="false">{{message}}</h1>
    <h1 v-if="true">{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    })
</script>
</body>
</html>

2、v-if和v-else使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1 v-if="isShow">
        {{message}}
    </h1>
    <h1 v-else>isShow为false</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue',
            isShow: true
        }
    })
</script>
</body>
</html>

3、v-if和v-else-if和v-else使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1 v-if="score>=90">优秀</h1>
    <h1 v-else-if="score>=80">良好</h1>
    <h1 v-else-if="score>=60">及格</h1>
    <h1 v-else>不及格</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            score: 98
        }
    })
</script>
</body>
</html>

4、用户登录切换案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <span v-if="isUser">
        <label for="username">用户账号</label>
        <input type="text" id="username" placeholder="用户账号">
    </span>
    <span v-else>
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="用户邮箱">
    </span>
    <button @click="isUser = !isUser">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            isUser: true
        }
    })
</script>
</body>
</html>

在这里插入图片描述
如果不想input进行复用,就添加不用的key
在这里插入图片描述

5、v-show使用

频率高的切换就使用v-show,否则v-if

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--v-if: 当条件为flalse时,包含v-if指令的元素,不会存在dom中-->
    <!--v-show: 当条件为false时,v-show只是给我们元素添加了一个行内样式 ==> display: none-->
    <h1 v-if="isShow" id="a">{{message}}</h1>
    <h1 v-show="isShow" id="b">{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue',
            isShow: true
        }
    })
</script>
</body>
</html>

四、循环遍历


1、v-for遍历数组

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--没有使用索引值-->
    <ul>
        <li v-for="item in names">{{item}}</li>
    </ul>
    <!--获取索引值-->
    <ul>
        <li v-for="(item,index) in names">{{index+1}}.{{item}}</li>
    </ul>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            names: ['kobe', 'james']
        }
    })
</script>
</body>
</html>

在这里插入图片描述

2、v-for遍历对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--获取一个值,那么获取的是value-->
    <ul>
        <li v-for="item in info">{{item}}</li>
    </ul>
    <!--获取key和value ==> (value,key)-->
    <ul>
        <li v-for="(value,key) in info">{{value}}-{{key}}</li>
    </ul>
    <!--获取key、value、index ==> (value, key, index)-->
    <ul>
        <li v-for="(value, key, index) in info">{{value}}-{{key}}-{{index}}</li>
    </ul>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            info: {
                name: 'yyy',
                age: 18,
                height: 1.88
            }
        }
    })
</script>
</body>
</html>

在这里插入图片描述

3、v-for使用过程添加

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--加入key保证唯一性,这样插入值时,效率更高,不会逐个修改-->
    <ul>
        <li v-for="item in letters" :key="item">{{item}}</li>
    </ul>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            letters: ['A', 'B', 'C', 'D','E']
        }
    })
</script>
</body>
</html>

4、那些数组的方法是响应式

<!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" :key="item">{{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', 'E']
        },
        methods: {
            btnClick() {
//                1、push方法
//                this.letters.push('abc')
//                this.letters.push('abc','def')
//                2、pop方法: 删除数组最后一个元素
//                this.letters.pop()
//                3、shift方法: 删除数组中第一个元素
//                this.letters.shift()
//                4、unshift方法: 在数组最前面添加元素
//                this.letters.unshift('abc')
//                this.letters.unshift('abc','def')
//                5、splice作用:
//                删除元素:第二个参数传入删除几个元素(如果没有,就删除到最后)
//                this.letters.splice(2)    //第二个元素删除到最后(不包括第二个元素)
//                this.letters.splice(1,2)   //从第一个元素开始删除2个元素
//                替换元素:第二个参数传入我们要替换几个元素,后面是用于替换前面的元素
//                this.letters.splice(1,3,'x','y','z','l')
//                插入元素:第一个参数表示那个位置插入,第二个参数必须为0,后面跟要插入的元素
//                this.letters.splice(1, 0,'x','y','z','l')
//                6、sort排序
//                this.letters.sort()
//                7、reverse反转
//                this.letters.reverse()
//                8、通过vue set
                Vue.set(this.letters,0,'bbbb')
            }
        }
    })
</script>
</body>
</html>

五、书籍购物车案例


1、目录结构

在这里插入图片描述

2、index.html

<!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>
            <th></th>
            <th>书籍名称</th>
            <th>出版日期</th>
            <th>价格</th>
            <th>购买数量</th>
            <th>操作</th>
        </thead>
        <tbody>
            <tr v-for="(item,index) in books">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.date}}</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>

3、main.js

const app = new Vue({
    el: '#app',
    data: {
        books: [
            {
                id: 1,
                name: '<<UNIX编程艺术>>',
                date: '2006-2',
                price: 59.00,
                count: 1
            },
            {
                id: 2,
                name: '<<编程珠玑>>',
                date: '2008-10',
                price: 39.00,
                count: 1
            }
        ]
    },
    methods: {
        // getFinalPrice(price) {
        //     return '¥' + price.toFixed(2)
        // }
        increment(index) {
            this.books[index].count++
        },
        decrement(index) {
            this.books[index].count--
        },
        removeHandle(index) {
            this.books.splice(index,1)
        }
    },
    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 i of this.books)
            let totalPrice = 0;
            for (let item of this.books) {
                totalPrice += item.price * item.count
            }
            return totalPrice
        }
    },
    // 过滤器
    filters: {
        showPrice(price) {
            return '¥' + price.toFixed(2)
        }
    }
})

4、style.css

table {
    border: 1px solid #e9e9e9;
    border-collapse: collapse;
    border-spacing: 0;
}

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

th {
    background: #f7f7f7;
    color: #5c6b77;
    font-weight: 600;
}

5、结果

在这里插入图片描述
六、高阶函数


1、filter函数

回调函数返回布尔值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    });
    const nums = [1,30,140,120,5,40,200];
    let newNums = nums.filter(function (n) {
        return n < 100
    });
    console.log(newNums)
</script>
</body>
</html>

在这里插入图片描述

2、map函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    });
    const nums = [1,30,140,120,5,40,200];
    let newNums = nums.map(function (t) {
        return t*2
    });
    console.log(newNums)
</script>
</body>
</html>

在这里插入图片描述

3、reduce函数

对数组中的所有内容进行汇总

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    });
    const nums = [1,30,140,120,5,40,200];
    let total = nums.reduce(function (p1, n) {
        return p1 + n
    }, 0);               //0为初始值
    console.log(total)
</script>
</body>
</html>

在这里插入图片描述

4、练习

函数式编程

1、方式一

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    });
    const nums = [1,30,140,120,5,40,200];
    let total = nums.filter(function (t) {
        return t < 100
    }).map(function (t) {
        return t * 2
    }).reduce(function (p1,n) {
        return p1 + n
    },0)
    console.log(total)
</script>
</body>
</html>

2、方式二(简写)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: 'hello,Vue'
        }
    });
    const nums = [1,30,140,120,5,40,200];
    let total =nums.filter(n => n < 100).map(n => n * 2).reduce((pre,n) => pre + n)
    console.log(total)
</script>
</body>
</html>

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wielun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值