【Vue】快乐学习第二篇

文章目录

  • 前言 ♥️
  • 计算属性 computed
  • 计算属性和methods对比
  • v-on的语法糖
  • v-on参数传递
  • v-on的事件修饰符 ✨
  • v-if和v-else if和v-else使用
  • 登录切换小案例 ⛹️‍♂️
  • v-show与v-if是情侣关系吗
  • v-for遍历数组和对象 ♻️
  • v-for 绑定 key
  • 数组中哪些方法是响应式的?⚙️
  • 购物车案例
  • 过滤器
  • 增强for (for in)
  • 增强 for (for of)
  • v-model的使用和原理
  • v-model结合radio
  • v-model结合checkbox
  • v-model结合select
  • v-model修饰符
  • 最后

前言 ♥️

大家好,大家好,我又来了,这次还是基础部分的知识,快来学习吧,下一篇将学习Vue组件化的使用以及组件通信,插槽等知识,原创不易,如果觉得写的不错,可以点赞评论支持一下


计算属性 computed

简单上手

假如要实现两个变量的计算,目前可以使用拼接,使用 methods 方法来实现,现在将引入一个新的 option ,计算属性,computed,你可能会疑问,有什么不一样吗?不着急,慢慢来,你会理解的
【Vue】快乐学习第二篇_第1张图片

<body>
    <div id="app">
        <h2>使用拼接 {{firstName + " " + lastName}}h2>
        <h2>使用方法 {{getFullName()}}h2>
        <h2>计算属性 {{fullName}}h2>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                firstName: 'liu',
                lastName: 'xiao sen',
            },
            methods: {
                getFullName() {
                    return this.firstName + " " + this.lastName;
                }
            },
            computed: {
                fullName: function () {
                    return this.firstName + " " + this.lastName;
                }
            }
        })
    script>
body>

【Vue】快乐学习第二篇_第2张图片


DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Documenttitle>
head>

<body>
    <div id="app">
        <h2>计算属性 {{fullName}}h2>
    div>
    <script src="./vue.js">script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                firstName: 'liu',
                lastName: 'xiao sen',
            },
            computed: {
                // 只用get方法时,可以简写
                /*fullName: function () {
                    return this.firstName + " " + this.lastName;
                }
                */

                // 完成写法是对象,我们通过 fullName 访问,会直接调用 get 方法,所以写成 fullName
                fullName: {
                    set: function (newVal) {
                        console.log(newVal);
                        const names = newVal.split(' ');
                        this.firstName = names[0];
                        this.lastName = names[1];
                    },
                    get: function () {
                        return this.firstName + ' ' + this.lastName;
                    }
                }
            }
        })
    script>
body>

html>


计算属性和methods对比

计算属性的优势就是它是使用缓存机制了的,如果多次使用,计算属性只执行一次

下面是对比的代码,一目了然

<body>
    <div id="app">
        <h3>{{getFullName()}}h3>
        <h3>{{getFullName()}}h3>
        <h3>{{getFullName()}}h3>
        <h3>{{getFullName()}}h3>
        <hr />
        <h3>{{fullName}}h3>
        <h3>{{fullName}}h3>
        <h3>{{fullName}}h3>
        <h3>{{fullName}}h3>
    div>
    <script src="./vue.js">script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                firstName: 'liu',
                lastName: 'xiao sen',
            },
            methods: {
                getFullName() {
                    console.log("method执行了");
                    return this.firstName + ' ' + this.lastName;
                }
            },
            computed: {
                fullName() {
                    console.log("计算属性执行了");
                    return this.firstName + ' ' + this.lastName;
                }
            }
        })
    script>
body>

结果
【Vue】快乐学习第二篇_第3张图片


v-on的语法糖

因为 v-on 使用较多,因此添加了语法糖,语法糖就是简写

普通写法

<body>
  <div id="app">
    <button v-on:click="count ++">{{count}}button>
  div>
  <script src="./vue.js">script>
  <script>
    new Vue({
      el: "#app",
      data: {
        count: 0,
      },
    });
  script>
body>

使用了语法糖,使用@代替重复的 v-on:

