前言
Vue 這個(gè)東西很強(qiáng),聽說不會(huì)js的學(xué)完后也能用得飛起?就是有點(diǎn)無腦妈橄,本文主要意圖是記錄自己學(xué)習(xí)中的流程和各種疑點(diǎn)庶近,總之它提供給我們有一堆相似的操作,但是要把它用成這個(gè)語言該有的樣子眷蚓,精確到哪個(gè)文件夾該放什么文件鼻种,形成一種開發(fā)的風(fēng)格、規(guī)約沙热,這樣最好不過
剛剛開始學(xué) Vue的時(shí)候用的是 傳統(tǒng)的開發(fā)方式叉钥,把一堆東西塞在 html 頁面里面掌逛,或者鏈接來鏈接去的找筝,就像下面這樣:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script type="text/javascript">
// ... BODY
Vue.component('Tree', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
// ... 過濾器 等等....
new Vue({
data:{
},
methods:{
}
})
</script>
</body>
</html>
這樣在小項(xiàng)目中確實(shí)沒啥問題,但是東西越來越大就會(huì)有煩惱:
- 全局定義 ,強(qiáng)制要求每個(gè)
component
中的命名不得重復(fù)- 字符串模板 (String templates) 缺乏語法高亮忘分,在 HTML 有多行的時(shí)候爵川,需要用到丑>陋的
\
- 不支持 CSS (No CSS support) 意味著當(dāng) HTML 和 JavaScript 組件化時(shí)敷鸦,CSS 明顯被遺漏
- 沒有構(gòu)建步驟 (No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用預(yù)處理器,如 Pug (formerly Jade) 和 Babel
然后現(xiàn)在又突然用到 單文件組件
,模塊化
,組件化
的開發(fā)方式寝贡,一時(shí)半會(huì)有點(diǎn)難受轧膘,
但用了一段時(shí)間過后:真香
<template>
<div>
</div>
</template>
<script>
export default {
name: 'test',
};
</script>
<style scoped>
</style>
至此組件更加內(nèi)聚,低耦合
Vue cli 2.x版本構(gòu)建項(xiàng)目目錄一覽
以下皆為
Vue cli
命令構(gòu)建的項(xiàng)目兔甘,Vue cli 命令:
vue ui
Vue cli 4.x版本構(gòu)建項(xiàng)目目錄一覽
關(guān)于static
,assets
文件夾
相同點(diǎn):資源在html中使用谎碍,都是可以的。
不同點(diǎn):使用assets下面的資源洞焙,在js中使用的話蟆淀,路徑要經(jīng)過webpack中l(wèi)oader編譯,路徑不能直接寫澡匪。static里面的文件build
后只是復(fù)制一遍熔任,路徑要寫絕對路徑注意:在動(dòng)態(tài)的綁定上面,使用assets中的資源會(huì)加載失敗唁情,因?yàn)閣ebpack使用的是
commenJS
規(guī)范疑苔,必須使用require
才可以(在運(yùn)行時(shí)動(dòng)態(tài)的決定請求哪一個(gè)資源進(jìn)來)
總結(jié):
static
中放別人的庫(建議放一些外部第三方)
assets
中放自己的資源
關(guān)于compoents
,views
文件夾
在之前的 vue cli2.x 中我還沒有發(fā)現(xiàn)有個(gè) views 的文件夾,現(xiàn)在多了一個(gè)甸鸟,所以就百度了下:
然后又扯到了一個(gè)
containers
文件夾
總結(jié):
components
中是推薦放常用的一些小組件惦费,這些組件將來可能被復(fù)用到很多個(gè)地方,
views
中推薦放頁面級(jí)的組件抢韭,按照它的命名薪贫,可以想到是各個(gè)視圖,一般views組件不被復(fù)用
containers
屬于容器級(jí)組件刻恭,根據(jù)項(xiàng)目大小決定是否使用
關(guān)于生命周期函數(shù)
我非常好奇的是瞧省,為什么要把
outerHTML
翻譯成外部的HTML
,不應(yīng)該是內(nèi)部的嘛?然后我看了下中文的vue.js文檔鞍匾,看到里面的直接翻譯交洗,我驚了!O鹗纭构拳!
vue的.png
這難到不是對新手理解及其不友好?前輩的直接翻譯梳码,是真的
n p
然后我又查了 MDN,還在一些框架中看到outerHTML 的字樣隐圾,它們的功能都是如此:
outerHTML屬性用來設(shè)置或者返回元素本身以及其后代HTML內(nèi)容
這就好像我剛?cè)腴T編程的時(shí)候伍掀,接觸到的英文教材上面的
context
掰茶,直接被翻譯成了上下文
,那不分明就是執(zhí)行調(diào)用時(shí),入棧的時(shí)候有個(gè)執(zhí)行體么蜜笤?用來保持里面的結(jié)構(gòu)濒蒋,數(shù)據(jù)等等......
Vue 組件的三大組成部分
template 模板:
<template>
<div id="app"> <!--根標(biāo)簽-->
{{mseeage}} <!--插值語句-->
</div>
</template>
每個(gè)模板要求有一個(gè)
container
容器 (必須要有一個(gè)根標(biāo)簽,span
,p
等等內(nèi)聯(lián)元素都行)
script 腳本:
<script>
export default {
name:'app',
data(){
return{
arr:[]
}
},
components:{
...
}
...
}
</script>
在模塊化編程中 data 需要是一個(gè)函數(shù)且返回一個(gè)對象把兔,而不是單純的
key
,value
components 中的 組件名稱命名請參考 Vue 官方風(fēng)格指南
style 樣式表:
<style>
...
</style>
v-bind 動(dòng)態(tài)綁定標(biāo)簽屬性
<div id="app" v-bind:title="titleName">
{{msg}}
</div>
<!--簡寫為:-->
<div id="app" :title="titleName">
{{msg}}
</div>
Vue 插值語句
<span>Message: {{ msg }}</span>
export default{
data(){
return:{
msg:666
}
}
}
v-on: 事件觸發(fā)
<div id="app" v-on:click="test">
{{msg}}
</div>
<!--省略為 @click-->
<div id="app" @click="test">
{{msg}}
</div>
可以將
on
縮寫為@
,比如@keyup
,@click
,@mousemove
v-model 觀察者模式實(shí)現(xiàn)的雙向綁定
<template>
<input type="text" v-model="name" />
</template>
<script>
export default {
data(){
return{
name:''
}
}
}
</script>
在input 中輸入內(nèi)容沪伙,vue組件實(shí)例中的屬性馬上響應(yīng)發(fā)送改變,牽一發(fā)而動(dòng)全身
常用指令
https://cn.vuejs.org/v2/api/#%E6%8C%87%E4%BB%A4
computed 計(jì)算屬性(它是屬性)
<div id="app-name">
<input type="text" name="" v-model="firstname">
<input type="text" name="" v-model="lastname">
<input type="text" name="" v-model="fullname">
</div>
const vm = new Vue({
el:'#app-name',
data:{
//普通屬性
firstname:'Will',
lastname:'Smith',
},
computed:{
// 計(jì)算屬性
fullname:{
get(){
return this.firstname +' '+ this.lastname;
},
set(value){
const names = value.split(' ');
this.firstname = names[0];
this.lastname = names[1];
}
}
}
});
被初始化的時(shí)候調(diào)用一次 參考生命周期示意圖
不定義
get()
,set()
時(shí)fullname
中的執(zhí)行體(context
)為get
時(shí)觸發(fā)計(jì)算屬性內(nèi)部與 data 中有相關(guān)聯(lián)的值也會(huì)觸發(fā)(當(dāng)相關(guān)聯(lián)的值發(fā)送改變的時(shí)候)
vue 知道 計(jì)算屬性
fullname
依賴于 普通屬性firstname
县好,lastname
围橡,當(dāng)它們兩個(gè)中的任意一個(gè)發(fā)生改變時(shí),``fullname的
set`被觸發(fā)
想觀察值發(fā)生的變動(dòng)并且及時(shí)作出反應(yīng)時(shí)缕贡,使用 computed翁授,適合將普通屬性中復(fù)雜一點(diǎn)的邏輯寫在里面
watch 偵聽器(是一個(gè)監(jiān)視者)
<template>
<div>
<el-input v-model="demo"></el-input>
{{value}}
</div>
</template>
<script>
export default {
name: 'index',
data() {
return {
demo: '',
value: ''
};
},
watch: {
demo(newval,oldval) {
this.value = this.demo;
}
}
};
</script>
watch 是一個(gè)屬性,用來監(jiān)視 (
data
)列表中的普通屬性
一旦被檢測的
普通屬性
的值發(fā)生變化,watch 可以捕獲到修改還可以用來監(jiān)視 路由的變化 (
'$route'(to,from){ }
)
computed晾咪、watch收擦、methods 比較
大佬文章 https://blog.csdn.net/zhouzy539/article/details/96340814
vue.js 官網(wǎng)給出 computed 與 methods 的答案是:computed 會(huì)緩存結(jié)果
普通函數(shù)中這樣定義:
methods:{
now:function(){
return Date.now()
}
}
我稍微將官網(wǎng)的例子修改了下,這樣方便我理解谍倦,對比一下下面的 computed 中的計(jì)算屬性 now:
每次手動(dòng)調(diào)用都是新的 Date 值
在計(jì)算屬性中這樣定義:
computed: {
now: function () {
return Date.now()
}
}
$vm.now 始終返回了初始化完成時(shí)候的值塞赂,既緩存了結(jié)果
假設(shè)我們有一個(gè)性能開銷比較大的計(jì)算屬性 A,它需要遍歷一個(gè)巨大的數(shù)組并做大量的計(jì)算昼蛀。然后我們可能有其他的計(jì)算屬性依賴于 A 宴猾。如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter叼旋!如果你不希望有緩存鳍置,請用方法來替代。
w3plus上的總結(jié):
methods
:正如他的名字一樣送淆,它們是掛載在對象上的函數(shù)税产,通常是Vue實(shí)例本身或Vue組件。computed
:屬性最初看起來像一個(gè)方法,但事實(shí)卻又不是方法辟拷。在Vue中撞羽,我們使用data
來跟蹤對特定屬性的更改,得到一定的反應(yīng)衫冻。計(jì)算屬性允許我們定義一個(gè)與數(shù)據(jù)使用相同方式的屬性诀紊,但也可以有一些基于其依賴關(guān)系的自定義邏輯。你可以考慮計(jì)算屬性的另一個(gè)視圖到你的數(shù)據(jù)隅俘。watchers
:這些可以讓你了解反應(yīng)系統(tǒng)(Reactivity System)邻奠。我們提供了一些鉤子來觀察Vue存儲(chǔ)的任何屬性。如果我們想在每次發(fā)生變化時(shí)添加一些功能为居,或者響應(yīng)某個(gè)特定的變化碌宴,我們可以觀察一個(gè)屬性并應(yīng)用一些邏輯。這意味著觀察者的名字必須與我們所觀察到的相符蒙畴。對于w3plus的總結(jié)我的理解:
methods
:和computed寫得一樣的功能來用完全沒毛病贰镣,自己手動(dòng)調(diào)用computed
:可以在數(shù)據(jù)變化的時(shí)候自己調(diào)用,處理復(fù)雜的邏輯膳凝,上面的加粗關(guān)鍵詞[自定義]watchers
: 把它用成它改有的樣子碑隆,比如 實(shí)現(xiàn)特定的功能、產(chǎn)生特定的邏輯蹬音,newvalue
與oldvalue
比較上煤,反應(yīng)系統(tǒng)一詞,我理解為著淆,我們可以把
watchers
定義為普通屬性
的鉤子函數(shù)
,在它數(shù)據(jù)發(fā)送改變后劫狠,我們做點(diǎn)什么
小小總結(jié):
watch
擅長處理的場景:一個(gè)數(shù)據(jù)影響多個(gè)數(shù)據(jù)
computed
擅長處理的場景:一個(gè)數(shù)據(jù)受多個(gè)數(shù)據(jù)影響相比于watch/computed,
methods
不處理數(shù)據(jù)邏輯關(guān)系牧抽,只提供可調(diào)用的函數(shù)
class 與 style 動(dòng)態(tài)綁定
<div id="app-name" class="per" :class="a"></div>
<script>
const vm = new Vue({
el:'#app-name',
data:{
a:'aClass'
}
});
</script>
在瀏覽器中顯示為:
<div id="app-name" class="per aClass"></div>
可取值為:String
,Object
,Array
<div id="app-name">
<p :class="a">class is string </p>
<p :class="{aClass:true , bClass:false}">class is string </p>
<p :class="['aClass','bClass']">class is array </p>
</div>
字符串值會(huì)在組件實(shí)例的 普通屬性和計(jì)算屬性中查找
對象值為
key:value
,value 標(biāo)識(shí)為true
時(shí)才起作用數(shù)組值:按照排列順序起作用,
注意:即使是 <p :class="['a','b']" class="c"> 這樣寫
還是 顯示為 <p class="c a b"> 的覆蓋順序嘉熊。
另外 <p :class="['a','b']" class="a"> 是不會(huì)報(bào)錯(cuò)的
:style=
用法一致,不過表現(xiàn)為這樣:
data(){
return{
newStyle:{
color:'red',
border:'1px solid blue'
}
}
}
Vue 條件渲染 扬舒,v-if/else
, v-show
先看v-if/else
:
<div id="app-name">
<p v-if="isLive">存活</p>
<p v-else="isLive">死亡</p>
<button @click="isLive=!isLive">switch</button>
</div>
const vm = new Vue({
el:'#app-name',
data:{
isLive:false
}
});
改寫成 v-show
<div id="app-name">
<p v-show="isShow">顯示</p>
<p v-show="isShow">不顯示</p>
<button @click="show">switch</button>
</div>
const vm = new Vue({
el:'#app-name',
data:{
isShow:false
},
methods:{
show(){
this.isShow = !(this.isShow)
}
}
});
兩者相同點(diǎn):
- 功能一樣
兩者不同點(diǎn):
v-if else
是 移除與創(chuàng)建元素阐肤,需要通過內(nèi)存來創(chuàng)建v-show
是在頁面中 決定該元素的display
來進(jìn)行切換的
總結(jié):頻繁切換的情況下使用
v-show
比較好
Vue 列表渲染
以前是通過先在頁面上寫好靜態(tài)的 布局,然后設(shè)置
css
,class
讲坎,然后再在js中用語句動(dòng)態(tài)的循環(huán)data.length
次孕惜,使勁的createElement
,setAttribute
,appendChild
, 現(xiàn)在舒服了
<div id="test">
<ul>
<li v-for="(p,index) in filterPersons)" :key="index">{{p.name}}--{{p.age}}</li>
</ul>
</div>
new Vue({
el:'#test',
data:{
persons:[
{name:'Bob',age:18},
{name:'Jack',age:22},
{name:'Anna',age:23}
],
}
}
固定的搞法,
v-for="(p,index) in filterPersons)" :key="index"
for...in
是用key
來遍歷的晨炕,遍歷對象合適不過index
為附加定義的一個(gè)唯一下標(biāo)值:key
作為該元素的唯一標(biāo)識(shí)衫画,注意key
相同時(shí)會(huì)拋出錯(cuò)誤,(可能會(huì)引起更新錯(cuò)誤)
Vue 單個(gè)組件的調(diào)試
先安裝
npm install -g @vue/cli-service-global
再使用命令 vue serve
后面是具體的路徑下的組件
vue serve src/components/Test.vue