Vue3.0系列——「vue3.0學(xué)習(xí)手冊」第一期
一、項目搭建
vite是尤大大開發(fā)的一款意圖取代webpack的工具。其實現(xiàn)原理是利用ES6的import發(fā)送請求加載文件的特性。攔截這些請求,做一些編譯,省去webpack冗長的打包時間。并將其與Rollup捆綁在一起用于生產(chǎn)。
在開發(fā)過程中沒有捆綁。源代碼中的ES Import語法直接提供給瀏覽器,瀏覽器通過本機<script module>支持對其進行解析,從而為每次導(dǎo)入發(fā)出HTTP請求。開發(fā)服務(wù)器攔截請求,并在必要時執(zhí)行代碼轉(zhuǎn)換。例如,對*.vue文件的導(dǎo)入會在發(fā)送回瀏覽器之前即時進行編譯。
1、全局安裝vite腳手架
npm install -g create-vite-app
2、使用腳手架創(chuàng)建項目
create-vite-app projectName
3、進入項目文件夾
cd projectName
4、安裝依賴
npm install
5、啟動vue3.0項目
npm run dev
二、vue2.x存在的問題
2.x中的一點問題是當(dāng)業(yè)務(wù)不斷增多時,數(shù)據(jù)跟邏輯分散,會很難維護。
<template>
<div>
<div>
<input type="text" v-model="obj.id">
<input type="text" v-model="obj.con">
<button @click="submit">提 交</button>
</div>
<ul>
<li v-for="(item,index) in list" :key="item.id" @click="cli(index)">
{{item.id}}-{{item.con}}
</li>
</ul>
</div>
</template>
<script>
export default {
name:"filterBox",
data(){
return {
list:[
{
id:1,
con:"a"
},
{
id:2,
con:"b"
}
],
obj:{
id:"",
con:""
}
// 代碼數(shù)據(jù)1
// 代碼數(shù)據(jù)2
// ...
}
},
methods:{
cli(index){
this.list = this.list.filter((item,idx)=>idx!==index);
console.log(this.list);
},
submit(){
// const obj = Object.assign({},this.obj);
this.list.push(this.obj);
this.obj.id = "";
this.obj.con = "";
},
// 執(zhí)行代碼代碼邏輯3
// ...
},
computed:{
// 執(zhí)行代碼代碼邏輯1
},
watch:{
// 執(zhí)行代碼邏輯2
}
}
</script>
<style>
</style>
三、組合API
ref
<template>
<div>
<p>{{count}}</p>
<button @click="add">add</button>
</div>
</template>
<script>
import {ref} from "vue"
export default {
name: 'App',
setup(){
// 定義一個名稱叫做count變量,這個變量的初始值是0
// 這個變量發(fā)生該改變之后,vue會自動更新頁面。
const count = ref(0);
// 在組合API中,如果想定義方法,不用定義到methods中,直接在setup函數(shù)中定義即可。
const add = () => {
count.value+=1;
}
// 在組合API中定義的變量/方法,要想在外界使用,必須return出去。
return {
count,
add
}
}
}
</script>
ref只能監(jiān)聽簡單類型的變化,不能監(jiān)聽復(fù)雜類型的變化(對象/數(shù)組)。
它的本質(zhì)是reactive,當(dāng)我們給ref函數(shù)傳遞一個值時,ref函數(shù)會自動將ref轉(zhuǎn)換成reactive。
ref(0) --> reactive({
value:0
})
另外,需要注意的是,如果是通過ref創(chuàng)建出來的數(shù)據(jù),那么在template中使用的時候不用通過.value來獲取。因為Vue會自動給我們添加.value 。
那么vue是如何決定是否需要自動添加.value的。vue在解析數(shù)據(jù)之前,會自動判斷這個數(shù)據(jù)是否是ref類型的,如果是就自動添加.value,如果不是就不自動添加.value。
vue是如何判斷當(dāng)前的數(shù)據(jù)是否是ref類型的?
通過當(dāng)前數(shù)據(jù)的__v_ref來判斷的,如果有這個私有的屬性,并且取值為true,那么就代表是一個ref類型的數(shù)據(jù)。
那么我們開發(fā)者也有自己api來判斷。isRef(數(shù)據(jù)),返回true或者是false。
import {isRef} from 'vue'
reactive
reactive 可以監(jiān)聽復(fù)雜類型的變化,如對象或者數(shù)組。
let state = reactive({
name:"maomin"
});
// 或
let arr = reactive([1,2,3]);
<template>
<div>
<ul>
<li v-for="(item,index) in state.list" :key="item.id" @click="removeItem(index)">{{item.id}}--{{item.con}}</li>
</ul>
</div>
</template>
<script>
import {reactive} from "vue"
export default {
name: 'App',
setup(){
const state = reactive({
list:[
{
id:1,
con:"A"
},
{
id:2,
con:"B"
},
{
id:3,
con:"C"
}
]
});
const removeItem = (index) => {
state.list = state.list.filter((item,i)=>i!==index)
}
return {
state,
removeItem
}
}
}
</script>
我們可以改變下,把數(shù)據(jù)跟邏輯放在一塊,這樣就解決了vue2.x的數(shù)據(jù)跟邏輯分散的問題。
<template>
<div>
<ul>
<li
v-for="(item, index) in state.list"
:key="item.id"
@click="removeItem(index)"
>
{{ item.id }}--{{ item.con }}
</li>
</ul>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
let {state,removeItem} = userReturn();
return {
state,
removeItem,
};
},
};
function userReturn(params) {
const state = reactive({
list: [
{
id: 1,
con: "A",
},
{
id: 2,
con: "B",
},
{
id: 3,
con: "C",
},
],
});
const removeItem = (index) => {
state.list = state.list.filter((item, i) => i !== index);
};
return {state,removeItem}
}
</script>
我們實現(xiàn)了上面的刪除功能,那我們在實現(xiàn)一個添加的功能。
<template>
<div>
<input type="text" v-model="state2.items.id">
<input type="text" v-model="state2.items.con">
<button @click="addItem">添加</button>
<ul>
<li
v-for="(item, index) in state.list"
:key="item.id"
@click="removeItem(index)"
>
{{ item.id }}--{{ item.con }}
</li>
</ul>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
let {state,removeItem} = userRemove();
let {state2,addItem} = userAdd(state);
return {
state,
removeItem,
state2,
addItem
};
},
};
// 添加
function userAdd(state) {
const state2 = reactive({
items:{
id:"",
con:""
}
});
const addItem = () => {
const items = Object.assign({},state2.items);
state.list.push(items);
state2.items.id = "";
state2.items.con = "";
};
return {state,state2,addItem}
}
// 刪除
function userRemove(params) {
const state = reactive({
list: [
{
id: 1,
con: "A",
},
{
id: 2,
con: "B",
},
{
id: 3,
con: "C",
},
],
});
const removeItem = (index) => {
state.list = state.list.filter((item, i) => i !== index);
};
return {state,removeItem}
}
</script>
如果是其他對象,默認(rèn)情況下修改對象,界面不會更新。
<template>
<div>
<p>{{state.time}}</p>
<button @click="add">加一天</button>
</div>
</template>
<script>
import {reactive} from 'vue'
export default {
name:"Demo4",
setup(){
const state = reactive(
{
time:new Date()
}
);
function add () {
state.time.setDate(state.time.getDate()+1);
console.log(state);
}
return {
state,
add
}
}
}
</script>
<style>
</style>
如果想更新,可以通過重新賦值的方法。
<template>
<div>
<p>{{ state.time }}</p>
<button @click="add">加一天</button>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "Demo4",
setup() {
const state = reactive({
time: new Date(),
});
function add() {
const newTime = new Date(state.time.getTime());
newTime.setDate(state.time.getDate() + 1);
state.time = newTime;
console.log(state);
}
return {
state,
add,
};
},
};
</script>
<style>
</style>
同樣,我們開發(fā)者如果要是檢測一個數(shù)據(jù)是否是reactive類型的??梢杂胕sReactive(數(shù)據(jù)),返回true或者false。
import {isReactive} from 'vue'
四、組合API本質(zhì)
compositionAPI與optionAPI可以混合使用。其本質(zhì)是注入。
<template>
<div>
<p>Vue2.x</p>
<button @click="cli1">點擊</button>
<p>Vue3.0</p>
<button @click="cli2">點擊</button>
</div>
</template>
<script>
import {ref} from "vue"
export default {
name:"Demo2",
data(){
return {
msg:"Vue2.x"
}
},
methods:{
cli1(){
alert(this.msg);
}
},
setup(){
let txt = ref("Vue3.0"); // 注入到data函數(shù)內(nèi)
function cli2() { // 注入到methods屬性內(nèi)
alert(txt.value);
}
return {
txt,
cli2
}
}
}
</script>
<style>
</style>
五、setup執(zhí)行時機與注意事項
setup函數(shù),是在beforecreate鉤子之前完成的。所以無法使用data跟methods。
另外要注意的是setup是同步的,不是異步的。
<template>
<div>
<button @click="name">打開</button>
</div>
</template>
<script>
export default {
name:"Demo3",
data(){
return {
msg:"hello"
}
},
setup(){
function name() {
console.log(this.msg); // undefined
}
return {
name
}
}
}
</script>
<style>
</style>
作者:Vam的金豆之路
主要領(lǐng)域:前端開發(fā)
我的微信:maomin9761
微信公眾號:前端歷劫之路