<body>
  <div id="app">
    <button @click="count ++">{{count}}button>
  div>
  <script src="./vue.js">script>
  <script>
    new Vue({
      el: "#app",
      data: {
        count: 0,
      },
    });
  script>
body>

在这里插入图片描述


v-on参数传递

◼️ 1. 无参数,不传
◼️ 2. 有一个参数或多个参数,但不包含时间对象参数时,加括号,参数按照顺序写
◼️ 3. 当不仅要传普通参数,还要传递事件参数时,获取事件对象通过 $event

例子

<body>
  <div id="app">
    <button @click="f1">按钮1button>
    <button @click="f2('小u')">按钮2button>
    <button @click="f3('小R',$event)">按钮3button>
  div>
  <script src="./vue.js">script>
  <script>
    new Vue({
      el: "#app",
      methods: {
        f1() {
          console.log("无参数");
        },
        f2(name) {
          console.log("name is:" + name);
        },
        f3(name, event) {
          console.log("name is:" + name + " and event is:" + event);
          console.log(event);
        },
      },
    });
  script>
body>


v-on的事件修饰符 ✨

事件修饰符,简化编码,比如阻止事件冒泡,阻止默认事件等等……
.stop 阻止事件冒泡
.prevent 阻止事件的默认行为
.键别名/键代码 特定键触发
.once 只触发一次回调

事件冒泡

微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。

<body>
  <div id="app">
    <div @click="f2">
      <div @click="f1">点击事件冒泡div>
    div>
  div>
  <script src="./vue.js">script>
  <script>
    new Vue({
      el: "#app",
      methods: {
        f1() {
          console.log("f1");
        },
        f2() {
          console.log("f2");
        },
      },
    });
  script>
body>

【Vue】快乐学习第二篇_第4张图片

js冒泡和捕获是事件的两种行为,使用event.stopPropagation()起到阻止捕获和冒泡阶段中当前事件的进一步传播。

<body>
  <div id="app">
    <div @click="f2">
      <div @click="f1">点击事件冒泡div>
    div>
  div>
  <script src="./vue.js">script>
  <script>
    new Vue({
      el: "#app",
      methods: {
        f1(e) {
          console.log("f1");
          e.stopPropagation();
        },
        f2() {
          console.log("f2");
        },
      },
    });
  script>
body>

【Vue】快乐学习第二篇_第5张图片
如果使用 vue 提供的事件修饰符,会更方便,可读性更好

<div id="app">
  <div @click="f2">
    
    <div @click.stop="f1">点击事件冒泡div>
  div>
div>

【Vue】快乐学习第二篇_第6张图片


v-if和v-else if和v-else使用

<body>
    <div id="app">
        <li v-if="count == 10">如果count=10我就显示li>
        <li v-if="count > 20">如果count大于20我就显示li>
        <li v-else>如果都不对我就显示li>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: "#app",
            data: {
                count: 15,
            },
        });
    script>
body>

在这里插入图片描述


登录切换小案例 ⛹️‍♂️

【Vue】快乐学习第二篇_第7张图片

DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        body {
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
        }

        span {
            cursor: pointer;
            background-color: #69F;
            color: #FFF;
            border-radius: 5px;
        }

        input {
            margin-top: 30px;
            border: none;
            outline: none;
            border-bottom: 1px solid #ccc;
            width: 250px;
        }

        input[type='submit'] {
            border: none;
            height: 25px;
            background-color: #69F;
            color: #fff;
        }
    style>
head>

<body>
    <div id="app">
        <span @click="f1">账号登录span>
        <span @click="f2">手机登录span>
        <form action="" method="post">
            <input type="text" placeholder="请输入账号" v-if="flag == 10">
            <input type="text" placeholder="请输入手机" v-else><br />
            <input type="password" placeholder="请输入密码"><br />
            <input type="submit" value="登录">
        form>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                flag: 0
            },
            methods: {
                f1() {
                    this.flag = 10;
                },
                f2() {
                    this.flag = 20;
                }
            },
        })
    script>
body>

html>

