vue- Vue-Cli腳手架工具安裝 -建立項目-頁面開發流程-組件生命週期-03

本博客環境

若是這些環境過期了,那就不用浪費時間看這博客了css

Vue-Cli 項目環境搭建

npm (就相似於手機的應用商城,python 中的 pip 也同樣)html

與 python 基礎環境對比

  1. node ~ python 解釋器
    • node 是 js 的解釋器,用 c++ 寫的
  2. npm ~ pip python 的庫管理工具(第三方模塊下載的應用商店)
    • npm 就相似於 pip ,也要換源(經常使用淘寶源 cnpm),下載才快
  3. vue ~ django
    • 相似於 django 是一個大框架

環境搭建

  • 安裝 node
node 官網下載安裝包,傻瓜式安裝:https://nodejs.org/zh-cn/

下面的命令都是在 命令行中 執行-g 參數表明全局(global),會自動配置環境變量)前端

  • 安裝 cnpm (使用淘寶鏡像源)vue

    npm 是 node 自帶的包管理器,cnpm 是淘寶鏡像源(能夠看作是 npm 的國內版本),下載第三模塊會比 npm(國外倉庫去下)快不少,幾乎全部用 npm 的地方均可以用 cnpm 替代java

npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 安裝腳手架工具 vue/cli
cnpm install -g @vue/cli
  • 清空緩存處理(前兩步出錯了再執行這個(把那些下載錯誤的文件刪除掉))
npm cache clean --force

建立啓動 vue 項目

必定要注意當前命令行的目錄位置node

能夠用 webstorm 來編寫 vue 代碼, 專門用來開發前端的,pycharm 的提示及便捷性不如它(自行了解)python

命令建立項目(步驟小多)

先進入到存放項目的目錄下webpack

cd /d E:\PyCharm 2019.1.3\ProjectFile\day010\day066 (項目將會放在 day66 這個文件夾下)c++

建立項目

vue create v-proj(項目名) ,輸入完後會進入到下面的界面

界面操做方式:鍵盤 上下(↑↓)箭頭 選擇要用那個模板,回車選中(進入下面的界面一樣用 上下箭頭 移動光標,按空格選取,回車確認)

咱們選擇下面這個 Manually select features

來到下面這個頁面,來看看這些選項都啥意思

各選項

  • Babel
    • 把 ES6 語法轉換成 ES5 讓瀏覽器能夠解析
  • TypeScript
    • 是 JavaScript 的超集(學起來會比 JavaScript 難一些)
  • Progressive Web App (PWA) Support
    • 有不少優化前臺項目的組件(後期再用到)
  • Router
    • vue 前臺的路由管理
  • Vuex
    • 至關於一個全局 單例,頁面未刷新有效,一刷新就沒了
  • CSS Pre-processors
    • less、sass --> 預編譯語言,寫的也是 css,但它能夠寫邏輯,必須瀏覽器解析成原生 css 纔有用,相對來講 less 會好學一點,兩個小時左右就能學會了
  • Linter / Formatter
    • 限制(團隊)代碼風格(縮進空格個數之類的) ESLint 更嚴格
  • Unit Testing
    • 測試用的
  • E2E Testing
    • 測試用的

咱們選擇下面的這幾個(空格選取)

回車下一步(再一路選大寫的就行)

history 讓 vue 的當頁面應用能夠至此跳轉(其餘的暫時默認便可)

默認配置以下

而後就會自動進行安裝

至此,vue 項目建立完成

啓動 vue 項目(命令行方式)

在命令行下,進入項目根目錄,執行 npm run serve 啓動項目

等待加載後,出現下面的頁面便可在瀏覽器上輸入 localhost:8080 訪問(vue 項目默認端口是 8080)

在瀏覽器上訪問

啓動 vue 項目(pycharm 方式)

命令行方式啓動有着諸多不便,因此咱們仍是選擇採用 pycharm 來啓動吧(其實 webstorm 對 vue 的支持會更好,但不是這裏的重點),下面是 pycharm 啓動須要作的一些配置

先右鍵項目文件夾,用 pycharm 打開

配置 pycharm 啓動

用 pycharm 的綠色的啓動按鈕啓動 vue 項目

頁面效果(至此,pycharm 便可啓動項目)

Vue 項目目錄結構分析

