後端開發者的Vue學習之路(四)

首發日期:2019-01-28
修改:前端

  1. 2019-01-29:增長404路由

上節內容回顧:

  • 組件的註冊(全局,局部)
  • 組件的數據傳輸(父子組件,非父子組件)
  • props(數據校驗)
  • 給組件綁定原生事件
  • template
  • 插槽(插槽的做用,命名插槽,插槽的默認內容,做用域插槽)
  • 動態組件
  • $refs

npm




介紹

npm是什麼?
npm 是 JavaScript 世界的包管理工具。js也是能夠建成一個項目的,不少時候前端的功能不多是純粹的本身寫的,咱們會去用別人造好的輪子(日曆插件,圖表插件之類的),若是咱們本身去找輪子,那麼首先要去那個輪子的官網下載(有時候這個步驟會很麻煩)。而npm的服務器上會收集了不少經常使用的js相關的文件(不只僅是js,更準確的說是代碼模塊,一般都是集成一個包),咱們能夠利用npm來下載項目的依賴模塊(包)。
除了依賴,npm還容許用戶從服務器下載並安裝別人編寫的命令行程序到本地使用。【好比vue-cli,安裝了vue-cli,就可使用這個程序來快速創建一個基礎的vue項目】vue


安裝

  • 首先,你須要到node.js 官網下載適合版本的node
  • 安裝node 【省略安裝過程,實在不懂的,能夠自行百度】
  • 測試node是否正常,在命令行輸入下面兩條命令:node -vnpm -v,若是輸出了各自的版本號,那麼就是安裝成功了。


經常使用命令:

這些命令能夠先暫時不記,後面用到的時候還會提一下。node

  • 安裝指定模塊:npm install 包名 【若是要全局安裝,那麼要加上參數-g】【一些第三方的包也是程序,安裝的時候也是使用npm install 程序名
  • 安裝項目中package.json所包含的模塊:npm install
  • 卸載模塊:npm uninstall 包名 【若是還想從package.json中刪除模塊,那麼還須要加上參數--save,即npm uninstall --save 包名
  • 啓動項目:npm start
  • 查看已經安裝的模塊:npm ls
  • 升級npm版本:npm install -g npm


補充:

  • npm下載模塊的時候須要從服務器上下載,若是你嫌慢,能夠考慮更換源,使用國內的cnpm:npm install -g cnpm --registry=http://registry.npm.taobao.org



基於npm的Hello World


1.進入命令行,鍵入命令npm install -g vue-cli【這一步是安裝vue腳手架vue-cli,vue-cli可以快速構建一個vue的基礎項目出來】
2.使用腳手架來建立一個vue項目:vue init webpack my-project 【webpack是建立vue項目的方式,my-project是vue項目的名稱】
webpack


3.等待下載完模塊後,使用cd命令進入項目文件夾後,輸入npm run dev來運行項目。

es6


4.訪問控制檯提示的url,就能夠看到基於npm的hello world了。
web


5.訪問localhost:8080,能夠看到以下的界面,說明一個基礎的vue項目已經初始化完成了:
vue-router


爲何不使用靜態導入來演示後面的例子了?
在後面,咱們將講到多個組件之間的複合使用,在有多個組件的時候,使用單文件來註冊組件是一個比較好的處理,並且在項目擴大的時候會涉及到方方面面的問題(路由啊,數據管理啊等等),這時候靜態導入就不太適合了,開發效率過低了。vuex



項目結構分析


項目構建完以後,讓咱們來分析一下「該在哪一個目錄寫下哪些代碼」
vue-cli

  • node_modules目錄:node_modules是項目依賴模塊的目錄,裏面的一個個文件夾都是項目依賴的模塊。通常不須要理會。咱們使用npm install來安裝依賴模塊的時候就是把模塊下載到這裏。
  • build目錄:build目錄是關於項目構建信息的目錄,裏面主要是webpack構建項目的一些配置。如今暫時不講,後面再講。
  • config目錄:
    • config目錄是存放項目的配置文件的目錄。
    • 基礎配置信息在index.js
    • 開發環境下的配置信息:dev.env.js
    • 線上產品環境下的配置信息:prod.env.js
  • static目錄:存放項目的靜態資源文件,這個目錄是開放訪問的。
  • package.json和package-lock.json文件:
    • package.json文件包含了項目依賴模塊的列表,使用npm 來安裝項目依賴模塊的時候都是從package.json來判斷須要什麼依賴的。
    • package-lock.json文件包含了項目依賴模塊的一些限制信息(限制版本號,限制下載地址,限制哈希值)
  • .eslintrc.js和.eslintignore文件:
    • .eslintrc.js是關於eslint的語法規則的文件。
    • .eslintignore是指定哪些文件或文件夾忽略eslint語法檢測。
  • index.html文件:是當前項目的首頁文件。
  • .babelrc文件:是一個關於vue語法與js語法轉換的文件【通常不須要理會】
  • src目錄:是項目的源代碼目錄
    • main.js:是項目的入口文件,包含了新建根實例等操做。(之後可能還會有全局註冊組件等操做。)
    • router目錄:用於設置vue路由信息的目錄
    • store目錄:用於設置vuex數據管理的目錄
    • App.vue文件:是項目的根組件。
    • components目錄:組件相關的目錄,單文件組件通常都存放在這裏
    • assets目錄:靜態資源存放處【與static的區別是,static會原封不動地構建起來,而assets會被webpack進行處理,路徑什麼的webpack會自動管理好的】