有一个小问题,生活中的注册登录,在切换登录方式时,里面的输入会被清空,但是我们上面的案例,并不会,为什么,这就涉及 vue 的底层了,它为了提高性能,使用了 diff 算法,说白了,就是找不同算法,结合虚拟 DOM ,实现最大化的复用,如果 key 相同,能复用,就原地复用,如果不能,再创建 DOM渲染视图,我们可以设置不同的 key,以达到每次都重新渲染的效果

<div id="app">
    <span @click="f1">账号登录span>
    <span @click="f2">手机登录span>
    <form action="" method="post">
        <input type="text" placeholder="请输入账号" v-if="flag == 10" key="account">
        <input type="text" placeholder="请输入手机" v-else key="phone"><br />
        <input type="password" placeholder="请输入密码"><br />
        <input type="submit" value="登录">
    form>
div>

【Vue】快乐学习第二篇_第8张图片


v-show与v-if是情侣关系吗

v-show 和 v-if 都是控制元素是否展示的,我想问他们是情侣吗?哈哈,跑偏了,回归正题,通过下面代码,你会秒懂,并知道啥时候该用啥

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <div id="app">
        <p v-if="1==1">v-if {{message}}p>
        <p v-show="1==1">v-show {{message}}p>
        <hr/>
        <p v-if="1==2">v-if {{message}}p>
        <p v-show="1==2">v-show {{message}}p>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el:'#app',
            data:{
                message:'Hello King'
            }
        })
    script>
body>
html>

【Vue】快乐学习第二篇_第9张图片

上图能发现,使用 v-show 为假隐藏元素时,他是通过css的 display:none 隐藏的,使用 v-for 为假隐藏元素时,他是直接将元素从 DOM 树里移除

什么时候使用 v-for,什么时候用 v-show

◼️ 当需要在隐藏和显示之间来回跳的话,推荐你使用 v-show,性能更好
◼️ 当只有一次或很少次的切换时,推荐使用 v-if


v-for遍历数组和对象 ♻️

<body>
    <div id="app">
        <ul>
            <li>普通遍历数组li>
            <li v-for="item in arrs">{{item}}li>
            <hr />
            <li>遍历数组,同时打印索引li>
            <li v-for="(item,index) in arrs">{{index + 1}} - {{item}}li>
            <hr />
            <li>普通遍历对象li>
            <li v-for="(value,key) in obg">{{key}} - {{value}}li>
            <hr />
            <li>遍历对象,同时获取indexli>
            <li v-for="(value,key,index) in obg">{{index}} - {{key}} - {{value}}li>
        ul>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                arrs: ['你的名字', '天气之子', '萤火之森'],
                obg: {
                    name: '小爱',
                    sex: '女',
                    age: 8
                }
            }
        })
    script>
body>

【Vue】快乐学习第二篇_第10张图片


v-for 绑定 key

key的主要作用是高效的更新虚拟 DOM

使用index作为key

<body>
    <div id="app">
        <ul>
            <li v-for="(item,index) in arrs" :key="index">
                {{item.id}} - {{item.name}} - {{item.age}}
                <input type="text">
            li>
        ul>
        <button @click="add">添加一个小张button>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                arrs: [
                    {
                        id: '001',
                        name: '小艾',
                        age: 18
                    },
                    {
                        id: '002',
                        name: '小兵',
                        age: 24
                    },
                    {
                        id: '003',
                        name: 'Sirie',
                        age: 26
                    }
                ]
            },
            methods: {
                add(){
                    const xiaozhang = {id:'004',name:'小张',age:8};
                    this.arrs.unshift(xiaozhang);
                }
            },
        })
    script>
body>

【Vue】快乐学习第二篇_第11张图片

使用 index 作为 key,当你在前面添加时,就导致 index 重新编排,最坏的就是从头插入,这时虚拟dom的diff算法,就不能就地复用了

当我们使用id作为 key 时,避免v-for“就地更新”策略导致的问题。


数组中哪些方法是响应式的?⚙️

◼️ 因为 Vue 是响应式的,所以当数据有变化时,Vue会自动检测到数据的变化,视图会发生对应的更新
◼️ Vue 包含了一组观察数组变化的方法,使用这些方法操作数组才会被 Vue 检测到,从而更新视图
◼️ 使用下标操作数组,不会被 Vue 检测到,因为代价较大,所以不是响应式的,而下面的这些方法都是被 Vue 重写过的,在实现功能的基础上,添加了响应式的代码