├── v-proj
|   ├── node_modules    // 當前項目全部依賴,通常不能夠移植給其餘電腦環境(版本控制、備份代碼 等等,這個文件通常都排除在外),在新環境下執行 cnpm install 便可從新安裝下載這個文件裏的內容
|   ├── public          
|   |   ├── favicon.ico // 瀏覽器標籤頁圖標(public/index.html 中的 <link rel="icon" href="<%= BASE_URL %>favicon.ico">)
|   |   └── index.html  // 當前項目惟一的頁面
|   ├── src
|   |   ├── assets      // 用來存放靜態資源,如:img、css、js
|   |   ├── components  // 存放小組件(再老一些的版本 components 和 views 是一個文件夾)
|   |   ├── views       // 存放頁面組件(通常是路由跳轉的組件)
|   |   ├── App.vue     // 根組件
|   |   ├── main.js     // 全局腳本文件(項目的入口)
|   |   ├── router.js   // 路由腳本文件(配置路由 url連接 與 頁面組件的映射關係)
|   |   └── store.js    // 倉庫腳本文件(vuex插件的配置文件,數據倉庫)
|   ├── README.md
└   └── **配置文件...

// "├" 輸入法 "v9" 能夠找到這個符號

pycharm 支持 vue 語法

安裝 vue 插件

雙擊 App.vue 能夠看到,沒有任何語法高亮,.vue 文件被識別成了普通文件,那麼咱們能夠經過安裝 vue 插件來解決這個問題

能夠點圖中的 install plugins 來安裝 vue 插件(按提示安裝便可)

也能夠在 pycharm 的 settings 裏下載,下載完成重啓 pycharm 便可

重啓 pycharm 後, pycharm 就能識別 .vue 文件了,而且可以爲咱們提供語法高亮(眼前又瞬間充滿了色彩)

部分 vue 文件剖析

自定義組件並渲染到頁面上

組件文件放在 components 下面,一般首字母大寫

組件一般由如下三部分組成

  1. template
    • 裏面有且只有一個根標籤
  2. script
    • 必須將 {} 導出(導出了外界才能導入) export default
    • 外界導入時,將 {} 賦值給前面的變量(進行關聯)
  3. style
    • style 標籤必須明確 scoped 屬性,表明該樣式只在組件內部起做用(樣式的組件化)

組件的導入與導出

寫代碼的時候有些地方紅色波浪線多是 ESLint 報錯,某個變量未被使用就會這樣,接着寫下去就好,不要太緊張

將組件導出(暴露出來)

組件須要將 實例?(內容豐富了長得很像 vue 實例)導出,外界才能使用

src/components/Test.vue

<template>
<!--    template 裏只能有一個根標籤(做爲一個組件)-->
    <div class="test">
        <p>Test 組件</p>
    </div>
</template>

<script>
    // 須要將其導出,外界才能導入,這個括號至關於一個 vue 實例
    export default {
        name: "Test"
    }
</script>

<style scoped>
    /* style 裏面的這個 scoped 能夠用來限制樣式的控制範圍(僅對這個組件生效)(讓樣式局部化,避免形成 css 衝突)*/
    p {
        color: red
    }
</style>

父級組件導入(暴露出來的)組件

src/views/TestViews.vue

<template>
    <div class="home">
        <!-- 3. 直接在頁面上渲染自定義標籤(在 .vue 結尾的文件中標籤能夠區分大小寫(不像 html 文件,不能區分標籤的大小寫))-->
        <T></T>  <!-- 到時候子組件會直接把這個替換掉 -->
    </div>
</template>

<script>
    // 1. 將組件導入,並賦值給 T (把子組件 export default 那個實例? 跟 變量T ? 關聯起來,在本(父)組件中就能夠直接用 T 來當 Test 組件操做了)
    import T from '@/components/Test'
    // 這個 @ 就等價於 src 文件夾的絕對路徑

    export default {
        // 2.註冊組件
        components: {
            T, // 註冊 T 組件
        }
    }
</script>

在 routers.js 裏配置路由

src/router.js

沒有 history 地址欄就會有 # 標識(localhost:8080/#/路由

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
// ****** 1. 先導入 ******
import Test from './views/TestViews'

Vue.use(Router)

