(該文章整理于網絡,僅用于學習記錄,如有侵權,請聯系删除)
一. 腳手架搭建(vue-cli 3 ):
# install vue-cli
$ npm install -g vue-cli //全局安裝,将vue變成一個指令行中的指令
# create a new project using the "webpack" boilerplate
$ vue init webpack my-project
# install dependencies and go!
$ cd my-project
$ cnpm install //每次你去下載下傳一整個的應用都要去下載下傳相對應的依賴,每個應用應該有幾十個依賴,這些依賴的資訊在package.json中都有說明,直接npm install 就能直接将所有需要的依賴安裝,我已經把npm 設定成了淘寶的鏡像
$ npm run dev// 這樣就運作起來了,其實這裡的dev這些設定也是 已經提前在package.json裡面設定好了,要注意在你的項目路徑下面運作,不然會找不到package.json檔案的。
二. 解析vue-cli中的頁面結構(工程目錄)
|-- build // 項目建構(webpack)相關代碼
| |-- build.js // 生産環境建構代碼
| |-- check-version.js // 檢查node、npm等版本
| |-- utils.js // 建構工具相關
| |-- vue-loader.conf.js // webpack loader配置
| |-- webpack.base.conf.js // webpack基礎配置
| |-- webpack.dev.conf.js // webpack開發環境配置,建構開發本地伺服器
| |-- webpack.prod.conf.js // webpack生産環境配置
|-- config // 項目開發環境配置
| |-- dev.env.js // 開發環境變量
| |-- index.js // 項目一些配置變量
| |-- prod.env.js // 生産環境變量
| |-- test.env.js // 測試腳本的配置
|-- src // 源碼目錄
| |-- components // vue所有元件
| |-- router // vue的路由管理
| |-- App.vue // 頁面入口檔案
| |-- main.js // 程式入口檔案,加載各種公共元件
|-- static // 靜态檔案,比如一些圖檔,json資料等
|-- test // 測試檔案
| |-- e2e // e2e 測試
| |-- unit // 單元測試
|-- .babelrc // ES6文法編譯配置
|-- .editorconfig // 定義代碼格式
|-- .eslintignore // eslint檢測代碼忽略的檔案(夾)
|-- .eslintrc.js // 定義eslint的plugins,extends,rules
|-- .gitignore // git上傳需要忽略的檔案格式
|-- .postcsssrc // postcss配置檔案
|-- README.md // 項目說明,markdown文檔
|-- index.html // 通路的頁面
|-- package.json // 項目基本資訊,包依賴資訊等
-
main.js 程式入口檔案,加載各種公共元件
第一部分(import)導入要用到的元件
第二部分建立了一個Vue對象,元件裡面寫的是App,也就是說導入 App.vue,在入口的時候将app的東西都顯示出來。
-
看看App.vue裡面寫的是什麼東西
這裡引入了一個元件 componentsA,直接以标簽的形式加在html裡面。
要在下面的export default裡面的components進行注冊,不然是用不了的。
對于元件的了解:元件是可以複用的Vue執行個體,帶有名字,也可以說是一個自定義元素。是頁面的一部分,就是可能其他地方也要用到,是以就封裝起來,是以要用的時候進行導入。
-
關于路由
設定了Helloworld這個元件的path為/
要注意,這個路由的出口就是在html中的<router-view></router-view>
helloworld這個元件最後顯示的應該就是‘welcome to your Vue,js App'
我們在App.vue裡面的html的最下面定義了路由出口
router對于建構大型單頁應用還是有很大優勢的,嵌套路由,視圖切換動畫,具名路徑
三、其他
每個Vue應用都是用Vue函數建立一個新的執行個體開始的。Vue就是一個構造函數,是以我們這個執行個體化的對象vm也繼承了Vue的特點。
new Vue({
el: '#app',
data: {
message:'hello Vue.js'
}
})
el指定挂載的位置,挂載到id為app的元素上
- 響應式系統中加入了所有data對象中所含有的屬性,也就是當這些屬性的值發生改變時,視圖中這些屬性的值也會相應的改變。這也是一個很重要的特點
簡單的例子:
<p div = "app">庫存:{{a}}</p>//html
var vm = new Vue({
el:"#app",
data:{
a:100
}
method:{
function(){ }
}
}) //script
data代表vue對象的資料,data這裡聲明,資料要在method代表vue對象的方法,是以function要在methods這裡聲明。可以看到<p></p>之間的{{a}}就是用了我們下面定義的id為“app"的vm這個對象裡面的data對象的a屬性的值。在控制台輸入 vm.a = 190 回車之後我們看到。這裡的庫存也改變了,這也是Vue的一個特點:響應式(relative)可以想象接入後端資料庫之後處理也是特别友善的。除了資料屬性,還有一些執行個體屬性和方法,他們都有字首$,以便與使用者定義的屬性區分開來。
問題:為什麼元件中的data一定要用reurn 傳回?
- 要做成元件,因為可以多次使用,比較友善。
- 如果多個地方同時用到一個元件,一旦其中一個地方的data改變,用return傳回的話就不會影響到其他元件中data的值,因為不是引用值(引用值就是不用return 直接 f:1,d:2這樣,而且資料隻有一份,一旦更改,其他地方的這個元件也會更改)
數組方法中的concat(),slice(),filter(),直接複制,或者改變數組長度的這些方法不會觸發視圖的更新,因為不會改變現有數組。
四、一些 Vue獨有的函數及其用法
1. v-if
<div id="app_2">
<p v-if="seen">你現在可以看到我</p>
</div> //html
var app2 = new Vue({
el:"#app_2",
data:{
seen:true
}
}) //script
1.1 v-if是類似于一個if的函數,進行判斷并操作,也就是說如果seen這個屬性是true的話,就會顯示文字,如果這個屬性是false的話,就不會顯示文字,是以如果你在控制台輸入app2.seen=false的話,"你現在可以看到我"這行文字是不會出現的。
<div id = "app">
<template v-if="ok">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div> //html
var vm = new Vue({
el:"#app",
data:{
ok:true
}
})
1.2 因為v-if是一個指令,是以必須綁定在一個上,如果要切換多個元素,此時可以把一個 <template> 元素當做不可見的包裹元素,并在上面使用 v-if。最終的渲染結果将不包含 <template> 元素。也就是用一個<template>把那些元素包含起來。
<div v-if="Math.random() > 0.5">
Now you see me
</div>
<div v-else>
Now you don't
</div>
1.3 if else的用法
1.4 和 v-show的差別
v-if 是“真正”的條件渲染,因為它會確定在切換過程中條件塊内的事件監聽器和子元件适當地被銷毀和重建。
相比之下,v-show 就簡單得多——不管初始條件是什麼,元素總是會被渲染,并且隻是簡單地基于 CSS 進行切換。如果需要非常頻繁地切換,則使用 v-show 較好;如果在運作時條件很少改變,則使用 v-if 較好。
2. v-for
2.1 對一個清單進行渲染
v-for 指令需要使用 "item in items "形式的特殊文法,
items 是源資料數組并且 item 是數組元素疊代的别名。
也就是說我們原來執行個體化的對象的data對象中的數組的名字是複數的(例如是products)然後在html中用<li v-for = "product in products"></li>來實作我們的周遊。
當然你用item in products也是沒問題的,用取到的item.text...進行操作,數組有index代表索引,對象有key代表索引(key,value) index從0開始
<div id="app_3">
<ol>
<li v-for = "(todo,index) in todos">
{{ todo.text }} {{index}}
</li>
</ol>
</div> //有索引值的情況
<div id="app_3">
<ol>
<li v-for = "todo in todos">
{{ todo.text }}
</li>
</ol>
</div>//html
var app3 = new Vue({
el: '#app_3',
data: {
todos: [
{ text: '學習 JavaScript' },
{ text: '學習 Vue' },
{ text: '整個牛項目' }
]
}
})
3. v-on
可以用 v-on 指令監聽 DOM 事件,并在觸發時運作一些 JavaScript 代碼。 v-on可以用來接收一個方法,我們應該在執行個體化對象的method中定義方法。
<div id="app_4">
<button v-on:click = "count = count+1">add</button>
<p>您已經點選{{count}}次</p>
</div> //html
var app4 = new Vue({
el:"#app_4",
data:{
count:0
}
})//script
4.v-model
在表單 <input> 及 <textarea> 元素上建立雙向資料綁定。可以監聽使用者的資料并且更新。
<div id="app_5">
<input v-model="message"placeholder="edit">
<p>您輸入的資訊是:{{message}}</p>
<!-- 文本框的雙向資料綁定 -->
</div>//html
var app5 = new Vue({
el:"#app_5",
data:{
message:''
}
})//script
5. v-bind
綁定class,href...
同一個标簽不管用v-bind還是直接<a class="xxx">所綁定的類是不會沖突的。
<div id="app_7">
<a v-bind:href="link" target="_blank" rel="external nofollow" v-bind:class="classA">to success</a>
</div>
var app7 = new Vue({
el:"#app_7",
data:{
link:"https://www.baidu.com",
classA:'red-fonts'
}
})
classA也是我們在data中的參數,可以在classA中指定。
總結:
- v-on,@,methods事件綁定
- v-on修飾符可以指定鍵盤事件
- v-model表單資料模型雙向綁定
五、父子通信
1、子元件向父元件通信
- 建立的元件最好就放在我們的components目錄下面
- 元件名字如果是駝峰形式,例如helloWorld,作為标簽直接導入時就應該是hello-world(這是vue的特點,vue自動為你轉化了)
- 要在父元件裡面的components裡面進行注冊才能用
- 這個就是因為沒有注冊我們的元件的提醒。請注意:我們的元件都是在components下面注冊的,components是和data,methods同一級的。
- 子元件通過$emit向父元件發送資訊,觸發事件,具體步驟如下:
- 1. 在子元件中進行< content @click=”close”>事件的綁定
- 2. 在子元件中的methods對這個close進行定義
- 3.
4. 在父元件中的子元件标簽中綁定on-close這個事件methods:{ close(){ this.emit(‘on-close’) } }
- 5.<dialog :on-close=”beClose”>
- 6.在父元件的methods定義這個事件
methods{ beClose(){ console.log(10) } }
2、父元件向子元件通信
父元件向子元件傳遞資訊時,要在子元件的props裡面進行定義
父元件中向子元件傳number=5;
需要在子元件裡面的props進行聲明,就直接傳遞過去了。
父元件的template.png
子元件.png
注意:props中多個單詞之間要用連接配接符不要用駝峰方式,如下子元件。
子元件駝峰與連接配接符.png
如果要實作動态綁定也十分簡單,注意要綁定,用v-bind或者:
将表單送出的值傳給子元件,将value與myVal綁定起來.png
子元件隻要定義一下就ok了.png
用于一些幻燈片元件的使用啊,具體的資料在父元件那裡的時候。
父元件向子元件傳遞資訊的另外一個方式是插槽<slot></slot>
父元件中的需要在子元件裡面加入<p>和<span>一些内容
子元件中沒有進行修改
顯示出來了,并且在相對應的位置
3.總結
父元件向内傳遞屬性-動态屬性
子元件向外釋出事件
slot插槽傳遞模闆-具名slot
六、vue-router
// 0. 如果使用子產品化機制程式設計,導入Vue和VueRouter,要調用 Vue.use(VueRouter)
// 1. 定義 (路由) 元件。
// 可以從其他檔案 import 進來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 2. 定義路由
// 每個路由應該映射一個元件。 其中"component" 可以是
// 通過 Vue.extend() 建立的元件構造器,
// 或者,隻是一個元件配置對象。
// 我們晚點再讨論嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 建立 router 執行個體,然後傳 `routes` 配置
// 你還可以傳别的配置參數, 不過先這麼簡單着吧。
const router = new VueRouter({
routes // (縮寫) 相當于 routes: routes
})
在html中,我們就可以用<router-link>來進行導航
<router-view/>是渲染出口
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 元件來導航. -->
<!-- 通過傳入 `to` 屬性指定連結. -->
<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由比對到的元件将渲染在這裡 -->
<router-view></router-view>
</div>
在執行個體化的時候, mode: 'history',可以後退。
前端路由參數
在映射表中進行設定
router的index.js檔案夾
color會被做為參數注入到$route.params裡面
apple.vue中擷取路由目前頁面的參數.png
鍵入參數.png
apple.vue中定義的方法取相關參數.png
列印台打出目前頁面參數.png
七、Vuex
Vuex 的狀态存儲是響應式的。當 Vue 元件從 store 中讀取狀态的時候,若 store 中的狀态發生變化,那麼相應的元件也會相應地得到高效更新。
你不能直接改變 store 中的狀态。改變 store 中的狀态的唯一途徑就是顯式地送出 (commit) mutation。這樣使得我們可以友善地跟蹤每一個狀态的變化,進而讓我們能夠實作一些工具幫助我們更好地了解我們的應用。
再次強調,我們通過送出 mutation 的方式,而非直接改變 store.state.count,是因為我們想要更明确地追蹤到狀态的變化。這個簡單的約定能夠讓你的意圖更加明顯,這樣你在閱讀代碼的時候能更容易地解讀應用内部的狀态改變。此外,這樣也讓我們有機會去實作一些能記錄每次狀态改變,儲存狀态快照的調試工具。有了它,我們甚至可以實作如時間穿梭般的調試體驗。
注意事項
記得注冊store!!!!!不然commit,mutation這些它是識别不出來的啊!state也是重點來着
Vuex 通過 store 選項,提供了一種機制将狀态從根元件“注入”到每一個子元件中(需調用 Vue.use(Vuex)):
同步邏輯放在mutation中
異步邏輯放在action中
然後就可以去調用store裡面的屬性。
八、其他重要知識點
1. 優雅的使用v-for 、computed
this在這裡是很重要的!!!!.png
注意綁定啊啊啊啊
沒有:就直接将isShowDialog作為值傳遞進去,這是不行的
雙向資料綁定
執行個體中示範了 input 和 textarea 元素中使用 v-model 實作雙向資料綁定
另一種方式實作 Vue 的響應式原理
衆所周知,vue是通過Object.defineProperty 追蹤依賴,進而實作響應式的。
有兩個不足之處:
- 不能檢測到增加或删除的屬性。
- 數組方面的變動,如根據索引改變元素,以及直接改變數組長度時的變化,不能被檢測到。
原因差不多,無非就是沒有被 getter/setter 。
第一個比較容易了解,為什麼數組長度不能被 getter/setter ?
在知乎上找了一個答案:如果你知道數組的長度,理論上是可以預先給所有的索引設定 getter/setter 的。但是一來很多場景下你不知道數組的長度,二來,如果是很大的數組,預先加 getter/setter 性能負擔較大。
現在有一個替代的方案 Proxy,但這東西相容性不好,遲早要上的。
Proxy,在目标對象之前架設一層攔截。具體,可以參考 http://es6.ruanyifeng.com/#docs/reference
Vue3.0就用的proxy
vue打包有時候會找不到圖檔,主要是打包路徑的問題
https://www.cnblogs.com/diantao/p/7776523.html
更新一下對于computed的認識
其實主要還是為了簡便計算
例如我們有一個這樣的需求: 将輸入兩個文本框的姓氏和名字一起顯示出來。
<input type="text"
v-model="firstName" />
<input type="text"
v-model="lastName" />
<p>{{name}}</p>
data () {
return {
msg: 'Welcome to Your Vue.js App',
firstName: '',
lastName: ''
}
},
computed: {
name () {
return this.firstName + this.lastName
}
}
隻要我們在computed裡面定義的這個name函數已經将firstName和lastName一起拼合起來就好了,然後就可以在标簽裡面直接用name了。
Vue生命周期
我們先來說說幾個最經常用到的。
-
created
執行個體(APP)已經建立,變量還未渲染到模闆
此時修改變量還是能起作用的
-
mounted
變量已經挂載到模闆上面了,此時修改變量也還是能起作用的
-
updated
執行個體更新
-
destoryed
執行個體銷毀
面試題:為什麼要使用VUEJS
實作項目的子產品化,元件化。
實作資料渲染。
提供路由,ajax,資料流等其他功能。