⚙️ push()
⚙️ pop()
⚙️ shift()
⚙️ unshift()
⚙️ splice()
⚙️ sort()
⚙️ reverse()

源码863行定义了这些响应式方法
【Vue】快乐学习第二篇_第12张图片


购物车案例

***


DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>购物车title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        #app {
            display: flex;
            width: 100vw;
            height: 100vh;
        }

        table {
            margin: auto;
            width: 40%;
            border-collapse: collapse;
        }

        th,
        td {
            height: 35px;
            line-height: 35px;
            text-align: center;
            border: 1px solid rgb(222, 222, 222);
        }

        th {
            background-color: rgb(238, 238, 238);
            color: #454545;
        }

        button {
            width: 40px;
            height: 25px;
            border: 1px solid #cfcfcf;
            border-radius: 6px;
            background-color: transparent;
        }

        p {
            position: absolute;
            bottom: 200px;
            left: 50%;
            transform: translateX(-50%);
        }
    style>
head>

<body>
    <div id="app">
        <p v-show="shoppings.length == 0">什么都没有呀p>
        <table>
            <tr>
                <th v-show="shoppings.length != 0" v-for="item in names">{{item}}th>
            tr>
            <tr v-for="(item,index) in shoppings">
                <td>{{item.name}}td>
                <td>{{item.date}}td>
                <td>{{item.price}}td>
                <td>
                    <button @click="subNum(index)">-button>
                    {{item.num}}
                    <button @click="addNum(index)">+button>
                td>
                <td>
                    <button @click="moveShop(index)">移除button>
                td>
            tr>
            <p v-show="shoppings.length != 0">总价:{{priceSum}}p>
        table>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                names: ['商品名称', '出版日期', '价格', '购买数量', '操作'],
                shoppings: [
                    {
                        id: 1,
                        name: '卫龙辣条',
                        date: '2012-12-12',
                        price: 10,
                        num: 1
                    },

                    {
                        id: 2,
                        name: '嘿嘿C语言',
                        date: '2012-2-10',
                        price: 100,
                        num: 1
                    },
                    {
                        id: 3,
                        name: '别想嫩多啦',
                        date: '2021-2-2',
                        price: 20,
                        num: 1
                    },
                    {
                        id: 4,
                        name: '球衣',
                        date: '2009-12-12',
                        price: 1000,
                        num: 1
                    },

                ],
                totalPrice: 0
            },
            methods: {
                addNum(index) {
                    this.shoppings[index].num++;
                },
                subNum(index) {
                    if (this.shoppings[index].num > 1) {
                        this.shoppings[index].num--;
                    }
                },
                moveShop(index) {
                    this.shoppings.splice(index, 1);
                }
            },
            computed: {
                priceSum() {
                    this.totalPrice = 0;
                    for (let i = 0; i < this.shoppings.length; i++) {
                        this.totalPrice += this.shoppings[i].price * this.shoppings[i].num;
                    }
                    return this.totalPrice;
                }
            }
        })
    script>
body>

html>

过滤器

定义在配置对象中添加 filters 配置项,然后写过滤函数,传入要处理的参数
使用在参数后 {{price | showDecimalPoint}}
可以使用多个过滤器

<body>
    <div id="app">
        <ul>
            <li v-for="price in prices">{{price | showDecimalPoint}}li>
        ul>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                prices: [100, 200, 300, 10]
            },
            filters: {
                showDecimalPoint(price) {
                    return '¥' + price.toFixed(2);
                }
            }
        })
    script>
body>

【Vue】快乐学习第二篇_第13张图片


增强for (for in)

使用增强 for 方便我们对数组和对象的遍历
使用 for in 遍历对象数组时,返回的是数组下标