export default new Router({
  mode: 'history',  // 讓 vue 這種單頁面應用也支持 瀏覽器的前進後退(← →) (能夠展開搜索下)
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
    },
    // ****** 2. 註冊一條路由 ******
    {
      path: '/test',  // ****** 3. 一下子直接訪問這個路由便可 localhost:8080/test ******
      name: 'test',
      component: Test
    }
  ]
})

瀏覽器訪問

localhost:8080/test

爲何頁面上會有 Home | About 呢?咱們剛剛又沒寫

爲何頁面上會有 Home | About 呢? - 實際上是根組件 App.vue 裏面寫了

src/App.vue (看裏面的 Home、| 、 About)

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

全局腳本文件 main.js 解析(項目入口)

通常導入的時候會省略後綴,因此 同一文件夾下面儘可能不要重名(導入能夠忽略後綴)

默認寫法(建立 vue 項目自動生成的)

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 新手教程的 使用提示 (要點 next next 的動畫)
Vue.config.productionTip = false

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')  // 等同於 el 掛載

解釋性寫法 咱們比較能理解的寫法(只是至關於對上面的解釋)

import Vue from 'vue'  // 加載vue環境
import App from './App.vue'  // 加載根組件
import router from './router'  // 加載路由環境
import store from './store'  // 加載數據倉庫環境

Vue.config.productionTip = false

new Vue({
    el: '#app',
    router,
    store,
    render: function (readFn) {
        return readFn(App);
    },
});

vue 項目啓動生命週期

加載 mian.js 啓動項目

  • import Vue from 'vue' 爲項目加載vue環境
  • import App from './App.vue' 加載根組件用於渲染替換掛載點
  • import router from './router' 加載路由腳本文件,進入路由相關配置

加載 router.js 文件

爲項目提供路由服務,並加載已配置的路由(連接與頁面組件的映射關係)

注:無論當前渲染的是什麼路由,頁面渲染的必定是根組件,連接匹配到的頁面組件只是替換根組件中的 <router-view></router-view>

監測路由變化來作處理

vue 發生頁面跳轉的原理

若是請求連接改變(路由改變),router 裏匹配到了,會把路由對應的 組件 拿出來,而後把根組件裏的 <router-view></router-view> 標籤替換成 該組件

  • 每次路由跳轉都會走一次組件的生命週期

參與文件

main.js 入口文件

該文件內容不變

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

App.vue 項目根組件

常見項目的根組件( App.vue)都只寫下面這幾行代碼

<template>
    <div id="app">
        <!-- url路徑會加載不一樣的頁面組件
            eg:/red => RegPage  | /blue => BluePage
         來替換router-view標籤,完成頁面的切換
         -->
        <router-view></router-view>
    </div>
</template>

views/RedPage.vue 自定義頁面組件

<template>
    <div class="red-page">
        
    </div>
</template>
<script>
    
    export default {
        name: "RedPage",
        components: {
            
        },
    }
</script>
<style scoped>
    .red-page {
        width: 100vw;
        height: 100vh;
        background-color: red;
    }
</style>

views/BluePage.vue

<template>
    <div class="blue-page">
        
    </div>
</template>
<script>
    
    export default {
        name: "BluePage",
        components: {
            
        }
    }
</script>
<style scoped>
    .blue-page {
        width: 100vw;
        height: 100vh;
        background-color: blue;
    }
</style>

router.js 路由文件

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import RedPage from "./views/RedPage";
import BluePage from "./views/BluePage";

Vue.use(Router);

export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/red',
            name: 'red',
            component: RedPage
        },
        {
            path: '/blue',
            name: 'blue',
            component: BluePage
        }
    ]
})

全局樣式文件配置與應用

jQuery、BootStrap 這些外部環境,都須要在 main.js 裏配

後期可能把路徑配置這些寫成一個配置文件

assets/css/global.css

/*html, body, h1, h2, ul, p {*/
*{
    margin: 0;
    padding: 0;
}
ul {
    list-style: none;
}
a {
    color: black;
    text-decoration: none;
}

main.js 中導入,讓它生效

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false;

// ********* 配置全局樣式 *********
import '@/assets/css/global.css'


// new Vue({
//     router,
//     store,
//     render: h => h(App)
// }).$mount("#app");

new Vue({
    el: '#app',
    router,
    store,
    render: function (readFn) {
        return readFn(App);
    },
});

小案例 - 封裝 Nav 導航欄組件

