首页
写过的文章
Search
1
mock的基本用法
718 阅读
2
js的数组常用方法
693 阅读
3
cnpm安装教程
565 阅读
4
能有效解决问题的提问方法2.0
554 阅读
5
Vue、git指令
490 阅读
默认分类
JavaScript
Vue
TypeScript
登录
Search
标签搜索
底部导航
tabbar
底部导航栏
vue3隐藏底部导航栏
vue3隐藏tabbar
网页
黑白
网页黑白
cnpm安装
cnpm
Z的故事
累计撰写
23
篇文章
累计收到
73
条评论
首页
栏目
默认分类
JavaScript
Vue
TypeScript
页面
写过的文章
搜索到
23
篇与
Zuiet
的结果
2022-09-09
vue2 与 vue3的区别(二)
数据双向绑定讲一下什么是数据双向绑定v-model(语法糖) 是Vue框架的一种内置的API指令,本质是一种语法糖写法。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理<input type="text" v-model="msg"/> // 等于下面代码 <input type="text" :value="msg" @input="msg = $event.target.value" />通过上面这两段代码片段可以看出来 v-model="msg" 是 :value="msg" @input="msg = $event.target.value"的缩写解析一下代码$event 当前触发的事件对象。$event.target 当前触发的事件对象的dom$event.target.value 当前dom的value值在@input方法中,value => msg在:value中:msg => value如此,形成了一个闭环,也就是所说的数据的双向绑定。那么就有人提问了, vue中的自定义组件能不能实现双向绑定<my-Input v-model="msg"></my-Input> //我们可以根据规则来拆解 <my-Input :value="msg" @input="msg = $event.target.value"></my-Input>解析还原一下组件封装的过程<template> <div> <input type="text" :value="value" @input="$emit('input', $event.target.value)"></input> </div> </template> <script> export default { props:{ value:String } } </script>看完以后突然恍然大悟, 这是父子组件的来回传值!!那么可以在思考一个问题就是代码里props的value里的值可不可以随便写一个呢? input可不可以随便定义一个事件呢?当我们在自定义组件使用v-model的时候并不能实现双向的数据绑定, 因为自定义的组件没有默认value和input事件,在使用的时候我们就得按照刚刚所写的一样去生命定义这些东西这时候,model的选项就派上用场了,在定义组件的时候,指定prop的值和监听的事件。组件的用法不变,子组件这样写(里面事件就随便填了)<template> <div> <input type="text" :value="xx" @input="$emit('xx', $event.target.value)"></input> </div> </template> <script> export default { model: { value:'xx', event:'xx', // 代表自定义的事件名称 } props: { xx: String //代表自定义的变量名成 } } </script> 上面就是整理的一些vue2的双向绑定以及一些用法vue3双向数据绑定vue3与vue2的双向数据绑定区别并不是很大,他是跟vue2的sync进行了合并,所以在vue3的就移除了sync,不多说,上代码!// 自定义一个Input组件 <template> <div> <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </div> </template> <script> export default { props: { modelValue: { type: String } } } </script> //在vue3中默认的不在是value 而是modelValue 然后在其他页面使用 <template> <h1>{{ msg }}</h1> <Input v-model="msg"></Input> //等同于下面语法 默认传入一个modelValue然后在子组件接收 <Input :modelValue="msg" @update:modelValue="msg = $event"></Input> </template> <script> import { ref } from "vue"; import Input from "@/components/Input" export default { components:{ Input }, setup(props){ const msg = ref('') return { msg } } } </script>那么这个默认的modelValue就无法改变了吗?当然不是// 父组件 <template> <h1>vue3中使用v-model {{msg}}</h1> <testModel v-model:msg="msg"></testModel> </template> 这时候子组件接收的props就要换成msg了// 子组件 <template> <div> <input type="text" :value="msg" @input="$emit('update:msg', $event.target.value)" /> </div> </template> <script> export default { props: { msg: { type: String } } } </script>当然提到双向绑定,你可能第一时间就会想到表单元素,双向绑定不一定是表单元素,你可以定义各种各样的组件,比如通过click事件改变父组件的值// 父组件 <template> <div>{{count}}</div> <testModel v-model="content" :content="content"></testModel> </template> <script> export default { components: { testModel }, setup(){ const count = ref(0) return { count } } } </script> // 子组件 <template> <!-- 一定是+1 不是+=1 或者++ 否则vue会触发一个不让子组件直接改变props的警告 --> <div @click="$emit('update:count', count + 1)">click me count + 1!</div> </template> <script> export default { props: { count: { type: Number } } } </script>
2022年09月09日
361 阅读
0 评论
0 点赞
2022-09-08
Vue2 与 Vue3区别(一)
vue2 vue3 双向数据的区别一.先来聊聊vue2双向绑定原理:是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图,实现数据和视图同步// 语法: Object.defineProperty(obj, "name", { get:()=> {}, set:()=> {}) 参数一: obj:劫持对象,参数二:"name":劫持对象属性 , 参数三:给属性添加set,get方法二. 再聊一聊vue3双向绑定原理:是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,因为 Proxy 是 ES6 的语法// 语法: let p =new Proxy(obj,{get:(target,prop,p)=>{},set:(target, prop, vaule, p)=>{}}) 总结:vue2通过Object.defineProperty劫持的是对象中每一个属性vue3通过Proxy劫持的是对象中每一个属性视图更新问题因为 Vue 实例中的数据是响应式的,⽽我们新增的属性并不是响应式的,由于受现在 JavaScript 的限制,Vue ⽆法检测到属性的新增或删除。所以有时⽆法实时的更新到视图上!vue2和vue3的执行机制有所不同,v2是通过object.defindProperty,监听对象新增或修改某一个属性的时候会触发,所以会出现数据更新视图不更新的情况,而v3则是通过es6的proxy监听整个对象的变化,所以不会存在数据变了试图不变的情况遇到这类问题的时候⼀般是通过 this.$set,该⽅法⼀共有三个参数,分别是给谁添加,新增属性,新增的值.下面代码实现:data:{ obj:{ a:1, b:2 } } methods:{ add(){ this.obj.c = 10;// 给obj添加属性及属性值 console.log(this.obj);// 打印下来发现后台有c这条数据, 但是视图却没有更新 this.$set(this.obj,"c",10);//这时候就通过这个方法强制更新 } }
2022年09月08日
433 阅读
3 评论
0 点赞
2022-09-04
js的数组常用方法
1.joinjoin('参数')把数组的元素以传入的参数为分割符,转换成字符串。let arr = [1, 2, 3, 4, 5]; let str = arr.join(','); console.log(str); -> '1,2,3,4,5' 2.push()和pop()push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。let arr = ['张三', '李四', '王五']; let count = arr.push('马六'); console.log(arr); // -> ['张三', '李四', '王五', '马六'] console.log(count); // -> 4 let item = arr.pop(); console.log(item); // -> 马六 3.shift() 和 unshift()shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。unshift:将参数添加到原数组开头,并返回数组的长度 。let arr = ['张三', '李四', '王五']; let item= arr.shift(); console.log(arr); // -> ['李四', '王五'] console.log(item); // -> 张三 let count= arr.unshift('马六'); console.log(arr); // -> ['马六', '李四', '王五'] console.log(count); // -> 3 4.reverse()将数组的数据进行反转,并且返回反转后的数组,会改变原数组let arr = [1, 2, 3, 4, 5]; let arr1 = arr.revers(); console.log(arr1); // [5, 4, 3, 2, 1] console.log(arr); // [5, 4, 3, 2, 1] 5.sort()对数组内的数据进行排序(默认为升序),并且返回排过序的新数组,会改变原来的数组let arr = [12,2,43,5,2,5]; console.log(arr.sort()) // -> [12, 2, 2, 43, 5, 5] /* 注意:通过上面的案例,你会发现 打印的数组和原数组比较还是有变化的 [12,2,43,5,2,5] -> [12, 2, 2, 43, 5, 5];但是有没有达到我们想要的结果,这是为什么呢?*/ /* 因为排序是针对字符的排序,先使用数组的toString()方法转为字符串,再逐位比较,3是大于12的,因为首位3>1,不 要与Number型的数据排序混淆。*/ //5.1那如果需要数值排序怎么办呢? /* 如果需要数值排序,sort(callback) 需要传入一个回调涵数,该函数应该具有两个参数,比较这两个参数,然后返回 一个用于说明这两个值的相对顺序的数字(a-b);*/ //例如: let arr = [12,2,43,5,2,5]; console.log(arr.sort((a,b)=>a-b)) // -> [2, 2, 5, 5, 12, 43] 6.slice()截取指定位置的数组,并且返回截取的数组,不会改变原数组// slice(startIndex, endIndex) 可以有两个参数, startIndex为必选, 表示从第几位开始.endIndex为可选 // 表示到第几位结束(不包含endIndex位),省略表示到最后一位, startIndex和endIndex都可以为负数, // 负数表示从最后一位开始算起,如-1表示最后一位 let arr = ['张三','李四','王五','马六']; console.log(arr.slice(1, 3));// -> ['李四', '王五'] console.log(arr); // -> ['张三','李四','王五','马六']; 原数组是没有改变的 7.splice()向数组中添加,或从数组删除,或替换数组中的元素,然后返回被删除/替换的元素 // splice(start, num, val1, val2, ...); 所有参数全部可选.和slice相比splice是会改变原数组的 // start是开始的位置,可以为负数, -1就表示从最后一位开始, num代表要删除或者替换的长度,不能为负数 let arr = ['张三','李四','王五','马六']; console.log(arr.splice(2, 1)) // -> ['王五'] console.log(arr) // -> ['张三','李四','王五','马六'] let arr1 = ['张三','李四','王五','马六']; console.log(arr1.splice(2, 1, '七郎')) // ->['王五'] console.log(arr1) // -> ['张三','李四','七郎','马六'] 8.toString()将数组转换成字符串,类似于没有参数的join()。该方法会在数据发生隐式类型转换时被自动调用,如果手动调用,就是直接转为字符串。不会改变原数组let arr = [1, 2, 3, 4, 5, 6]; //toString没有参数 console.log(arr.toString()) // -> '1, 2, 3, 4, 5, 6' 9.indexOf()根据指定的数据,从左向右,查询在数组中出现的位置,如果不存在指定的数据,返回-1,找到了指定的数据返回该数据的索引// indexOf(value, start),value为要查询的数据, start为可选,表示开始查询的位置 // 当start为负数时,从数组的尾部向前数, 如果查询不到value的存在,则返回-1 let arr = ['张三', '李四', '王五', '马六']; console.log(arr.indexOf('李四')) // -> 1 console.log(arr.indexOf('李四', 2)) // -> -1 10.forEach()ES5新增的方法,用来遍历数组,没有返回值// forEach(callback), callback默认有三个参数, // 分别为value(遍历到的数组的数据), index(对应的索引), self(数组自身) let arr = ['张三', '李四', '王五', '马六'] let a = arr.forEach((value, index, self) => { console.log(value + '->' + index + '->' + (arr === self)); }) //打印结果为: 张三-> 0 -> true 李四-> 1 -> true ... console.log(a) // -> undefined --- forEach没有返回值 // 该方法为遍历方法, 不会修改原数组 11.map()1.同forEach功能。2.map的回调函数会将执行结果返回,最后map将所有回调函数的返回值组成新数组返回。// map(callback), callback默认有三个参数, 分别为value, index, seif. 跟forEach参数一样 let arr = ['张三', '李四', '王五', '马六']; let arr1 = arr.map(item => { return '你好' + item }) console.log(arr1) // -> ['你好: 张三', '你好: 李四', '你好: 王五', ...] 12.filter()1.同forEach功能;2.filter的回调函数需要返回布尔值,当为true时,将本次数组的数据返回给filter,最后filter将所有回调函数的返回值组成新数组返回(此功能可理解为“过滤”)。// filter(callback), callback默认有三个参数, 分别为value, index, self let arr = [1, 2, 3, 4, 5, 6]; let arr1 = arr.filter((item, index, self) => { console.log(item) // -> 1, 2, 3, 4, 5, 6 console.log(index) // -> 0, 1, 2, 3, 4, 5 console.log(self) // -> [1, 2, 3, 4, 5, 6] return item > 3 }) console.log(arr1) // -> [4, 5, 6] 13.find()数组的循环,查找到符合条件的值并且打断循环返回找到的值。let arr = ['张三', '李四', '王五', '马六']; let str = arr.find(item => item == '李四'); console.log(str); // -> '李四' 14.findIndex()数组的循环,查找到符合条件的索引并且打断循环返回找到的索引值let arr = ['张三', '李四', '王五', '马六']; let index = arr.findIndex(item => item == '李四'); console.log(str); // -> 1 15.every()判断数组中每一项是否都满足条件,只有所有项都满足条件,才会返回true。// every()接受一个回调函数作为参数, 这个回调函数需要有返回值, every(callback) // callback三个参数, 分别是value, index, self let arr = [1, 2, 3, 4, 5, 6]; let bool = arr.every(item => item > 0) console.log(bool) // -> true let bool1 = arr.every(item => item > 3) console.log(bool1) // -> false 16.some()判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。否侧就会返回false// some()接受一个回调函数作为参数, 这个回调函数需要有返回值, some(callback); callback默认有三个参数 // 分别为value, index, self let arr = [1, 2, 3, 4, 5, 6] let bool = arr.every(item => item > 5) console.log(bool) // -> true let bool1 = arr.every(item => item > 7) console.log(bool1) // -> false 17.reduce()数组的第一项开始,逐个遍历到最后,迭代数组的所有项,然后构建一个最终返回的值。参数:reduce()接收一个或两个参数:第一个是回调函数,表示在数组的每一项上调用的函数;第二个参数(可选的)作为归并的初始值,被回调函数第一次执行时的第一个参数接收。 reduce(callback,initial);callback默认有四个参数,分别为prev,now,index,self。 callback返回的任何值都会作为下一次执行的第一个参数。 如果initial参数被省略,那么第一次迭代发生在数组的第二项上,因此callback的第一个参数是数组的第一项,第二个参数就是数组的第二项。let arr = [10, 20, 30, 40, 50]; let sum = arr.reduce((prev, now) => prev + now) console.log(sum) // -> 150 let sum1 = arr.reduce((prev, now) => prev + now, 110) console.log(sum1) // -> 260
2022年09月04日
693 阅读
12 评论
0 点赞
1
...
4
5