龍山建設(shè)集團(tuán)有限公司網(wǎng)站云南優(yōu)化公司
Vue3 基礎(chǔ)
概述
Vue (發(fā)音為 /vju?/,類(lèi)似 view) 是一款用于構(gòu)建用戶(hù)界面的 JavaScript 框架。它基于標(biāo)準(zhǔn) HTML、CSS 和 JavaScript 構(gòu)建,并提供了一套聲明式的、組件化的編程模型,幫助你高效地開(kāi)發(fā)用戶(hù)界面。無(wú)論是簡(jiǎn)單還是復(fù)雜的界面,Vue 都可以勝任。
Vue 的兩個(gè)核心功能:
- 聲明式渲染:Vue 基于標(biāo)準(zhǔn) HTML 拓展了一套模板語(yǔ)法,使得我們可以聲明式地描述最終輸出的 HTML 和 JavaScript 狀態(tài)之間的關(guān)系。
- 響應(yīng)性:Vue 會(huì)自動(dòng)跟蹤 JavaScript 狀態(tài)并在其發(fā)生變化時(shí)響應(yīng)式地更新 DOM。
Vue3官方文檔
Vite官方文檔
安裝Vue
一、使用CDN
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
二、npm安裝
npm init vue@latest
三、下載JavaScript文件自行托管
使用JS的方式引入Vue
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>vue3簡(jiǎn)單使用</title><script src="./vue3.js"></script>
</head><body><div id="counter"><p>{{uname}}</p><p>{{age}}</p></div><script>// 配置對(duì)象const counter = {data: function () {return {uname: "小明",age: 0}}};// 使用createApp函數(shù)創(chuàng)建一個(gè)應(yīng)用實(shí)例// 傳入配置對(duì)象let app = Vue.createApp(counter)// 應(yīng)用實(shí)例必須調(diào)用mount函數(shù),掛載后才會(huì)渲染出來(lái).mount("#counter");//數(shù)據(jù)雙向綁定app.age = 18;</script>
</body></html>
使用vite
簡(jiǎn)介
Vite是要給web開(kāi)發(fā)構(gòu)建工具,由于其原生ES模塊導(dǎo)入方式,可以實(shí)現(xiàn)閃電般的冷服務(wù)器啟動(dòng)。
使用vite搭建項(xiàng)目
npm create vite@latest
或者:
npm create vite@latest my-vue-app -- --template vue
接著依次執(zhí)行命令啟動(dòng)vue項(xiàng)目:
cd my-vue-app
npm install
npm run dev
模板語(yǔ)法
Vue 使用一種基于 HTML 的模板語(yǔ)法,使我們能夠聲明式地將其組件實(shí)例的數(shù)據(jù)綁定到呈現(xiàn)的 DOM 上。所有的 Vue 模板都是語(yǔ)法層面合法的 HTML,可以被符合規(guī)范的瀏覽器和 HTML 解析器解析。
在底層機(jī)制中,Vue 會(huì)將模板編譯成高度優(yōu)化的 JavaScript 代碼。結(jié)合響應(yīng)式系統(tǒng),當(dāng)應(yīng)用狀態(tài)變更時(shí),Vue 能夠智能地推導(dǎo)出需要重新渲染的組件的最少數(shù)量,并應(yīng)用最少的 DOM 操作。
基本使用
v-bind:
可以簡(jiǎn)寫(xiě)為:
v-on:
可以簡(jiǎn)寫(xiě)問(wèn)@
<script>
export default {data() {return {name: "小明123",age: 18,num: 0,rawHtml: "<h2 style='color:red;'>hello msg</h2>",myid: "id01",isBtnDisabled: true,objAttrs: {id: "id01",class: "box"},imgUrl: "https://cn.vitejs.dev/logo-with-shadow.png",attributeName: "id",mouseEvent: "click",}},methods: {changeNum() {this.num++;},changeColor() {this.id = "id01";},alertMsg() {alert("hello world");}}
}
</script><template><!-- 文本插值 --><p>姓名:{{ name }}</p><p>年齡:{{ age }}</p><p>數(shù)量:{{ num }}</p><!-- 僅修改一次 --><p v-once>數(shù)量:{{ num }}</p><button @click="changeNum">修改num</button><!-- 使用html --><p v-html="rawHtml"></p><!-- 屬性綁定 --><p v-bind:id="myid">v-bind</p><!-- v-bind簡(jiǎn)寫(xiě) --><p :id="myid">v-bind2</p><!-- 布爾類(lèi)型 --><button :disabled="isBtnDisabled">v-bind2</button><br><!-- 綁定多個(gè)屬性 --><p v-bind="objAttrs">hello world</p><!-- 動(dòng)態(tài)參數(shù) --><p v-bind:[attributeName]="myid">動(dòng)態(tài)屬性1</p><img v-bind:src="imgUrl" style="width: 50px;"><!-- 簡(jiǎn)寫(xiě) --><p :[attributeName]="myid">動(dòng)態(tài)屬性2</p><button @[mouseEvent]="attributeName = 'class'">動(dòng)態(tài)事件</button><button @click="mouseEvent = 'mouseover'">改變事件</button><br><!-- 點(diǎn)擊事件 --><button v-on:click="changeColor">修改顏色</button><!-- 簡(jiǎn)寫(xiě) --><button @click="changeColor">修改顏色</button><br><!-- 使用JavaScript表達(dá)式 --><p>{{ num + 1 }}</p><p>{{ name.split("").reverse().join("") }}</p>
</template><style>
#id01 {color: red;
}#id02 {color: blue;
}.id01 {color: green;
}.id02 {color: yellowgreen;
}.active {color: red;
}.box {border: 1px dashed red;
}
</style>
條件渲染
<script>export default {data() {return {age: 68,isShow: true}}}
</script><template>
<!-- v-if條件渲染 -->
<p v-if="age < 18">未成年人</p>
<p v-if="age >= 18 && age < 60">年輕人</p>
<p v-else>老人</p><!-- v-show,本質(zhì)是display:none; -->
<p v-show="isShow">hello template</p>
</template>
v-if
:會(huì)根據(jù)條件進(jìn)行渲染,切換時(shí)元素會(huì)被銷(xiāo)毀或重建,因此切換開(kāi)銷(xiāo)大。v-for
:本質(zhì)是通過(guò)display
進(jìn)行顯示和隱藏。
列表渲染
<script>export default {data() {return {userList: [{ name: "張三", age: 19, address: "北京" },{ name: "李四", age: 29, address: "上海" },{ name: "王五", age: 39, address: "廣州" }],userInfo: {name: "小白",title: "頂級(jí)作者",bookName: "西游記"}}}}
</script><template> <!-- v-for遍歷數(shù)組 --><ul><li v-for="(item, index) in userList">編號(hào):{{ index }} 姓名:{{ item.name }} 年齡:{{ item.age }} 地址:{{ item.address }}</li></ul><ul><li v-for="({ name, age, address }, index) in userList">編號(hào):{{ index }} 姓名:{{ name }} 年齡:{{ age }} 地址:{{ address }}</li></ul><!-- v-for遍歷對(duì)象 --><ul><li v-for="(value, key) in userInfo">{{ key }} : {{ value }}</li></ul>
</template>
通過(guò)key管理狀態(tài)
Vue 默認(rèn)按照“就地更新”的策略來(lái)更新通過(guò) v-for
渲染的元素列表。當(dāng)數(shù)據(jù)項(xiàng)的順序改變時(shí),Vue 不會(huì)隨之移動(dòng) DOM 元素的順序,而是就地更新每個(gè)元素,確保它們?cè)谠局付ǖ乃饕恢蒙箱秩尽?/p>
默認(rèn)模式是高效的,但只適用于列表渲染輸出的結(jié)果不依賴(lài)子組件狀態(tài)或者臨時(shí) DOM 狀態(tài) (例如表單輸入值) 的情況。
為了給 Vue 一個(gè)提示,以便它可以跟蹤每個(gè)節(jié)點(diǎn)的標(biāo)識(shí),從而重用和重新排序現(xiàn)有的元素,你需要為每個(gè)元素對(duì)應(yīng)的塊提供一個(gè)唯一的 key
attribute:
<script>export default {data() {return {userList: [{ name: "張三", age: 19, address: "北京" },{ name: "李四", age: 29, address: "上海" },{ name: "王五", age: 39, address: "廣州" }]}},methods: {addUser() {this.userList.unshift({ name: "小白", age: "8", address: "成都" })}}}
</script><template><!-- :key的使用 --><ul><li v-for="item in userList" :key="item"><input type="checkbox">{{ item.name }}</li></ul><button @click="addUser">添加user</button>
</template>
數(shù)組變化偵測(cè)
Vue 能夠偵聽(tīng)響應(yīng)式數(shù)組的變更方法,并在它們被調(diào)用時(shí)觸發(fā)相關(guān)的更新。這些變更方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
計(jì)算屬性
計(jì)算屬性只會(huì)在依賴(lài)值發(fā)生變化時(shí)才會(huì)重新計(jì)算。
<script >
export default {data() {return {message: "hello world",firstMsg: "abc",lastMsg: "efg"}},//方法methods: {reverseMsg2() {console.log("reverseMsg2");return this.message.split("").reverse().join("");}},//計(jì)算屬性computed: {reverseMsg() {console.log("reverseMsg");return this.message.split("").reverse().join("");},// 可寫(xiě)計(jì)算屬性fullName: {// getterget() {return this.firstMsg + "-" + this.lastMsg;},// setterset(newValue) {[this.firstMsg, this.lastMsg] = newValue.split(" ");}}}
}
</script><template><p>{{ message }}</p><p>{{ reverseMsg2() }}</p><p>{{ reverseMsg2() }}</p><p>{{ reverseMsg }}</p><p>{{ reverseMsg }}</p><button @click="message = '你好'">修改message</button><p>{{ fullName }}</p><p>{{ fullName="ABC EFG" }}</p>
</template>
說(shuō)明:
打印了2次“reverseMsg2”,說(shuō)明每次調(diào)用方法都會(huì)執(zhí)行一次;打印了1次“reverseMsg”,說(shuō)明計(jì)算屬性會(huì)緩存。
點(diǎn)擊按鈕修改了message屬性,會(huì)重復(fù)上面操作,說(shuō)明計(jì)算屬性只有依賴(lài)值發(fā)生變化時(shí)才會(huì)重新計(jì)算。
偵聽(tīng)器
監(jiān)聽(tīng)狀態(tài)變化。
<script >
export default {data() {return {message: "hello world",isHidden: true,user: {name: "小明",age: 18,sex: true}}},// 偵聽(tīng)器watch: {// 偵聽(tīng)器,方式一,message發(fā)生變化時(shí)調(diào)用// message(newValue, oldValue) {// console.log("新值:" + newValue, "舊值:" + oldValue);// if (newValue.length < 5 || newValue.length > 10) {// this.isHidden = false;// } else {// this.isHidden = true;// }// }// 偵聽(tīng)器,方式二,初始化時(shí)觸發(fā)message: {immediate: true, // 是否初始化時(shí)調(diào)用handler(newValue, oldValue) {if (newValue.length < 5 || newValue.length > 10) {this.isHidden = false;} else {this.isHidden = true;}}},// 深度監(jiān)聽(tīng),方式一,監(jiān)聽(tīng)對(duì)象的每個(gè)屬性// user: {// handler(newValue) {// console.log(newValue);// console.log(newValue.name);// },// deep: true // 是否深度監(jiān)聽(tīng),給對(duì)象的每個(gè)屬性都加上偵聽(tīng)器// },// 深度監(jiān)聽(tīng),方式二,監(jiān)聽(tīng)對(duì)象的單個(gè)屬性"user.name": {handler(newValue) {console.log(newValue);},deep: true // 是否深度監(jiān)聽(tīng)}}
}
</script><template><p>{{ message }}</p><button @click="message = '你好'">修改message</button><br><input type="text" v-model="message"><br><p :hidden="isHidden">輸入框中的內(nèi)容不能小于5或大于10</p><button @click="user.name = '小白'">修改user.name</button>
</template>
類(lèi)和樣式綁定
<script >
export default {data() {return {message: "hello wold",//classisActive: true,isBgColor: true,classObj: {active: true,bgColor: true},error: null,activeClass: "active",bgColorClass: "bgColor",//styleactiveColor: "red",bgColor: "grey",fontSize: "30px",styleObj: {color: "red",'background-color': "grey",fontSize: "30px"}}},// 計(jì)算屬性computed: {classObject() {return {active: this.isActive && !this.error,bgColor: this.isBgColor && !this.error}}}
}
</script><template><!-- 使用class --><p class="active">hello world1</p><!-- 綁定對(duì)象 --><p :class="{ active: isActive }">hello world2</p><p :class="{ active: isActive, bgColor: isBgColor }">hello world3</p><!-- 綁定對(duì)象簡(jiǎn)寫(xiě) --><p :class="classObj">hello world4</p><!-- 計(jì)算屬性 --><p :class="classObject">hello world5</p><!-- 綁定數(shù)組 --><p :class="[activeClass, bgColorClass]">hello world6</p><button @click="isActive = !isActive">修改active</button><button @click="isBgColor = !isBgColor">修改bgColor</button><!-- 使用內(nèi)聯(lián)樣式 --><p style="color:red;">hello1</p><!-- 綁定對(duì)象 --><p :style="{ color: activeColor, 'background-color': bgColor, fontSize: fontSize }">hello2</p><!-- 綁定對(duì)象 --><p :style="styleObj">hello3</p><!-- 綁定數(shù)組 --><p :style="[styleObj]">hello4</p>
</template><style>
.active {color: red;
}.bgColor {background-color: grey;
}
</style>