components/Nav.vue 新建子組件

採用 a 標籤會發生頁面跳轉刷新,從新加載了一次項目界面

--> 而 vue 是單頁面應用,一般採用 <router-link to="/路由"> </router-link> 處理跳轉

  • 每次路由跳轉都會走一次組件的生命週期
<template>
    <div class="nav">
        <!--採用 vue-router 完成頁面跳轉,不能採用 a 標籤(會發生頁面刷新,本質就是從新加載了一次項目界面)-->
        <ul>
            <li>
                <!--<a href="/">主頁</a>-->
                <router-link to="/">主頁</router-link>
            </li>
            <li>
                <router-link to="/red">紅頁</router-link>
            </li>
            <li>
                <router-link to="/blue">藍頁</router-link>
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: "Nav",
    }
</script>

<style scoped>
    .nav {
        width: 100%;
        height: 60px;
        background-color: orange;
    }
    .nav li {
        float: left;
        font: normal 20px/60px '微軟雅黑';
        padding: 0 30px;
    }
    .nav li:hover {
        cursor: pointer;
        background-color: aquamarine;
    }
    .nav li.active {
        cursor: pointer;
        background-color: aquamarine;
    }
</style>

views/HomePage.vue 新建視圖頁面

RedPage.vue與BluePage都是添加下方三個步驟代碼

<template>
    <div class="home">
        <!-- 3)使用Nav組件 -->
        <Nav></Nav>
    </div>
</template>

<script>
    // 1)導入Nav組件
    import Nav from '@/components/Nav'
    export default {
        // 2)註冊Nav組件
        components: {
            Nav,
        }
    }
</script>

新增頁面三步驟

  1. 在views文件夾中建立視圖組件(.vue 文件)
  2. 在router.js文件中配置路由
  3. 設置路由跳轉,在指定路由下渲染該頁面組件(替換根組件中的router-view標籤)
    • 渲染誰,(router-view)就替換成誰

案例

增長一個 tan 頁面 案例代碼

views/TanPage.vue

<template>
    <div class="tan-page">
        <Nav></Nav>
    </div>
</template>

<script>
    import Nav from '@/components/Nav'
    export default {
        name: "TanPage",
        components: {
            Nav
        }
    }
</script>

<style scoped>
    .tan-page {
        width: 100vw;
        height: 100vh;
        background-color: tan;
    }
</style>

router.js

// ...
import TanPage from "./views/TanPage";
export default new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
        // ...
        {
            path: '/tan',
            name: 'tan',
            component: TanPage
        }
    ]
})

components/Nav.vue

...
<li>
    <router-link to="/tan">土頁</router-link>
</li>
...

組件生命週期(鉤子函數剖析)*****

基本概念

詳細的能夠看 vue 官方 API (推薦好好看看官方文檔這塊的介紹)

組件的生命週期:一個組件從建立到銷燬的過程,就稱之爲組件的生命週期

組件建立到銷燬的過程當中,會出現衆多關鍵的時間節點,如:

  • 組件要建立了
  • 組件建立完畢了
  • 組件數據渲染完畢了
  • 組件要被銷燬了
  • 組件銷燬完畢了
  • ...等等 時間節點

