个人网站能做淘宝客吗,山西网站建设企业,免费网站服务器安全软件下载,中国工信备案查询网站先来说说当下市场开发使用的问题#xff0c;目前2021年使用vue3开发的企业还是少#xff0c;基本上都还是以vue2的形式进行开发#xff0c;vue3的开发模式跟react很像#xff0c;这时候有人就会想那我学vue3有用么#xff0c;淦#xff0c;他喵的#xff0c;先别激动目前2021年使用vue3开发的企业还是少基本上都还是以vue2的形式进行开发vue3的开发模式跟react很像这时候有人就会想那我学vue3有用么淦他喵的先别激动冷静听我说说vue3对于现在企业来说都在慢慢的把一些vue2的东西进行升级这个非常关键因为vue2中可以使用vue3的方法vue3不能使用vue2你连vue2都没有搞定还拿个锤子去搞vue3我们先来看看vue3和vue2的一些区别
1.webpack和vite
① vue2使用的是webpack形式去构建项目 webpack是一开始是入口文件然后分析路由然后模块最后进行打包然后告诉你服务器准备好了可以开始干了 ②vue3使用vite构建项目 先告诉你服务器准备完成然后等你发送HTTP请求然后是入口文件Dynamic import动态导入code split point代码分割
最大的好处和区别就是为了让项目中一些代码文件多了以后去保存更新数据时更快能够看到实际效果也就是所谓的热更新
2.main.js文件
vue2中我们可以使用pototype(原型)的形式去进行操作引入的是构造函数 vue3中需要使用结构的形式进行操作引入的是工厂函数 vue3中app组件中可以没有根标签
3.setup函数
setup函数必须要return 返回出去
scriptexport default {name: appName,setup(){//变量let name 打工仔let age 18//方法function say(){console.log(我只是一个${name},今年${age}岁)}//返回一个对象return {name,age,say}}}
/script
你会发现当前的${name}中name不需要使用this去进行操作this的作用只不过是取到某个作用域中变量而已而setup函数提供了当前只在这个作用域中
这时候就很不爽了那岂不是每次我定义的变量和方法都需要return,vue3中给我们提供了 在script标签上添加setup 如script setup/script,相当在编译运行时放到了setup中注setup比beforeCreate、created生命周期更早也就是说在当前直接用this去获取data中的数据打出来的还是undefined setup语法中课接收2个参数setup(props,context) 都知vue2中this.$attrs,this.$slots,this.$emit等同context中attrsslotsemit注当我们只接受一个参数时页面会提示警告但是不影响使用
4.指令与插槽
vue2中使用slot可以直接使用slot,而vue3中必须使用v-slot的形式v-for与v-if在vue2中优先级高的是v-for指令而且不建议一起使用vue3中v-for与v-if,只会把当前v-if当做v-for中的一个判断语句不会相互冲突vue3中移除keyCode作为v-on的修饰符当然也不支持config.keyCodesvue3中移除v-on.native修饰符vue3中移除过滤器filter
5.ref与reactive
ref 把数据变为响应式数据ref把它们变成了对象如果我们直接去操作代码是修改不了的你会发现当前name和age还是通过get和set修改页面这时你需要使用.value并且ref还是Refimpl
templatediv classhomeh1姓名{{name}}/h1h1年龄{{age}}/h1button clicksay修改/button/div
/templatescript
import {ref} from vue
export default {name: Home,setup(){let name ref(中介)let age ref(18)console.log(name)console.log(age)//方法function say(){name波妞age18}return {name,age,say}}
}
/script这样的话那我们在页面上不是得{{name.value}}来做显示实际不用这样的在我们vue3中会检测到你的ref是对象自动会给你加上.value如果我们自己定义的ref对象实例会变为refimpl,这个时候用XX.value.XX进行修改
templatediv classhomeh1姓名{{name}}/h1h1年龄{{age}}/h1h2职业{{job.occupation}}/h2h2薪资{{job.salary}}/h2button clicksay修改/button/div
/templatescript
import {ref} from vue
export default {name: Home,setup(){let name ref(中介)let age ref(18)let jobref({occupation:程序员,salary:10k})console.log(name)console.log(age)//方法function say(){job.value.salary12k}return {name,age,job,say}}
}
/script这时我们打印obj.value他已经不再是refimpl对象变成了proxy对象因为vue3底层是proxy对象基本数据类型都是按Object.defineProperty里面get和set进行数据劫持vue3已经把reactive封装进去了相当于我们在调用ref时会自动调用reactive
reactive 上面我们说ref里面的对象会调用reactive把Object转换为Proxy现在我们直接通过reactive变成Proxy它进行了一个深层次的响应式
templatediv classhomeh1姓名{{name}}/h1h1年龄{{age}}/h1h2职业{{job.occupation}}br薪资{{job.salary}}/h2h3爱好{{hobby[0]}},{{hobby[1]}},{{ hobby[2] }}/h3button clicksay修改/button/div
/templatescript
import {ref,reactive} from vue
export default {name: Home,setup(){let name ref(波妞)let age ref(18)let jobreactive({occupation:程序员,salary:10k})let hobbyreactive([吃饭,睡觉,打豆豆])console.log(name)console.log(age)//方法function say(){job.salary12khobby[0]学习}return {name,age,job,say,hobby}}
}
/script这时你肯定会觉得方法太多了还不如使用ref提供的.value,是不是感觉爽爽爽但是有一个问题如果有一堆数据那不是要一直去.value点到冒烟这个时候你可以用模拟vue2中data的形式就会感觉更香
templatediv classhomeh1姓名{{data.name}}/h1h1年龄{{data.age}}/h1h2职业{{data.job.occupation}}br薪资{{data.job.salary}}/h2h3爱好{{data.hobby[0]}},{{data.hobby[1]}},{{ data.hobby[2] }}/h3button clicksay修改/button/div
/templatescript
import {reactive} from vue
export default {name: Home,setup(){let datareactive({name:波妞,age:18,job:{occupation:程序员,salary:10k},hobby:[吃饭,睡觉,打豆豆]})//方法function say(){data.job.salary12kdata.hobby[0]学习}return {data,say,}}
}
/scriptref与reactive区别
ref定义的是基本数据类型ref通过Object.defineProperty()的get和set实现数据劫持ref操作数据.value读取时不需要.valuereactive定义对象或数组数据类型reactive通过Proxy实现数据劫持reactive操作和读取数据不需要.value
6.vue3的响应式原理
vue2的响应式原理用Object.defineProperty的get和set进行数据劫持从而实现响应式
vue2中只有get和set方法去进行属性的读取和修改操作当我们进行新增删除时页面不会实时更新直接通过下标改数组页面也不会实时更新
vue3中响应式原理使用Proxy进行代理使用window内置对象Reflect反射学了Es6的语法的就知道我们在使用Proxy进行代理好比甲方公司给出需要什么技术的前端攻城狮让乙方去干招聘、面试等环节
Proxy可以拦截对象中任意的属性变化当然包括读写添加删除等Reflect对源对象属性进行操作
const pnew Proxy(data, {
// 读取属性时调用get (target, propName) {return Reflect.get(target, propName)},
//修改属性或添加属性时调用set (target, propName, value) {return Reflect.set(target, propName, value)},
//删除属性时调用deleteProperty (target, propName) {return Reflect.deleteProperty(target, propName)}
}) 7.computed和watch与watchEffct区别
computed vue2中computed方法直接去写上当前方法去进行调用完事
computed:{ //计算属性_suming(){return parseInt(this.one)parseInt(this.two)},dataTimeing(){console.log(计算属性方法);// return 计算属性方法new Date()return 普通方法this.time}},vue3中computed变为组合式Api那么意味着需要引入当前如果需要去修改就需要去终结computed
templatediv classhome姓input typetext v-modelnames.familyNamebr名input typetext v-modelnames.lastNamebr姓名{{fullName}}br/div
/templatescript
import {reactive,computed} from vue
export default {name: Home,setup(){let namesreactive({familyName:波,lastName:妞})fullNamecomputed((){return names.familyName.names.lastName})//修改写法names.fullNamecomputed({get(){return names.familyName.names.lastName},set(value){let nameListvalue.split(.)names.familyNamenameList[0]names.lastNamenameList[1]}})return {names,fullName}}
}
/scriptwatch vue2中watch通过对象的形式去直接监听
watch: {userName: {handler(val,res){console.log(val);console.log(res);},immediate:true,deep:true},}vue3中watch是不是跟computed都是组合APi呢它就是
templatediv classhomeh1当前数字为:{{num}}/h1button clicknum点击数字加一/button/div
/templatescript
import {ref,watch} from vue
export default {name: Home,setup(){let numref(0)//监听单个watch(num,(newValue,oldValue){console.log(当前数字增加了,${newValue},${oldValue})})//监听多个响应数据//watch([num,msg],(newValue,oldValue){// console.log(当前改变了,newValue,oldValue)//})return {num}}
}
/script为什么newValue与oldValue一样呢就很尴尬都是新的数据就算你使用ref来定义还是没有办法监听到oldValue他喵的都给你说了ref定义的对象会自动调用reactive,所以在监视reactive定义的响应式数据时oldValue无法正确获取,并且你会发现它是强制开启深度监视deep:true并且无法关闭。
reactive监听的是响应式数据只是监听其中一个我们都知道vue3会监听reactive或者ref定义并不能监听那需要监听多个属性怎么办呢可以只能是写成下面这种
watch([()names.age,()names.familyName],(newValue,oldValue){console.log(names改变了,newValue,oldValue)
})
如果需要监听深度属性怎么办呢我们都知道reactive是响应式数据属性如果这个属性是对象那么我们就可以开启深度监听
//第一种
watch(() names.job.salary,(newValue,oldValue){console.log(names改变了,newValue,oldValue)
})
//第二种
watch(() names.job,(newValue,oldValue){console.log(names改变了,newValue,oldValue)
},{deep:true})watchEffect watchEffect是vue3中新增的函数看字面意思就知道他也有watch实际上他跟watch功能一样
优势
默认开启 immediate:true需要用哪个就监听哪个值发生改变就调用一次且不需要返回值
watchEffect((){const one num.valueconst tow person.ageconsole.log(watchEffect执行了)
})8.生命周期
vue2中我们是通过new Vue(),在执行beforeCreate与created接着问你有没有vm.$mount(el) vue3中是先准备好所有后再执行 区别beforeCreate与created并没有组合式API中,setup就相当于这两个生命周期函数
setup中
beforeCreateNot needed*createdNot needed*beforeMount onBeforeMountmountedonMountedbeforeUpdateonBeforeUpdateupdated onUpdatedupdatedbeforeUnmount onBeforeUnmountunmounted onUnmounted
9.hooks函数
//一般都是建一个hooks文件夹都写在里面
import {reactive,onMounted,onBeforeUnmount} from vue
export default function (){//鼠标点击坐标let point reactive({x:0,y:0})//实现鼠标点击获取坐标的方法function savePoint(event){point.x event.pageXpoint.y event.pageYconsole.log(event.pageX,event.pageY)}//实现鼠标点击获取坐标的方法的生命周期钩子onMounted((){window.addEventListener(click,savePoint)})onBeforeUnmount((){window.removeEventListener(click,savePoint)})return point
}
//在其他地方调用
import useMousePosition from ./hooks/useMousePosition
let point useMousePosition10.toRef与toRefs
toRef相当于ref类型数据
templatediv classhomeh1当前姓名:{{names.name}}/h1h1当前年龄:{{names.age}}/h1h1当前薪水:{{names.job.salary}}K/h1button clicknames.name!点击加!/buttonbutton clicknames.age点击加一/buttonbutton clicknames.job.salary点击薪水加一/button/div
/templatescript
import {reactive} from vue
export default {name: Home,setup(){let namesreactive({name:老谭,age:23,job:{salary:10}})return {names}}
}
/script这时我们只是操作变量如果我们需要去操作页面字符串可以达到响应式吗这个时候我们需要把name.XX变为toRef去进行操作name中的数据 那这时你肯定会去想说句妈卖批我为何不使用ref去改变呢ref也能达到响应式数据效果当前的names里面的数据并不是源数据而是新定义出的数据自然操作修改的也不是源数据的names
return {name:names.name,age:names.age,salary:names.job.salary
}return {name:toRef(names,name),age:toRef(names,age),salary:toRef(names.job,salary)
}return {name:ref(names.name),age:ref(names.age),salary:ref(names.job.salary),
}toRefs toRefs与toRef有什么不同呢字面意思也能看出来s肯定是更多的意思这时你又在猜想是这样的自信一些特喵的当前...是结构了一次不懂的可以去看看Es6这就不过多的谈 h1当前姓名:{{name}}/h1h1当前薪水:{{job.salary}}K/h1
return {...toRefs(names)
}11.router
vue2中还是使用this. r o u t e r . p u s h 来 进 行 路 由 跳 转 在 v u e 3 中 没 有 这 些 而 是 定 义 了 一 个 v u e − r o u t e r , 直 接 引 入 u s e R o u t e , u s e R o u t e r 相 当 于 v u e 2 中 提 供 的 ‘ t h i s . router.push来进行路由跳转在vue3中没有这些而是定义了一个vue-router,直接引入useRoute,useRouter相当于vue2中提供的this. router.push来进行路由跳转在vue3中没有这些而是定义了一个vue−router,直接引入useRoute,useRouter相当于vue2中提供的‘this.routethis. r o u t e r ‘ , 别 问 这 ‘ t h i s . router,别问这this. router‘,别问这‘this.routethis.$router有什么区别这都没看过我建议你去先看看vue2
import {useRouter,useRoute} from vue-router;
setup(){const router useRouter()const route useRoute()function fn(){this.$route.push(/about)}onMounted((){console.log(route.query.code)})return{fn}
}12.全局Api的转移很重要 2.x 全局 API Vue3.x 实例 API(app)Vue.config.xxxxapp.config.xxxxVue.config.productionTip移除Vue.componentapp.componentVue.directiveapp.directiveVue.mixinapp.mixinVue.useapp.useVue.prototypeapp.config.globalPropertiesvue2中可以通过Vue.prototype去操作原型在vue3中只能通过app.config.globalProperties当时玩的时候还以为自己写错了修改的这些你会发现改动的东西挺多
其他APi(了解)
13.shallowReactive与shallowRef
shallowReactive浅层次的响应式,它就是只把第一层的数据变为响应式深层的数据不会变为响应式,shallowRef如果定义的是基本类型的数据那么它和ref是一样的不会有什么改变但是要是定义的是对象类型的数据那么它就不会进行响应式之前我们说过如果ref定义的是对象那么它会自动调用reactive变为Proxy,但是要是用到的是shallowRef那么就不会调用reactive去进行响应式。
shallowReactive只处理对象最外层属性的响应式浅响应式。shallowRef只处理基本数据类型的响应式, 不进行对象的响应式处理
let person shallowReactive({name:大理段氏,age:10,job:{salary:20}
})
let x shallowRef({y:0
})14.readonly与shallowReadonly
readonly是接收了一个响应式数据然后重新赋值返回的数据就不允许修改深层只读shallowReadonly却只是浅层只读第一层只读其余层可以进行修改
namesreadonly(names)
namesshallowReadonly(names)
15.toRaw与markRaw
toRaw其实就是将一个由reactive生成的响应式对象转为普通对象。如果是ref定义的话是没有效果的包括ref定义的对象如果在后续操作中对数据进行了添加的话添加的数据为响应式数据当然要是将数据进行markRaw操作后就不会变为响应式可能大家会说不就是和readonly一样吗那肯定不一样咯readonly是根本没办法改但markRaw是不转化为响应式但是数据还会发生改变
templatediv classhomeh1当前姓名:{{names.name}}/h1h1当前年龄:{{names.age}}/h1h1当前薪水:{{names.job.salary}}K/h1h1 v-ifnames.girlFriend女朋友{{names.girlFriend}}/h1button clicknames.name!点击加!/buttonbutton clickaddAges点击加一/buttonbutton clickaddSalary点击薪水加一/buttonbutton clickadd添加女朋友/buttonbutton clickaddAge添加女朋友年龄/button/div
/templatescript
import {reactive,toRaw,markRaw} from vue
export default {name: Home,setup(){let namesreactive({name:老伍,age:23,job:{salary:10}})function addAges(){names.ageconsole.log(names)}function addSalary(){let fullNametoRaw(names)fullName.job.salaryconsole.log(fullName)}function add(){let girlFriend{sex:女,age:40}names.girlFriendmarkRaw(girlFriend)}function addAge(){names.girlFriend.ageconsole.log(names.girlFriend.age)}return {names,add,addAge,addAges,addSalary}}
}
/script16.customRef
customRef创建一个自定义的 ref并对其依赖项跟踪和更新触发进行显式控制 可以使用其特性做防抖节流原生的方法就不具体写说一下概念后续出一个节流防抖递归深浅拷贝等
防抖规定时间内触发同一时间只执行一次执行的这一次可以在最开始也可以在最后节流在规定一定间隔时间内触发同一事件在当前时间内只执行一次下一个时间内也只执行一次当前执行的可以在最开始也可以最后
templateinput typetext v-modelkeyWordh3{{keyWord}}/h3
/templatescript
import {customRef} from vue
export default {name: App,setup() {//自定义一个ref——名为myReffunction myRef(value,times){let timereturn customRef((track,trigger){return {get(){console.log(有人从myRef中读取数据了我把${value}给他了)track() //通知Vue追踪value的变化必须要有并且必须要在return之前return value},set(newValue){console.log(有人把myRef中数据改为了${newValue})clearTimeout(time)time setTimeout((){value newValuetrigger() //通知Vue去重新解析模板必须要有},times)},}})}let keyWord myRef(HelloWorld,1000) //使用自定义的refreturn {keyWord}}
}
/script17.provide与inject
都知道组件传值吧在vue2中如果要在后代组件中使用父组件的数据那么要一层一层的父子组件传值或者用到vuex但是现在无论组件层次结构有多深父组件都可以作为其所有子组件的依赖提供者。这个特性有两个部分父组件有一个 provide 选项来提供数据子组件有一个 inject 选项来开始使用这些数据
//父
import { provide } from vue
setup(){let fullname reactive({name:阿月,salary:15k})provide(fullname,fullname) //给自己的后代组件传递数据return {...toRefs(fullname)}
}
//后代
import {inject} from vue
setup(){let fullname inject(fullname)return {fullname}
}18.响应式判断
isRef: 检查值是否为一个 ref 对象。isReactive检查对象是否是由 reactive 创建的响应式代理。isReadonly: 检查对象是否是由 readonly 创建的只读代理。isProxy检查对象是否是由 reactive 或 readonly 创建的 proxy。
import {ref, reactive,readonly,isRef,isReactive,isReadonly,isProxy } from vue
export default {name:App,setup(){let fullName reactive({name:小唐,price:20k})let num ref(0)let fullNames readonly(fullName)console.log(isRef(num))console.log(isReactive(fullName))console.log(isReadonly(fullNames))console.log(isProxy(fullName))console.log(isProxy(fullNames))console.log(isProxy(num))return {}}
} --------------------- 作者BiKABi 来源CSDN 原文https://blog.csdn.net/weixin_43932097/article/details/121512132 版权声明本文为作者原创文章转载请附上博文链接 内容解析ByCSDN,CNBLOG博客文章一键转载插件