<body>
    <div id="app">
        <button @click="heightenFor">点击使用增强for(for in)button>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                arrs: [
                    { id: 1, age: 56 },
                    { id: 2, age: 34 },
                    { id: 3, age: 24 },
                    { id: 4, age: 22 },
                ]
            },
            methods: {
                heightenFor() {
                    for (let arr in this.arrs) {
                        console.log(this.arrs[arr].age);
                    }
                }
            },
        })
    script>
body>

【Vue】快乐学习第二篇_第14张图片


增强 for (for of)

使用 for of 遍历对象数组时,会直接返回我们的对象,这就非常的方便了

<body>
    <div id="app">
        <button @click="heightenFor">点击使用增强for(for of)button>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                arrs: [
                    { id: 1, age: 56 },
                    { id: 2, age: 34 },
                    { id: 3, age: 24 },
                    { id: 4, age: 22 },
                ]
            },
            methods: {
                heightenFor() {
                    for (let arr of this.arrs) {
                        console.log(arr.id);
                        console.log(arr.age);
                    }
                }
            },
        })
    script>
body>

【Vue】快乐学习第二篇_第15张图片


v-model的使用和原理

<body>
    <div id="app">
        <p>用户账号 <input type="text" v-model="username"> p>
        <p>username: {{ username}}p>
    div>
    <script src="./vue.js">script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                username: ''
            }
        })
    script>
body>


模拟实现双向绑定

v-model其实是一个语法糖

1. 使用 v-bind 绑定一个 value 属性
2. v-on 指令给当前元素绑定 input 事件

<body>
    <div id="app">
        <input type="text" :value="message" @input="message = $event.target.value">{{message}}
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'abc'
            }
        })
    script>
body>

在这里插入图片描述


v-model结合radio

<body>
    <div id="app">
        <label for="male">
            <input type="radio" v-model="gender" value="" id="male">
        label>
        <label for="female">
            <input type="radio" v-model="gender" value="" id="female">
        label>
        <p>{{gender}}p>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                gender: '男'
            }
        })
    script>
body>

在这里插入图片描述


v-model结合checkbox

<body>
    <div id="app">
        <label for="agreement">
            <input type="checkbox" id="agreement" v-model="isAgree">同意协议
        label>
        {{isAgree}}

        <hr />
        <label for="1">
            <input type="checkbox" v-model="hobbys" value="看动漫" id="1">看动漫
        label>
        <label for="2">
            <input type="checkbox" v-model="hobbys" value="学java" id="2">学java
        label>
        <label for="3">
            <input type="checkbox" v-model="hobbys" value="打豆豆" id="3">打豆豆
        label>
        <label for="4">
            <input type="checkbox" v-model="hobbys" value="起飞" id="4">起飞
        label>
        <p>你的爱好是: {{hobbys}}p>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                isAgree: false,
                hobbys: []
            }
        })
    script>
body>

【Vue】快乐学习第二篇_第16张图片


v-model结合select

<body>
    <div id="app">
        <select name="" id="" v-model="me">
            <option value="青果">青果option>
            <option value="香蕉">香蕉option>
            <option value="山楂">山楂option>
            <option value="草莓">草莓option>
            <option value="西瓜">西瓜option>
        select>
        <p>你选择的水果是: {{me}}p>
        <hr />
        <select name="" id="" v-model="mes" multiple>
            <option value="青果">青果option>
            <option value="香蕉">香蕉option>
            <option value="山楂">山楂option>
            <option value="草莓">草莓option>
            <option value="西瓜">西瓜option>
        select>
        <p>你选择的水果是: {{mes}}p>
    div>
    <script src="./vue.js">script>
    <script>
        new Vue({
            el: '#app',
            data: {
                me: '西瓜',
                mes: []
            }
        })
    script>
body>


v-model修饰符

lazy修饰符,使用 lazy 修饰符可以让数据在失去焦点或者回车时才更新
number修饰符,可以让输入框中的内容自动转换成数字类型
trim修饰符,可以过滤输入内容左右两边的空格【Vue】快乐学习第二篇_第17张图片

最后

感谢你能看完这篇文章,我相信你一定收获颇多,如果对博主的文章有什么建议,欢迎在评论区讨论,拜拜了

【Vue】快乐学习第二篇_第18张图片

你可能感兴趣的:(vue,前端框架,vue.js,vue)