前言
官網地址:
https://staging-cn.vuejs.org/vue最新版分為兩個版本: Vue3.0(20年9月18日) Vue 3.2 (21年8月10日)
#Vue 3.2 +Vite+volar
Vue3 框架做了大量的性能優化,包括虛擬 DOM,編譯模板、代理的新數據監聽,體積更小的打包文件等。
新的組合式 API (composition-api),更適合大型項目的構建,去除繁瑣的 this 操作;
由于是基于 TypeScript 編寫,對 TypeScript 原生支持更好,更強大的智能類型推導功能;
生命周期的一些改變,vue2 中的 beforeCreate 和 created 被一個新增的 setup 生命周期函數代替;
一些常見 API 如 v-model 的變化,支持對一個組件同時進行多個 v-model 的數據綁定。
vscode 的插件 vetur 對vue3 的composition API語法支持度非常弱,所以開發vue3項目需要將vetur禁用 更換另一個插件
開發vue3安裝并使用: volar 插件
#1.項目創建
Vite 官網:https://cn.vitejs.dev/
yarn create vite my-vue-App --template vue
#2.SFC 單文件組件
html 部分變化不大
vue2的 template 中只能有一個子節點,vue3的 template 中可以寫多個子節點
js 部分內置ts,但是vite創建的項目沒有開啟 , <script lang="ts" setup> 這樣寫即可支持ts
新增setup 語法糖,js代碼大量簡化
代碼中不再出現 this
css 代碼中 可以使用v-bind 指令
<template> <div> </div></template><script setup> let color = '#f60';</script><style scoped>.box{ width: 100px; height: 100px; background: v-bind(color);}</style>
#2. setup語法糖
起初 Vue3.0 暴露變量必須 return 出來,template中才能使用; 這樣會導致在頁面上變量會出現很多次。
vue3.2只需在script標簽中添加setup,可以幫助我們解決這個問題。
1.組件只需引入不用注冊,屬性和方法也不用返回, 也不用寫setup函數,也不用寫export default , 甚至是自定義指令也可以在我們的template中自動獲得。
#3.data 定義
#3.1 直接定義 無響應式
<template> <div> <h1>{{name}}</h1> <!-- 這里雙向綁定失效,直接定義變量沒有響應式特性 --> <input type="text" v-model="name"> </div></template><script setup> let name = '張麻子';</script>
#3.2 ref 定義基本數據類型 有響應式
<template> <div> <h1>{{name}}</h1> <!-- 修改數據 有響應式 --> <input type="text" v-model="name"> <button @click="setData">修改數據</button> </div></template><script setup> import {ref} from 'vue'; let name = ref('張麻子'); //js中修改數據有響應式 const setData = ()=>{ name.value = '黃四郎' } </script>
#3.3 reactvie 定義引用數據類型 有響應式
<template> <div> <h2>{{user.name}}</h2> <!-- 修改數據 有響應式 --> <input type="text" v-model="user.name"> <!-- 新增屬性 --> <button @click="addItem">新增屬性</button> </div></template><script setup>import {ref,reactive} from 'vue'let user = reactive({ name:'張麻子', age:40})// js中新增對象屬性-可以直接賦值和修改(有響應式),在ts環境下,vscode會提示錯誤,但在頁面中可以正常渲染const addItem = ()=>{ user.like='打豆豆'}</script>
#4.methods 方法定義
<template> <div> <!-- 年齡 + --> <h1>{{user.age}}</h1> <!-- 調用方法 --> <button @click="addAge">年齡+</button> </div></template><script setup>import { ref, reactive } from "vue";let user = reactive({ name: "張麻子", age: 40,});//方法const addAge=()=>{ user.age++;}//方法調用方法const getUserInfo=()=>{ addAge() console.log(user.age)}</script>
#5.computed 計算屬性
<script setup>import { ref, reactive, computed } from "vue";let user = reactive({ name: "張麻子", age: 40,});//計算屬性const getAge = computed(()=>{ return '我的年齡'+user.age})</script>
#6.watch 使用
watch(監聽數據源,執行函數,[配置參數]) //配置參數: 立即執行 深度監聽{immediate: true, deep: true }
#6.1 監聽基本數據類型單一數據源
<script setup>import {ref, watch} from 'vue' let name = ref('張麻子') //監聽器watch(name,(newVal,oldVal)=>{ console.log('變量發生了改變...',newVal);})</script>
#6.2 監聽引用數據類型單一數據源
<script setup>import {reactive, ref, watch} from 'vue'let user = reactive({name:'張三',age:14}) //監聽器watch(()=>user.name,(newVal,oldVal)=>{ console.log('對象user中的name屬性發生了變化..',newVal);})</script>
#6.3 監聽引用數據類型 多數據源[深度監聽]
<template> <div> <button @click="addNum()"> 添加隨機數</button> <div v-for="item in nums" :key="item">{{ item }}</div> </div></template><script setup>import { reactive, ref, watch } from 'vue'let nums = reactive([]);//添加隨機數const addNum = () => { let num = Math.ceil(Math.random() * 100); nums.push(num);}//監聽數組變化-深度監聽watch(()=>nums,(newVal,oldVal)=>{ console.log('nums數組發生了變化..',newVal);},{deep:true})</script>
#7.生命周期
vue2 |
vue3.0 |
vue3.2 |
備注 |
beforeCreate |
|
setup |
組件創建之前 可以獲取頂級實例對象 |
created |
|
setup |
組件創建完成,可以獲取變量 |
beforeMount |
|
onBeforeMount |
掛載前,VNdom創建完成,真實dom未渲染 |
mounted |
|
onMounted |
掛載完成,真實dom創建完成,可以獲取dom |
beforeUpdate |
|
onBeforeUpdate |
dom更新前觸發 |
updated |
|
onUpdated |
dom更新完成觸發 |
beforedestroy,destroyed |
beforeUnmount |
onBeforeUnmount |
組件卸載后觸發 所有的掛載的數據 子組件全部卸載后觸發 |
|
errorCaptured |
onErrorCaptured |
在捕獲一個來自后代組件的錯誤時被調用 |
|
renderTracked |
onRenderTracked |
跟蹤虛擬 DOM 重新渲染時調用 |
|
renderTriggered |
onRenderTriggered |
當虛擬 DOM 重新渲染被觸發時調用 |
activated |
activated |
onActivated |
緩存組件激活時調用 |
deactivated |
deactivated |
onDeactivated |
緩存組件失活時調用 |
<template> <div> <div class="box"></div> </div></template><script setup>import { onMounted } from 'vue'; //生命周期鉤子監聽 onMounted(()=>{ console.log(document.querySelector('.box')); //可以獲取dom })</script>
#8.組件使用
- 創建 src/components/Son.vue
- App.vue中導入并使用該組件
- vue3.2 中當我們導入子組件時,setup語法糖會自動去注冊該組件,所以注冊語句不用寫了。
<template> <div> <son></son> </div><script setup>import Son from './components/Son.vue'</script>
#9.組件通信
#9.1 父傳子 defineProps
- 父組件
<template> <div> <Son class="box" title="我是父組件傳遞的標題" :likes="likes"></Son> </div></template><script setup> import Son from './components/Son.vue' let likes = ['張三','李四']</script>
- 子組件
<script setup>const props=defineProps({ title:{ type:String, default:'' }, likes:{ type:Array, default:()=>[] }})</script>
#9.2 子傳父 defineEmits
- 子組件
<template> <div> <button @click="sendData">傳遞數據</button> </div></template><script setup>//定義自定義事件const emit = defineEmits(['send'])//自己的事件執行函數const sendData = () => { //執行自定義事件 emit('send', '我是兒子組件傳遞的數據')}</script>
- 父組件
<template> <div> <Son class="box" @send="getData" ></Son> </div></template><script setup> import Son from './components/Son.vue' //觸發自定義事件-接收數據 const getData = (data)=>{ console.log(data); }</script>