上面的文件具體不須要太理解,咱們只須要關注src目錄。咱們只須要在src目錄下寫代碼就好。下面將介紹怎麼在src目錄下寫代碼。


用法遷移


項目換到了npm上後,先了解一下前面學習過的內容怎麼在npm建立的vue項目中使用吧。


1.還需不須要手動建立根實例?
已經不須要了,在main.js文件會自動建立一個根實例。


2.根實例管理區域在哪裏?
從main.js文件中,能夠看到根實例所對應的區域的id仍是app,而這個app在index.html中【你能夠嘗試修改index.html,肯定一下是這個區域,好比說能夠修改一些頁面的title】


3.是如何渲染出上面的Hello World頁面的?
能夠看到出來main.js是核心的入口文件,它建立了一個根實例來管理了index.html的app區域,而且聲明瞭內部使用的template,因此在渲染的時候,app區域裏面會渲染成<App/>,而App是一個組件(這是單文件組件,App.vue),因此也就是把App組件中的內容顯示到app區域中。


4.怎麼修改首頁?
從上面來看,首頁就是index.html,核心的顯示區域是app區域,而app區域顯示的是組件App的內容,若是咱們修改App組件(App.vue)中的內容就能夠修改首頁了。


5.怎麼註冊組件?
使用npm來構建項目後,一個組件能夠定義在一個單獨的vue中。
除了以往的那些全局註冊,局部註冊,你還可使用單個vue文件來註冊一個組件(實質至關於局部註冊)。這個步驟這裏能夠簡單地說一下,首先定義一個vue文件,例如App.vue文件,而後在App.vue中定義組件的內容,而且要使用export來「導出」組件,在須要的地方使用import 來導入組件,而後就可使用組件了。(上面的main.js使用App.vue組件的時候也有一行import App from './App')

【上圖有個問題,若是你直接打,你會發現頁面的color都變了,若是你想要在當前組件生效,那麼能夠在style後加個scoped】


6.組件的經常使用屬性的定義:
基本仍是按之前的規則,好比data要是一個函數。


7.router-view是什麼?
若是你嘗試修改App.vue,你會發現裏面有一個router-view,這是什麼呢?這是一個用於路由顯示的元素。它會裝載當前路由所定義的內容。若是你學過iframe或者frame,你就明白這個東西的意義,router-view會根據當前所處的url來顯示對應的內容(這個路由對應的內容在router目錄下的index.js中)。



小提醒


ES6語法

這裏提一下一些在Vue中經常使用的ES6語法:

  • 若是鍵名和值同樣,能夠單寫鍵名。
    • 因此在使用components的時候,若是組件名和組件別名一致,那麼能夠單寫一個。
    • 其餘狀況若是key和value是同樣的時候也能夠單寫key:
  • 若是是一個函數,能夠單寫一個括號


知識補充

  • 在import的時候,若是不寫後綴,會自動查找符合後綴的。順序是:.vue->.js->.json。import Hello from '@/components/Hello'
  • 在上面使用了@,這是一個預約義的路徑,表明src目錄。這個預約義路徑是webpack給咱們的。
  • export,import,export default
  • index.html中的id='app'與App.vue中的id='app'的區別:首先index.html裏的app給vue找到了管理區域,而後在使用template的時候,會把index.html中的<div id="app"></div>渲染成<App/>,而後<App/>再渲染成對應的組件的內容。也就是說index.html裏面的app提供了裝載點,App.vue提供了裝載的內容。【若是修改了App.vue裏面的id,你會發現渲染成功後頁面的id會變。】【而爲了使用好app這個實例,不要修改App.vue的id,否則裝載完內容後,對應的管理區域會指向不明,而致使渲染失敗。】



單文件組件