每個時間節點,vue 都爲其提供了一個回調函數(在該組件到達該時間節點時,就會觸發對應的回調函數,在函數中就能夠完成該節點須要完成的業務邏輯

生命週期鉤子函數也是 vue 的實例成員

生命週期鉤子函數

vue 官方提供的生命週期鉤子函數

beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
errorCaptured

在 vue 組件的 script 的 export default 導出字典中直接寫鉤子函數

重點鉤子函數:created(其餘函數根據需求來用)

通常該組件請求後臺的數據,都是在該鉤子中完成

  1. 請求來的數據能夠給頁面變量進行賦值(此時實例成員已經加載了)
  2. 該節點還只停留在虛擬 DOM 範疇,若是數據還須要作二次修改再渲染到頁面
  3. 能夠在 beforeMount、mounted 鉤子中添加邏輯處理
export default {
    // ...
    beforeCreate() {
        console.log('組件建立了,但數據和方法還未提供');
        // console.log(this.$data);
        // console.log(this.$options.methods);
        console.log(this.title);
        console.log(this.alterTitle);
    },
    // 該鉤子須要掌握,通常該組件請求後臺的數據,都是在該鉤子中完成
    // 1)請求來的數據能夠給頁面變量進行賦值
    // 2)該節點還只停留在虛擬 DOM 範疇,若是數據還須要作二次修改再渲染到頁面,
    //  能夠在beforeMount、mounted鉤子中添加邏輯處理
    created() {
        console.log('組件建立了,數據和方法已提供');
        // console.log(this.$data);
        // console.log(this.$options.methods);
        console.log(this.title);
        console.log(this.alterTitle);
        console.log(this.$options.name);
    },
    destroyed() {
        console.log('組件銷燬完畢')
    }
}
  • this.$options 能夠拿到全部實例成員,包括自定義成員(好像會讓 vue 提早加載實例成員這些),一堆的屬性這些都在裏面(能夠用它來取自定義屬性)
  • vue 實例能夠直接 this.屬性/方法 取到 實例成員 data、methods 的內容(作了封裝,能夠直接拿到)

  • vue 沒有 this.$method 這個成員屬性

根據請求路徑高亮路由標籤案例

<router-link to="/">主頁</router-link>

  • router-link 最終會被解析爲 a 標籤,用 to 完成指定路徑跳轉,可是不能添加系統事件(由於是組件標籤)
  • 在 js 方法中能夠用 this.$router.push('路徑') 完成 邏輯跳轉
  • 在 js 方法中能夠用 this.$route.path 拿到當前請求的頁面路由

components/Nav.vue

this.$route、this.$router 能夠好好了解一下(搜一下),一個管理路由數據,一個管理路由跳轉

<template>
    <div class="nav">
        <!--採用vue-router完成頁面跳轉,不能採用a標籤(會發生頁面刷新,本質就是從新加載了一次項目界面)-->
        <ul>
            <li @click="changePage('/')" :class="{active: currentPage === '/'}">
                <!--<a href="/">主頁</a>-->
                <!--<router-link to="/">主頁</router-link>-->
                主頁
            </li>
            <li @click="changePage('/red')" :class="{active: currentPage === '/red'}">
                <!--<router-link to="/red">紅頁</router-link>-->
                紅頁
            </li>
            <li @click="changePage('/blue')" :class="{active: currentPage === '/blue'}">
                <!--<router-link to="/blue">藍頁</router-link>-->
                藍頁
            </li>
            <li @click="changePage('/tan')" :class="{active: currentPage === '/tan'}">
                <!--<router-link to="/tan">土頁</router-link>-->
                土頁
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: "Nav",
        data() {
            return {
                // 每渲染一個頁面,都會出現加載 Nav 組件,currentPage 就會被重置,
                // 1)在點擊跳轉事件中,將跳轉的頁面用 數據庫 保存,在鉤子函數中對 currentPage 進行數據更新
                // currentPage: localStorage.currentPage ? localStorage.currentPage: ''
                // 2)直接在 created 鉤子函數中,獲取當前的 url 路徑,根據路徑更新 currentPage
                currentPage: ''
            }
        },
        methods: {
            changePage(page) {
                // console.log(page);
                // 當 Nav 出現渲染,該語句就無心義,由於在 data 中將 currentPage 重置爲空
                // this.currentPage = page;

                // 有 bug,用戶不經過點擊,直接修改請求路徑完成頁面跳轉,數據庫就不會更新數據
                // localStorage.currentPage = page;

                // 任何一個標籤的事件中,均可以經過 router 完成邏輯條件
                // console.log(this.$route);  // 管理路由數據
                // console.log(this.$router);  // 管理路由跳轉
                this.$router.push(page);  // 路由的邏輯跳轉
            }
        },
        // 當前組件加載成功,要根據當前實際所在的路徑,判斷單選激活標籤
        created() {
            // console.log(this.$route.path);
            this.currentPage = this.$route.path;
        }
    }
</script>

<style scoped>
    .nav {
        width: 100%;
        height: 60px;
        background-color: orange;
    }
    .nav li {
        float: left;
        font: normal 20px/60px '微軟雅黑';
        padding: 0 30px;
    }
    .nav li:hover {
        cursor: pointer;
        background-color: aquamarine;
    }
    .nav li.active {
        cursor: pointer;
        background-color: aquamarine;
    }
</style>

vue 官方提供的組件生命週期圖

相關文章
相關標籤/搜索