vue3和vue2的語(yǔ)法區(qū)別:1、vue2使用的是webpack形式去構(gòu)建項(xiàng)目,而vue3使用vite構(gòu)建項(xiàng)目;2、vue2中可以使用pototype的形式去進(jìn)行操作,引入的是構(gòu)造函數(shù),而vue3中需要使用結(jié)構(gòu)的形式進(jìn)行操作,引入的是工廠函數(shù)。
本教程操作環(huán)境:windows10系統(tǒng)、Vue3版、Dell G3電腦。
vue3和vue2的語(yǔ)法有什么區(qū)別
1.webpack和vite
vue2使用的是webpack形式去構(gòu)建項(xiàng)目
webpack是一開(kāi)始是入口文件,然后分析路由,然后模塊,最后進(jìn)行打包,然后告訴你,服務(wù)器準(zhǔn)備好了可以開(kāi)始干了
vue3使用vite構(gòu)建項(xiàng)目
先告訴你服務(wù)器準(zhǔn)備完成,然后等你發(fā)送HTTP請(qǐng)求,然后是入口文件,Dynamic import(動(dòng)態(tài)導(dǎo)入)code split point(代碼分割)
最大的好處和區(qū)別就是為了讓項(xiàng)目中一些代碼文件多了以后去保存更新數(shù)據(jù)時(shí)更快能夠看到實(shí)際效果,也就是所謂的(熱更新)
2.main.js文件
vue2中我們可以使用pototype(原型)的形式去進(jìn)行操作,引入的是構(gòu)造函數(shù)
vue3中需要使用結(jié)構(gòu)的形式進(jìn)行操作,引入的是工廠函數(shù)
vue3中app組件中可以沒(méi)有根標(biāo)簽
3.setup函數(shù)
setup函數(shù)必須要return 返回出去
<script> export default { name: 'appName', setup(){ //變量 let name = '打工仔' let age = 18 //方法 function say(){ console.log(`我只是一個(gè)${name},今年${age}歲`) } //返回一個(gè)對(duì)象 return { name, age, say } } } </script>
你會(huì)發(fā)現(xiàn)當(dāng)前的${name}中name不需要使用this去進(jìn)行操作,this的作用只不過(guò)是取到某個(gè)作用域中變量而已,而setup函數(shù)提供了當(dāng)前只在這個(gè)作用域中
這時(shí)候就很不爽了,那豈不是每次我定義的變量和方法都需要return,vue3中給我們提供了
在script標(biāo)簽上添加setup 如:<script setup></script>,相當(dāng)在編譯運(yùn)行時(shí)放到了setup中
注:setup比beforeCreate、created生命周期更早,也就是說(shuō)在當(dāng)前直接用this去獲取data中的數(shù)據(jù)打出來(lái)的還是undefined
setup語(yǔ)法中課接收2個(gè)參數(shù)setup(props,context)
都知vue2中this.$attrs,this.$slots,this.$emit等同context中attrs,slots,emit
注:當(dāng)我們只接受一個(gè)參數(shù)時(shí),頁(yè)面會(huì)提示警告,但是不影響使用
4.指令與插槽
vue2中使用slot可以直接使用slot,而vue3中必須使用v-slot的形式
v-for與v-if在vue2中優(yōu)先級(jí)高的是v-for指令,而且不建議一起使用
vue3中v-for與v-if,只會(huì)把當(dāng)前v-if當(dāng)做v-for中的一個(gè)判斷語(yǔ)句,不會(huì)相互沖突
vue3中移除keyCode作為v-on的修飾符,當(dāng)然也不支持config.keyCodes
vue3中移除v-on.native修飾符
vue3中移除過(guò)濾器filter
5.ref與reactive
ref
把數(shù)據(jù)變?yōu)轫憫?yīng)式數(shù)據(jù),ref把它們變成了對(duì)象,如果我們直接去操作代碼是修改不了的,你會(huì)發(fā)現(xiàn)當(dāng)前name和age還是通過(guò)get和set修改頁(yè)面,這時(shí)你需要使用.value,并且ref還是Refimpl
<template> <div class="home"> <h1>姓名:{{name}}</h1> <h1>年齡:{{age}}</h1> <button @click="say">修改</button> </div> </template> <script> 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='波妞' age=18 } return { name, age, say } } } </script>
這樣的話那我們?cè)陧?yè)面上不是得{{name.value}}來(lái)做顯示,實(shí)際不用這樣的,在我們vue3中會(huì)檢測(cè)到你的ref是對(duì)象,自動(dòng)會(huì)給你加上.value,如果我們自己定義的ref對(duì)象,實(shí)例會(huì)變?yōu)閞efimpl,這個(gè)時(shí)候用XX.value.XX進(jìn)行修改
<template> <div class="home"> <h1>姓名:{{name}}</h1> <h1>年齡:{{age}}</h1> <h2>職業(yè):{{job.occupation}}</h2> <h2>薪資:{{job.salary}}</h2> <button @click="say">修改</button> </div> </template> <script> import {ref} from 'vue' export default { name: 'Home', setup(){ let name = ref('中介') let age = ref(18) let job=ref({ occupation:'程序員', salary:'10k' }) console.log(name) console.log(age) //方法 function say(){ job.value.salary='12k' } return { name, age, job, say } } } </script>
這時(shí)我們打印obj.value,他已經(jīng)不再是refimpl對(duì)象,變成了proxy對(duì)象,因?yàn)関ue3底層是proxy對(duì)象,基本數(shù)據(jù)類型都是按Object.defineProperty里面get和set進(jìn)行數(shù)據(jù)劫持,vue3已經(jīng)把reactive封裝進(jìn)去了,相當(dāng)于我們?cè)谡{(diào)用ref時(shí),會(huì)自動(dòng)調(diào)用reactive
reactive
上面我們說(shuō)ref里面的對(duì)象會(huì)調(diào)用reactive,把Object轉(zhuǎn)換為Proxy,現(xiàn)在我們直接通過(guò)reactive變成Proxy,它進(jìn)行了一個(gè)深層次的響應(yīng)式
<template> <div class="home"> <h1>姓名:{{name}}</h1> <h1>年齡:{{age}}</h1> <h2>職業(yè):{{job.occupation}}<br>薪資:{{job.salary}}</h2> <h3>愛(ài)好:{{hobby[0]}},{{hobby[1]}},{{ hobby[2] }}</h3> <button @click="say">修改</button> </div> </template> <script> import {ref,reactive} from 'vue' export default { name: 'Home', setup(){ let name = ref('波妞') let age = ref(18) let job=reactive({ occupation:'程序員', salary:'10k' }) let hobby=reactive(['吃飯','睡覺(jué)','打豆豆']) console.log(name) console.log(age) //方法 function say(){ job.salary='12k' hobby[0]='學(xué)習(xí)' } return { name, age, job, say, hobby } } } </script>
這時(shí)你肯定會(huì)覺(jué)得方法太多了,還不如使用ref提供的.value,是不是感覺(jué)爽爽爽,但是有一個(gè)問(wèn)題,如果有一堆數(shù)據(jù)那不是要一直去.value,點(diǎn)到冒煙,這個(gè)時(shí)候你可以用模擬vue2中data的形式,就會(huì)感覺(jué)更香
<template> <div class="home"> <h1>姓名:{{data.name}}</h1> <h1>年齡:{{data.age}}</h1> <h2>職業(yè):{{data.job.occupation}}<br>薪資:{{data.job.salary}}</h2> <h3>愛(ài)好:{{data.hobby[0]}},{{data.hobby[1]}},{{ data.hobby[2] }}</h3> <button @click="say">修改</button> </div> </template> <script> import {reactive} from 'vue' export default { name: 'Home', setup(){ let data=reactive({ name:'波妞', age:18, job:{ occupation:'程序員', salary:'10k' }, hobby:['吃飯','睡覺(jué)','打豆豆'] }) //方法 function say(){ data.job.salary='12k' data.hobby[0]='學(xué)習(xí)' } return { data, say, } } } </script>
ref與reactive區(qū)別
ref定義的是基本數(shù)據(jù)類型
ref通過(guò)Object.defineProperty()的get和set實(shí)現(xiàn)數(shù)據(jù)劫持
ref操作數(shù)據(jù).value,讀取時(shí)不需要。value
reactive定義對(duì)象或數(shù)組數(shù)據(jù)類型
reactive通過(guò)Proxy實(shí)現(xiàn)數(shù)據(jù)劫持
reactive操作和讀取數(shù)據(jù)不需要.value
6.vue3的響應(yīng)式原理
vue2的響應(yīng)式原理用Object.defineProperty的get和set進(jìn)行數(shù)據(jù)劫持,從而實(shí)現(xiàn)響應(yīng)式
vue2中只有g(shù)et和set方法去進(jìn)行屬性的讀取和修改操作,當(dāng)我們進(jìn)行新增,刪除時(shí),頁(yè)面不會(huì)實(shí)時(shí)更新
直接通過(guò)下標(biāo)改數(shù)組,頁(yè)面也不會(huì)實(shí)時(shí)更新
vue3中響應(yīng)式原理使用Proxy進(jìn)行代理,使用window內(nèi)置對(duì)象Reflect反射,學(xué)了Es6的語(yǔ)法的就知道我們?cè)谑褂肞roxy進(jìn)行代理,好比甲方公司給出需要什么技術(shù)的前端攻城獅,讓乙方去干招聘、面試等環(huán)節(jié)
Proxy可以攔截對(duì)象中任意的屬性變化,當(dāng)然包括讀寫(xiě),添加,刪除等
Reflect對(duì)源對(duì)象屬性進(jìn)行操作
const p=new Proxy(data, { // 讀取屬性時(shí)調(diào)用 get (target, propName) { return Reflect.get(target, propName) }, //修改屬性或添加屬性時(shí)調(diào)用 set (target, propName, value) { return Reflect.set(target, propName, value) }, //刪除屬性時(shí)調(diào)用 deleteProperty (target, propName) { return Reflect.deleteProperty(target, propName) } })
【