1.新建vue文件
我選擇在src/components下新建一個Hello.vue


2.定義組件的內容

<template>
  <div class='hello'>{{msg}}</div>
</template>

<script>
export default {
  name: 'Hello',
  data () {
    return {
      msg: 'This is my msg!'
    }
  },
  created: function () {
    console.log('haha')
  }
}
</script>

<style scoped>
.hello{
  color: red
}
</style>


3.在其餘文件中使用組件(這個所謂的其餘文件,也能夠是其餘組件):首先使用import來導入組件,而後使用components來聲明使用組件,最後在組件的template中使用組件

<template>
    <hello></hello>
</template>

<script>
import Hello from '@/components/Hello'
export default {
  name: 'HelloWorld',
  components: {
    Hello
  }
}
</script>


使用注意:

  • 組件的內容必須有一個根元素包裹,除了template之外,template裏面還得有一個根元素。
  • 要進行export default導出,否則這個組件沒法在其餘地方使用。
  • 定義組件的其餘屬性要遵循以往的格式,如data要是一個函數。



路由


  • 在以往,都是經過a元素來進行頁面跳轉的,跳轉的過程能夠稱爲「路由跳轉」,在這裏是一個頁面到另一個頁面的過程。
  • 而在vue中,因爲是單頁面應用,因此這裏的路由本質上是進行了頁面重渲染(同時修改了頁面的地址)。


開啓路由

若是要使用路由,那麼首先要開啓功能:


定義路由

路由與內容的對應信息定義在router目錄下的index.js文件中。


使用路由

數據顯示

  • 首先,路由的數據是使用<router-view></router-view>來顯示的,<router-view></router-view>會渲染出當前路由對應的內容。
  • 咱們能夠嘗試修改一下路由對應信息來顯示其餘組件信息:


路由跳轉

<router-link></router-link>能夠實現點擊後跳轉到指定路由的功能。
<router-link to="/hello">hello</router-link>點擊後能夠跳轉到/hello路由。


帶參路由

動態路徑參數

所謂路徑參數,就是形似https://xxxx.xxx.com/info/1011337448中的1011337448這個參數。這個參數告訴了這個頁面該怎麼渲染。
在路由中,咱們可使用形如/path/:id的方式來匹配參數,:後面跟的是參數名;

而後在組件中使用this.$route.params.參數名來獲取參數。

路徑參數是能夠有多個的,如/hello/:id/:name,這是分別利用this.$route.params.參數名來獲取參數。


查詢參數

所謂查詢參數,就是形如https://xxxx.xxx.com/info?name='lilei'中name='lilei'的這個參數。
給下一個路由帶查詢參數可使用以下的方法:
1.<router-link :to="{path: '/hello',query:{ id :'001'}}" >hello</router-link>,點擊這個獲得的url是/hello?id=001。【這裏使用路由的path來標識路由】


2.<router-link :to="{ name: 'user', query: { userId: 123 }}">User</router-link>【這裏使用路由的name來標識路由】

而後在組件中咱們可使用$route.query.參數名來獲取參數


監聽路由參數變化

若是想要監聽路由參數變化,那麼可使用watch來監聽。


嵌套路由

  • 假如已經有了一個路由/admin,而後再有一個路由/admin/sys的話就是路由進行了嵌套。【這是一種很是常見的狀況】
  • 咱們上面知道了路由的信息是由router-view來顯示的,那麼嵌套的路由裏的信息要用什麼顯示呢?其實仍是用<router-view><router-view>也是能夠嵌套的。
  • 若是咱們在路由的index.js中使用了children來定義嵌套路由,而且在子組件中也建立了一個router-view,那麼嵌套路由的數據會顯示在子組件的<router-view>中,而不是父組件的router-view中(具體看下圖)


步驟:
1.首先,在路由中使用children來定義嵌套路由

2.先訪問/hello,確認App.vue中的router-view渲染了路由/hello的數據

3.在Hello.vue中寫一些文字,用來肯定路由切換時,第一級的router-view的數據沒有被清除。同時新建一個router-view。

4.隨便定義一點Child.vue的內容。
5.先訪問/hello,再訪問/hello/child:


命名視圖

  • 上面講了router-view的嵌套,若是想要在同一組件內使用多個router-view呢?(爲何會須要多個router-view呢?有可能想要發生某些路由變化的時候,頁面某一部分不發生變化,只在某些狀況發生變化,好比側邊欄這樣的東西。一般都想要側邊欄不變化,只有中間的顯示區域發生變化,但若是退出登陸了,那麼兩個部分應該都發生變化。)
  • 能夠給router-view添加一個屬性name,從而讓router-view有名字。<router-view name='left'/>
  • 當一個組件中有多個命名router-view的時候,路由該怎麼定義呢?
  • 若是想要切換路由的時候,但願某些命名路由不變,那麼能夠這樣作:
  • 嵌套路由也能夠與命名路由結合使用:


編程式路由

上面的使用router-link的方式能夠稱爲聲明式路由,下面講的這種叫作編程式路由。
咱們可使用this.$router.push('路由的path')來進行路由跳轉

<template>
    <div>雷猴
      <button @click='search'>跳轉</button>
    </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  methods: {
    search () {
      // this.$router.push('user') // 根據路由的path來跳轉
      // this.$router.push({name: 'user2'}) // 根據路由的name來跳轉
      // this.$router.push({ name: 'user', params: { id: '123' }})
      // 上一行是根據路由的name來跳轉,帶路徑參數,要求path帶路徑參數[若是提供了 path,params 會被忽略]
      this.$router.push({path: '/user', query: {id: 123}}) // 帶查詢參數
    }
  }
}
</script>


404路由

在上面的路由匹配中,若是咱們訪問了一個沒有進行定義的路由,那麼頁面會顯示空白。
咱們能夠在路由的最下面定義一個以下的路由:

這樣就能夠把匹配不到的路由都渲染成指定的頁面。

補充:

  • 路由的複用問題:當路由跳轉時,會複用沒有發生變化的組件。
  • 沒有說的內容:通配路由、匹配優先級、路由組件傳參重定向和別名
  • 一些路由的進階知識也沒講,若是你以爲上面的路由知識不夠用,也能夠上官網看一下。vue-router



vuex


  • [官網的話:]Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
  • [小菜鳥的話:]vuex能夠用來存儲多個組件之間須要共享的數據,而且可以以一種方式來提醒其餘組件某個數據發生了變化。有些數據獲取了以後應該是在全部組件裏面都共享的。好比某些應用中的「城市」這個數據,當選定了城市後,後面的組件的渲染都應該知道選定的城市是什麼。

vuex


  • Vuex由Actions,Mutations,State組成。
    • Actions負責數據的處理,
    • Mutations負責數據修改,
    • State負責數據存儲。
  • 組件想要提交數據到Actions,要使用dispatch;
  • Action要提交數據到Mutations,要使用commit。


開啓vuex並建立store

1.首先進行安裝:npm install vuex --save
2.而後聲明使用vuex,並建立一個store:
【對於大型應用,咱們會但願把 Vuex 相關代碼分割到模塊中。因此下面的代碼寫在src/store/index.js中(請手動新建)】

import Vue from 'vue'
import Vuex from 'vuex'
// 1. 在src\store\index.js中聲明使用vuex
Vue.use(Vuex)
// 2.新建一個store,用來存儲數據
export default new Vuex.Store({
  state: { // store裏面的state用來存儲數據,數據以鍵值對形式存儲
    global_info: 'global_info_msg'
  }
})


3.在根實例中使用store:


使用vuex

上面建立store的時候存儲了一個數據進去,下面講一下怎麼操做這個數據。

獲取數據

【因爲在根實例中使用了store,因此全部的子實例都會有store,咱們可使用this.$store.state.數據名來獲取數據】


改變數據

改變store中的數據有兩種方法,一種是actions->mutations->state;一種是mutations->state。
1.經過actions來改變數據:
首先派發action給actions,使用this.$store.dispatch('action名',參數)來派發action【派發action給actions以後,actions會調用action來處理數據】

定義action如何處理數據,而後使用commit('mutation名', 參數)把數據提交給mutations:

定義mutation修改哪一個數據,利用賦值表達式賦值:


上面的修改數據的操做遵循了下圖的順序:
vuex




2.除了一步步來修改數據,還能夠直接經過mutations來改變數據:this.$store.commit('mutation名',參數),這時候咱們只須要定義一個mutations便可。


項目結構

  • 對於大型應用,咱們會但願把 Vuex 相關代碼分割到模塊中。
  • 咱們可能會有屢次進行上面的store中的數據操做,那麼這意味着咱們須要寫多幾個action和mutation,若是把這些action和mutation都寫在index.js是很贅餘的,咱們一般把action的內容寫到actions.js中,把mutations的內容寫到mutations.js中。

    actions.js的內容能夠相似這樣來寫:

    而後在index.js中導入:

    mutations.js的內容能夠參考上面action.js的方式來寫。

補充:

  • 想了解更多,能夠查看官網的vuex的文檔:https://vuex.vuejs.org/zh/
相關文章
相關標籤/搜索