文章目錄
VUE簡介
如何你學習過Django的一些知識,這時候想學習一個前端的一些知識,我會推薦你學習vue,因爲你在學習會發現vue在模板方面有一些和Django相似的地方,更容易上手VUE的一些語法,而且vue作者尤雨溪爲一箇中國人,所以他的的中文社區和文檔都非常完善。
VUE官網, VUE網上的介紹很多,看此博客之前,最少有HTML和css的相關知識,和對js有一定了解,你要是對Python開發也有一定經驗那更好,下面我會經常使用Python和Django和Vue做一些比較。
引入VUE
當前我們開始學習一些基礎的Vue時只需要使用cdn進行引入即可,便捷高效
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
https://cdn.jsdelivr.net/npm/vue
中存放的是vue當前最新的版本,(如果是因爲是學習階段,推薦大家可以使用最新的版本)
但是CDN引入必須要在在線環境下才能正常運行,如果你需要一個可以離線運行的文件,可以去將上述連接中的js代碼下載後引入(直接另存爲即可)
當前開始學習,我們就不花費過多時間放在配置上,之後我會單獨寫一篇講解單文件組件的Vue-CLI(創建單文件的Vue腳手架)環境配置文章和基本使用。
開發環境
我當前使用的是vscode進行前端開發,前端開發對環境要求並不高,你可以根據你的喜好選擇開發工具,如果你想的話甚至可以使用記事本( ̄ェ ̄;),如果你和我一樣使用的vscode,我推薦你下載一個插件vue-helper,這個插件可以補全一下vue常用的代碼,下面學習vue的時候,我也會適當的教大家一些常用的簡寫命令。
基本使用
綁定元素( {{}}
)
使用Vue,首先需要創建一個Vue對象,並在這個對象中傳遞el(element:元素)屬性,用來找到一個給Vue渲染的根元素,並且我們可以傳遞一個data屬性,data有點類似與Python類中的__init__
,用於存放一些變量,data中的所有值都可以直接在根元素下使用{{}}來渲染使用! Vue的元素渲染和Django比較相似,都是採用的雙大括號進行包裹,不同的是Vue渲染的元素只能在el綁定的根元素下使用,如果在el外使用則是無效的。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<!-- <div id="dome"></div> 簡寫-> div#dome -->
<div id="dome">
<p>{{name}}</p>
</div>
<p>{{name}}</p>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// new Vue({}) 簡寫-> vnew
new Vue({
el: "#dome",
data:{
name: "這是一個測試項目"
}
})
</script>
</html>
創建函數使用屬性
創建函數需要用到methods屬性, Vue中函數的格式爲函數名:function(參數){}
其中我們函數的內容是放入大括號中的,可以對比一下Python中的函數def 函數名(參數):
還是有較大區別的。在Python中的類裏,如果我們想要引入一個屬性,只需加上self.屬性名
即可,在vue中我們把self替換爲this即可,比如this.name
。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<!-- <div id="dome"></div> 簡寫-> div#dome -->
<div id="dome">
<p>{{fundemo()}}</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// new Vue({}) 簡寫-> vnew
new Vue({
el: "#dome",
data:{
name: "這是一個測試項目"
},
methods: {
//fundemo:function()可以簡寫爲fundemo()
fundemo:function(){
return this.name + "的一個函數"
}
}
})
</script>
</html>
保持持久性
上面我們提到可以使用{{}}雙層大括號直接將vue屬性中的數據或者函數可以渲染到綁定的元素中,並且只要Vue對象中的數據發生變化,那麼在綁定元素中渲染的值也立馬會改變。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<!-- <div id="dome"></div> 簡寫-> div#dome -->
<div id="dome">
<p>{{name}}</p>
<button v-on:click="change">按鈕</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// new Vue({}) 簡寫-> vnew
new Vue({
el: "#dome",
data:{
name: "這是一個測試項目"
},
methods: {
change:function(){
this.name = "這個測試項目被修改了"
}
}
})
</script>
</html>
如果我們需要保證及時Vue中的數據發生改變,頁面也不會被重新渲染,可以用到v-once屬性(添加到需要保存不變的元素標籤中即可),比如上方如果我需要p標籤中的元素不發生改變,只需要把p標籤改爲<p v-once>{{name}}</p>
即可。
顯示原生HTML
如果我們vue中存儲的是一個HTML標籤,我們直接使用雙層大括號渲染會發現,HTML標籤並沒有執行,而是被當成字符串渲染出來了,如果我們想要將其當成HTML標籤執行,就需要藉助v-html
屬性,在需要渲染的地方添加一個標籤中使用v-html綁定需要渲染的屬性即可,如下所示
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<!-- <div id="dome"></div> 簡寫-> div#dome -->
<div id="dome">
<p>{{vdata}}</p>
<p v-html='vdata'></p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// new Vue({}) 簡寫-> vnew
new Vue({
el: "#dome",
data:{
vdata: '<a href="https://www.baidu.com/">我是一個連接</a>',
}
})
</script>
</html>
屬性綁定(v-bind:
或:
)
這裏我們使用class和style做演示進行綁定。
單值綁定
上述我們在渲染模板時都是在標籤中進行渲染,而如果我們想將數據渲染進入標籤內使用雙大括號則無法識別{{}},需要在屬性前加入v-bind:
或者簡寫爲:
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<style>
.color{
color: burlywood;
}
</style>
<title>Vue測試1</title>
</head>
<body>
<!-- <div id="dome"></div> 簡寫-> div#dome -->
<div id="dome">
<!-- 使用大括號"{{vclass}}"無法渲染屬性 -->
<p class="{{vclass}}">{{vdata}}</p>
<!-- 使用v-bind:進行綁定後,即可渲染無需添加大括號 -->
<p v-bind:class="vclass">{{vdata}}</p>
<!-- : 是 v-bind: 的簡寫 -->
<p :class="vclass">{{vdata}}</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
// new Vue({}) 簡寫-> vnew
new Vue({
el: "#dome",
data:{
vdata: "我修改了字體顏色",
vclass: "color"
}
})
</script>
</html>
除了單值綁定外,還有多值綁定等方法,如果想要詳細瞭解v-bind以及v-modle和v-on請看我的另一篇博客中有詳解 ,點擊查看-> Vue中v-bind,v-modle,v-on都是幹什麼的
使用JavaScript表達式
使用vue模板的進行渲染的元素中我們可以直接使用JavaScript表達式,如下,我就在模板中直接使用了幾個js的表達式
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<div id="dome">
<!-- p標籤的style屬性中,我使用了一個JS的三元表達式, vcolor?'red':'blue' 其中規則是,當vcolor值爲真則執行:號前的內容,假這是後面的 -->
<!-- 在元素中,我使用了JS的三個方法將字符串進行了反轉(這三個方法Python中也有,且功能一致), split(" ")表示根據字符串中的空格拆分成列表, .reverse()將列表反轉, .join(" ")將列表根據合成使用空格隔開-->
<p :style="{color:vcolor?'red':'blue'}">{{vdata.split(" ").reverse().join(" ")}}</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: "#dome",
data:{
vdata: '索尼 大法好',
vcolor: 'true'
}
})
</script>
</html>
條件判斷
v-if
vue有些比較好用的屬性,條件判斷就是其中之一,他的功能顧名思義,用if,else來做判斷此標籤是否執行,但是他的寫法和python中的if語句寫法不太一樣,if在Vue中是v-if
, elif是v-else-if
,而else是v-else
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<div id="vclass">
<p :style="{color:vcolor}" v-if = '"vcolor"=="black"'>我是黑色字體</p>
<p :style="{color:vcolor}" v-if-else = '"vcolor"=="red"'>我是紅色字體</p>
<p v-else>當前顯示的不知道是什麼花裏胡哨的顏色</p>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: "#vclass",
data: {
vcolor : "red"
}
})
</script>
</html>
加載多個元素
有時候我們可能會想在一個條件中加載多個HTML元素,那麼我們可以通過template
元素實現,如下。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Vue測試1</title>
</head>
<body>
<div id="vclass">
<template v-if="level < 18">
<p>你當前的等級是{{level}}</p>
<p>你現在還是個連史萊姆都幹不掉的傢伙</p>
</template>
<template v-else-if="level == 18">
<p>你當前的等級是{{level}}</p>
<p>你可以轉職去去幹史萊姆了</p>
</template>
<!-- 注意,這裏不能直接用18 < level < 85 或者像python中使用and也不行,只能是&&表示與和||表示或 -->
<template v-else-if="18 < level && level < 85">
<p>你當前的等級是{{level}}</p>
<p>你爲啥都{{level}}級了還在幹史萊姆!!!</p>
</template>
<template v-else>
<p>你當前的等級是{{level}}???</p>
<p>你這個等級"{{level}}"有點東西啊。</p>
</template>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el: "#vclass",
data: {
level : "80"
}
})
</script>
</html>
注:
- 使用
template
只是一種規範,並非強制性,你也可以使用其他標籤比如div將其包含,可以達到相同效果 - 上述註釋出我也提過,vue中的範圍不支持連寫,需要使用&&或者||做判斷!!
更新狀態
在模板中,Vue會盡量重用已有的元素,而不是重新渲染(頁面中如果已經有你條件中的標籤,這時候如果需要跟進判斷更新局部更新,已有的標籤並不會重新渲染),這樣的好處樹可以變得更加高效,但也會凸顯出一些問題。比如用戶在切換登陸方式時,輸入框中的內容不會被自動清除!比如下列代碼中,我們切換郵箱和手機號輸入,輸入框中的內容會殘留。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>dome2</title>
</head>
<body>
<div id="vdome">
<template v-if="login == 'email'">
<label for="email">郵箱:</label>
<input type="text" name="email" id="email" placeholder="郵箱">
</template>
<template v-else-if="login == 'phone'">
<label for="phone">電話:</label>
<input type="text" name="phone" id="phone" placeholder="電話">
</template>
<!-- 這裏v-on是事件綁定,後面會詳細講解,這裏爲了體現出Vue的一個效果 -->
<button v-on:click="cutLongin">切換登陸方式</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:'#vdome',
data:{
login : 'email',
},
methods:{
cutLongin:function(){
this.login = this.login=='email'?'phone':'email';
}
}
})
</script>
</html>
解決這個問題其實也很簡單,用key綁定即可解決,我們在想要他重新渲染的標籤內綁定一個key值即可解決,比如我們當前想要重新渲染輸入框,即可在input中加入key屬性
<div id="vdome">
<template v-if="login == 'email'">
<label for="email">郵箱:</label>
<!-- 這裏加入了key="emali" -->
<input type="text" name="email" id="email" key="emali" placeholder="郵箱">
</template>
<template v-else-if="login == 'phone'">
<label for="phone">電話:</label>
<!-- 這裏加入了key="phone" -->
<input type="text" name="phone" id="phone" key="phone" placeholder="電話">
</template>
<!-- 這裏v-on是事件綁定,後面會詳細講解,這裏爲了體現出Vue的一個效果 -->
<button v-on:click="cutLongin">切換登陸方式</button>
</div>
v-show
除了v-if能進行判斷外,v-show也能進行判斷
v-if和v-show的區別
- v-if是惰性的,v-if在值爲真的時候纔開始渲染,假的時候並不會進行渲染,而v-show會在頁面加載的時候就進行渲染,如果有值爲假的元素,會將其在標籤中使用
style="display: none;"
元素進行隱藏 - 根據上述可以推出,v-if有着更大的切換開銷(適合在一些切換頻率較低的地方), 而v-show有着更大的初始渲染開銷(適合在一些切換頻率較高的地方)。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>dome3</title>
</head>
<body>
<div id="vdome">
<p v-show='6>5'>我是人類懂王</p>
<p v-show='5>6'>沒有人比我更懂show</p>
<p v-show='!know'>人類登日第一人</p>
<div v-show='know'>
<p>🙌沒有人</p>
<p>👐比我</p>
<p>👌更懂</p>
<p>☝show</p>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el:'#vdome',
data:{
know : true
}
})
</script>
</html>
注意,v-show 不支持 元素,也不支持 v-else。
循環
在模板中,我們可以使用v-for
進行循環,vue中的也可以依靠循環遍歷可迭代對象。vue中的v-for
和Python中的for循環是有一定相似的,特別都是在遍歷字典或者 列表 數組時很方便。vue循環還一個很好用的功能是可以在循環的時候直接獲取索引值(當前循環的次數),只需要多給一個變量接收索引即可。不過索引值從0開始計算,如果需要從1開始計算,可以在引入的時候+1即可。
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>dome4</title>
</head>
<body>
<div id="vdome">
<h1>'{{name}}'的稱號:</h1>
<div>
<!-- 接收多個值時,一定要記得加括號!(i,index) index接收的是索引!需要注意的是這裏接收變量的名字叫什麼都可以,主要是索引值一定在最後一個變量!!! -->
<span v-for="(i,index) in vfor_list">
{{index}}. {{i}}
</span>
</div>
<h2>for循環還能循環字典</h2>
<div>
<p v-for="(key,value,index) in vfor_dict">
<!-- 索引從0開始計算,如果需要從1開始,手動加1即可 -->
{{index+1}}. {{key}}的稱號是:{{value}}
</p>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
new Vue({
el : '#vdome',
data : {
vfor_list: ['美國藥水哥', '推特羅永浩', '油管老八', '紐約王境澤', '人類登日第一人', '人類登日返地第一人', '人類登日返地又登日第一人', '人類登日返地又登日,又返地第一人', '太陽之子', '宇宙學大師', '病毒學天王', '辯論鬼才', '美利堅救星', '間諜之王(主)', '朋克商人', '因果律派大星', '經濟學海綿寶寶', '千層餅特級廚師'],
name: '川 人類之光 普老師',
vfor_dict: {
人類懂王 : '川建國',
祖傳百萬 : '孫宇晨',
這飯真香 : '王境澤',
直播帶貨 : '羅老師'
}
}
})
</script>
</html>
保持狀態
假設我們有多個元素遍歷出來需要渲染,每個渲染的元素都會跟隨一個輸入框,這裏就會造成和上述v-if類似的情況,輸入框不會跟着改變!效果如下:
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>dome5</title>
</head>
<body>
<div id="app">
<div v-for="i in language">
<input type="text" v-bind:placeholder="i">
</div>
<button v-on:click="change_language">更換圖書</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
language: ['python','vue','Django','html']
},
methods: {
change_language: function(){
// 下列函數用於隨機排序(sort進行排序, parseInt裝換爲整數, Math.random()生成隨機數)
this.language.sort((x,y) => {
return 5 - parseInt(Math.random()*10)
});
}}
});
</script>
</html>
如果我們想要輸入框能跟隨元素一起變動,這時候還是需要用到key綁定,但是這裏的key,不過這裏的key一定要和v-for放在同一個標籤中才行,並且因爲這裏我們想要輸入框跟隨着元素一起啓動,所以我們需要key和元素綁定上,所以就需要v-bind:
,例如:<div v-for="i in language" v-bind:key="i">