碼文不易啊,轉載請帶上本文鏈接呀,感謝感謝 https://www.cnblogs.com/echoyya/p/14394057.html
在2020年9月中旬,vue.js發布了3.0正式版,在不久的將來,VUE3.0 也終將成為大前端的必然趨勢,
環境搭建
-
node
版本要求:Node.js8.9
或更高版本 ,輸入node -v
查看node版本 -
vue-cli
版本:達到vue-cli4.5.0
以上,可創建vue3.0的項目,支持體驗vue3.0的新特性,(3.x Preview)
,vue -V
查看腳手架版本 -
終端輸入:
vue create project_name
核心知識
一、組件的定義和使用
組件:是維護單一功能,可復用的單個個體,相同的樣式及邏輯即可抽離成組件,方便維護,復用性增強。也是vue3.0項目中,最核心的概念
defineComponent
:vue3.0中提供了一個函數返回傳遞給它的對象,最重要的是:在TypeScript下,給予了組件 正確的參數類型推斷 。此處先不展開介紹,后續會總結 vue3.0 + ts。
setup
:組件的啟動函數,兩個參數: props(父組件傳遞的數據)
,content ( 上下文對象)
,最后return 定義的數據,方法,鈎子函數等,且setup中 沒有this,不能訪問this
<script>
import { defineComponent } from 'vue'
export default defineComponent ({
setup (props, content) {
// TODO 數據,方法,鈎子函數等
return { }
}
})
</script>
二、數據的定義和使用
ref
:定義單個數據
,接受一個參數值並返回一個響應式且可改變的ref 對象
。ref 對象擁有一個指向內部值的單一屬性.value
。
import { ref } from 'vue'
export default {
setup () {
let num1 = ref(10) // Number
let name1 = ref('Echoyya') // String
let arr1 = ref(['a','d','c','d']) // Array
let obj1 = ref({age:20}) // Object
// 獲取及改變 ref對象的值,獲取內部值的單一屬性 value
console.log(num1.value) // 10
num1.value++
console.log(num1.value) // 11
return {
//使用 ref 定義的數據,需要直接 return
num1,name1,arr1,obj1
}
}
}
reactive
: 用於創建響應式數據,接收一個普通對象然后返回該普通對象的響應式代理
,即雙向數據綁定,-
使用 reactive 定義的數據,不需要逐一 return,可以使用 ES6 的擴展運算符。
-
解構會破壞雙向數據綁定的特性, 變更為單向數據綁定
-
解決:vue3.0中添加了新特性,可對當前的數據進行轉換。將其轉換為響應式數據,
toRefs
將數據包裹即可轉換為響應式數據
-
import { reactive, toRefs } from 'vue'
export default {
setup () {
let data = reactive ({
num:33,
arr:['a','d','c','d'],
obj:{age:20},
})
// 獲取及改變:reactive 定義的數據,調用時直接 reactive變量名.數據名,
console.log(data.num) // 33
data.num++
console.log(data.num) // 34
return {
...toRefs(data)
}
}
}
三、方法的定義和使用
創建的方法仍然需要 return
<template>
<div>
<p><button @click="clickNum">{{num}}</button></p>
<p><button @click="clickNum1">{{num1}}</button></p>
<p><button @click="singleMethod">{{name}}</button></p>
</div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue'
export default {
setup () {
let num1 = ref(10)
let name = ref('Echoyya')
let data = reactive({
num:33,
})
// 定義多個方法,不需要逐一 return
let methods = {
clickNum1: () => {
num1.value++
console.log(num1.value);
},
clickNum : () => {
data.num ++
console.log(data.num);
}
}
// 定義單個方法,需要return
let singleMethod = () => {
console.log(name.value)
}
return {
num1,
name,
singleMethod,
...toRefs(data)
...methods,
}
}
}
</script>
四、路由的定義、使用和傳參
- /src/router/index.js:在路由文件中使用了
createRouter
方法
import { createRouter } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = createRouter({
routes
})
export default router
- home組件中使用,路由跳轉及傳遞參數
<template>
<div>
<p><button @click="gotoQuery">query跳轉</button></p>
<p><button @click="gotoParams">params跳轉</button></p>
</div>
</template>
<script>
import { useRouter } from 'vue-router'
export default {
setup (){
// router對象是全局路由的實例。
let router = useRouter()
// 跳轉路由用push: 跳轉時可使用name 和 path,傳遞參數可使用query 和 params
let gotoQuery = () => {
// query: 可以使用name和path,參數顯示在地址欄中, 且頁面刷新參數仍在
router.push({
// name:'About',
path:'/about',
query:{
name:'Echoyya',
age: 25,
obj:JSON.stringify({gender:"f"})
},
})
}
let gotoParams = () => {
// params:只能使用name ,不顯示在地址欄中,且頁面刷新,參數清空 console.log(route.params); 打印空對象
router.push({
name:'Home',
params:{
name:'Echoyya',
age: 25,
obj:JSON.stringify({gender:"f"})
}
})
}
return {
gotoQuery,
gotoParams
}
}
}
- about組件中使用,接收路由參數
import { useRoute } from 'vue-router'
export default {
setup (){
// route對象表示當前的路由信息,包含了當前 URL 解析得到的信息。包含當前的路徑,參數,query對象等。
let route = useRoute()
console.log(typeof route.query.age) //string, query傳遞的參數都是string類型
console.log(route.query); //獲取query傳參
console.log(route.params); //獲取params傳參
return {}
}
}
五、父子組件傳值
-
父 to 子
:通過動態綁定屬性
的方式,子組件在props
中去接收, -
子 to 父
:通過ctx.emit('事件名稱', 傳遞的參數)事件分發
的方式, 父組件當中,調用子組件標簽上綁定自定義事件,其中包含一個參數,即子組件傳遞過來的數據-
ctx.emit('事件名稱', 傳遞的參數)事件分發
, ctx是 setup 函數的第二個參數,上下文對象 -
emit 只能接受兩個參數,其余不生效,第一個參數:事件名稱,第二個: 傳遞的數據
-
事件分發,不一定要通過點擊事件,也可使用鈎子函數等
-
需要傳遞多個參數時,emit第二個參數可選擇數組或是對象
-
father.vue
<template>
<div class="wrapper">
<p>this is father components</p>
<p> 子組件傳遞的值:{{childMsg}}</p>
<!-- msg 自定義屬性,send 自定義監聽事件-->
<p><child :msg="msg" @send="getChildData"></child></p>
</div>
</template>
<script>
import { ref } from 'vue'
import child from '../components/child'
export default {
components:{
child
},
setup() {
let msg = ref('father組件數據')
let childMsg = ref('')
let getChildData = (data)=>{
childMsg.value = data
}
return {
msg,
childMsg,
getChildData
}
},
}
</script>
child.vue
<template>
<div>
this is child components
<p>父組件傳遞過來的值:{{msg}}</p>
<p><button @click="send">傳值給父組件</button></p>
</div>
</template>
<script>
import {ref,onMounted, reactive} from 'vue'
export default {
name:'child',
// props 接收的數據,不能直接修改,如props.xxx = yy
props:{
msg:{
type:String , // 數據類型校驗
require:true , // 是否必傳 默認false
default:'默認值' // require和default 有些沖突,即必填時,可不設置默認值
}
},
setup(props,ctx){
console.log(props.msg); // 父組件傳遞的數據:father組件數據
let childMsg = ref('child組件數據')
let data = reactive({
childNum:10
})
let send = ()=>{
ctx.emit('send',childMsg.value)
// ctx.emit('send',[childMsg.value,data.childNum]) // 數組
// ctx.emit('send',{ // 對象
// msg:childMsg.value,
// num:data.childNum
})
}
return {
childMsg,
send,
...data
}
}
})
</script>
六、狀態管理的定義和使用
狀態管理即 VUEX
,為達到數據共享的目的
- /src/store/index.js:在狀態管理文件中使用了
createStore
方法
import { createStore } from 'vuex'
export default createStore({
// 定義所需要的狀態
state: {
name: 'Echoyya',
},
// 同步修改state ,是方法,不能操作異步操作(包括發送請求及定時器等)
mutations: {
// 可接收兩個參數:一:state,二:需修改的值,payload(可選)
setName(state, payload) {
state.name = payload
},
},
// 提交 mutations
actions: {
// 可接收兩個參數 一:store, 二 要修改的值
asyncSetName(store, params) {
setTimeout(() => {
// commit 是提交mutation, 提交異步的mutations方法
store.commit('setName', params)
console.log(store.state.name)
}, 2000)
}
},
// 模塊化
modules: {}
})
- 組件中調用,VUEX操作數據
<template>
<div>
{{name}}===={{name1}}===={{name2}}
<p><button @click="setName">設置 name</button></p>
<p><button @click="asyncSetName">異步設置 name</button></p>
</div>
</template>
<script>
import { reactive, ref, toRefs, computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup (){
//通過 ref 方式
let name = ref(store.state.name)
// 計算屬性 方式
let name1 = computed(()=>{
return store.state.name + 'computed'
})
//reactive 方式
let data = reactive({
name2:store.state.name + '_reactive'
})
// 觸發 mutations
let setName = ()=>{
console.log(store.state.name) // Echoyya
store.commit('setName','nhyya')
console.log(store.state.name) // nhyya
}
// 觸發 action
let asyncSetName = ()=>{
store.dispatch('asyncSetName','nhyya1212')
}
return {
name,
name1,
...toRefs(data),
setName,
asyncSetName
}
}
})
</script>
七、常用的生命周期
-
setup:不需要引入的生命周期 ,表示組件創建的過程,且沒有this
-
onMounted:比
setup
稍微晚一些執行,表示組件掛載的過程,包括數據, dom元素等,是一個函數,需要傳入一個回調函數執行,無參數。- 常用於:發送請求、數據初始化的操作、接受路由傳遞的參數
-
onUnmounted:與
onMounted
相對應,組件卸載或銷毀(路由跳轉),常用於清除定時器等操作
較 VUE2.0 另有哪些改變?
-
3.0去掉了filter, 沒有beforeCreate created,用setup取代
-
setup里沒有this
-
3.0兼容IE12以上
-
可直接監聽數組類型的數據變化
-
監聽的目標為對象本身,不需要像Object.defineProperty一樣遍歷每個屬性,有一定的性能提升
-
直接實現對象屬性的新增/刪除
-
重構 Virtual DOM:模板編譯時的優化,將一些靜態節點編譯成常量
-
另附上vue3.0 文檔地址: https://v3.cn.vuejs.org/
上述內容並非全部 VUE3 內容,只是我通過一段時間的學習,做的自我總結,以便學習和復習,寫的不准確之處還望大神們能留言指正