0


【Vue】快乐学习第二篇

文章目录

前言 ♥️

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


计算属性 computed 🥤

简单上手

假如要实现两个变量的计算,目前可以使用拼接,使用 methods 方法来实现,现在将引入一个新的 option ,计算属性,computed,你可能会疑问,有什么不一样吗?不着急,慢慢来,你会理解的 🤪
在这里插入图片描述

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

在这里插入图片描述


<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Document</title></head><body><divid="app"><h2>计算属性 {{fullName}}</h2></div><scriptsrc="./vue.js"></script><script>var app =newVue({el:'#app',data:{firstName:'liu',lastName:'xiao sen',},computed:{// 只用get方法时,可以简写/*fullName: function () {
                    return this.firstName + " " + this.lastName;
                }
                */// 完成写法是对象,我们通过 fullName 访问,会直接调用 get 方法,所以写成 fullNamefullName:{set:function(newVal){
                        console.log(newVal);const names = newVal.split(' ');this.firstName = names[0];this.lastName = names[1];},get:function(){returnthis.firstName +' '+this.lastName;}}}})</script></body></html>

在这里插入图片描述


计算属性和methods对比 🍵

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

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

<body><divid="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><scriptsrc="./vue.js"></script><script>var app =newVue({el:'#app',data:{firstName:'liu',lastName:'xiao sen',},methods:{getFullName(){
                    console.log("method执行了");returnthis.firstName +' '+this.lastName;}},computed:{fullName(){
                    console.log("计算属性执行了");returnthis.firstName +' '+this.lastName;}}})</script></body>

结果
在这里插入图片描述


v-on的语法糖 🌿

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

普通写法

<body><divid="app"><buttonv-on:click="count ++">{{count}}</button></div><scriptsrc="./vue.js"></script><script>newVue({el:"#app",data:{count:0,},});</script></body>

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

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

在这里插入图片描述


v-on参数传递 💬

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

例子

<body><divid="app"><button@click="f1">按钮1</button><button@click="f2('小u')">按钮2</button><button@click="f3('小R',$event)">按钮3</button></div><scriptsrc="./vue.js"></script><script>newVue({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><divid="app"><div@click="f2"><div@click="f1">点击事件冒泡</div></div></div><scriptsrc="./vue.js"></script><script>newVue({el:"#app",methods:{f1(){
          console.log("f1");},f2(){
          console.log("f2");},},});</script></body>

在这里插入图片描述

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

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

在这里插入图片描述
如果使用 vue 提供的事件修饰符,会更方便,可读性更好

<divid="app"><div@click="f2"><!-- 事件后点加修饰符 --><[email protected]="f1">点击事件冒泡</div></div></div>

在这里插入图片描述


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

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

在这里插入图片描述


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

在这里插入图片描述

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title><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><divid="app"><span@click="f1">账号登录</span><span@click="f2">手机登录</span><formaction=""method="post"><inputtype="text"placeholder="请输入账号"v-if="flag == 10"><inputtype="text"placeholder="请输入手机"v-else><br/><inputtype="password"placeholder="请输入密码"><br/><inputtype="submit"value="登录"></form></div><scriptsrc="./vue.js"></script><script>newVue({el:'#app',data:{flag:0},methods:{f1(){this.flag =10;},f2(){this.flag =20;}},})</script></body></html>

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

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

在这里插入图片描述


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

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

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><divid="app"><pv-if="1==1">v-if {{message}}</p><pv-show="1==1">v-show {{message}}</p><hr/><pv-if="1==2">v-if {{message}}</p><pv-show="1==2">v-show {{message}}</p></div><scriptsrc="./vue.js"></script><script>newVue({el:'#app',data:{message:'Hello King'}})</script></body></html>

在这里插入图片描述

上图能发现,使用 v-show 为假隐藏元素时,他是通过css的

display:none

隐藏的,使用 v-for 为假隐藏元素时,他是直接将元素从 DOM 树里移除

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

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


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

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

在这里插入图片描述


v-for 绑定 key 🧃

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

使用index作为key

<body><divid="app"><ul><liv-for="(item,index) in arrs":key="index">
                {{item.id}} - {{item.name}} - {{item.age}}
                <inputtype="text"></li></ul><button@click="add">添加一个小张</button></div><scriptsrc="./vue.js"></script><script>newVue({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>

在这里插入图片描述

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

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


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

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

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

源码863行定义了这些响应式方法
在这里插入图片描述


购物车案例 🍓

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


<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="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><divid="app"><pv-show="shoppings.length == 0">什么都没有呀</p><table><tr><thv-show="shoppings.length != 0"v-for="item in names">{{item}}</th></tr><trv-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><pv-show="shoppings.length != 0">总价:{{priceSum}}</p></table></div><scriptsrc="./vue.js"></script><script>newVue({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;}returnthis.totalPrice;}}})</script></body></html>

过滤器 🍂

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

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

在这里插入图片描述


增强for (for in) 🥣

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

<body><divid="app"><button@click="heightenFor">点击使用增强for(for in)</button></div><scriptsrc="./vue.js"></script><script>newVue({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 inthis.arrs){
                        console.log(this.arrs[arr].age);}}},})</script></body>

在这里插入图片描述


增强 for (for of) 💊

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

<body><divid="app"><button@click="heightenFor">点击使用增强for(for of)</button></div><scriptsrc="./vue.js"></script><script>newVue({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 ofthis.arrs){
                        console.log(arr.id);
                        console.log(arr.age);}}},})</script></body>

在这里插入图片描述


v-model的使用和原理 🌍

<body><divid="app"><p>用户账号 <inputtype="text"v-model="username"></p><p>username: {{ username}}</p></div><scriptsrc="./vue.js"></script><script>var vm =newVue({el:'#app',data:{username:''}})</script></body>

在这里插入图片描述


模拟实现双向绑定

v-model其实是一个语法糖

🧃 1. 使用 v-bind 绑定一个 value 属性
🧃 2. v-on 指令给当前元素绑定 input 事件
请添加图片描述

<body><divid="app"><inputtype="text":value="message"@input="message = $event.target.value">{{message}}
    </div><scriptsrc="./vue.js"></script><script>newVue({el:'#app',data:{message:'abc'}})</script></body>

在这里插入图片描述


v-model结合radio🥳

<body><divid="app"><labelfor="male"><inputtype="radio"v-model="gender"value="男"id="male">🚹
        </label><labelfor="female"><inputtype="radio"v-model="gender"value="女"id="female">🚹
        </label><p>{{gender}}</p></div><scriptsrc="./vue.js"></script><script>newVue({el:'#app',data:{gender:'男'}})</script></body>

在这里插入图片描述


v-model结合checkbox🥳

<body><divid="app"><labelfor="agreement"><inputtype="checkbox"id="agreement"v-model="isAgree">同意协议
        </label>
        {{isAgree}}

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

在这里插入图片描述


v-model结合select🥳

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

在这里插入图片描述


v-model修饰符 🎨

lazy修饰符,使用 lazy 修饰符可以让数据在失去焦点或者回车时才更新
number修饰符,可以让输入框中的内容自动转换成数字类型
trim修饰符,可以过滤输入内容左右两边的空格请添加图片描述

最后 💧

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

请添加图片描述

标签: 前端框架 vue.js vue

本文转载自: https://blog.csdn.net/m0_53321320/article/details/124062718
版权归原作者 王子的烦恼 所有, 如有侵权,请联系我们删除。

“【Vue】快乐学习第二篇”的评论:

还没有评论