Vue生命周期&腳手架工程&Element-UI

一 Vue2.x生命周期

每個vue實例再被創(chuàng)建時都要經過一系列的初始化過程:
創(chuàng)建實例
裝載模板
渲染模板等等
vue為生命周期中的每個狀態(tài)都設置了鉤子函數(shù)(監(jiān)聽函數(shù))。每個vue實例處于不同的生命周期時,對應的函數(shù)就會觸發(fā)調用
https://www.cnblogs.com/L-xmin/p/13031773.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

<div id="app">
    <span id="num">{{num}}</span>
    <button @click="num++">點贊</button><br>
    {{name}},有{{num}}個點贊!
</div>

</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        let vm=new Vue({
            el:"#app",
            data:{
                name:"張三",
                num:1
            },
            methods:{
                show(){
                    return this.name
                }
            },
            // 第一個生命周期函數(shù),組件的data,methods,DOM結構都還沒有初始化
            beforeCreate() {
                console.log("=========beforeCreate=============");
                console.log("數(shù)據(jù)模型未加載: "+this.name,this.num); //undefined
                console.log("方法未加載: "+this.show());
                console.log("html模板未渲染: "+document.getElementById("num").innerText);
            },
            // 第二個生命周期函數(shù),組件的data,methods已經可以訪問到,但html模板尚未渲染,該函數(shù)中我們通常發(fā)送ajax請求
            created(){
                console.log("=========created=============");
                console.log("數(shù)據(jù)模型已加載: "+this.name,this.num); //undefined
                console.log("方法已加載: "+this.show());
                console.log("html模板已加載:" + document.getElementById("num"));
                console.log("html模板未渲染: "+document.getElementById("num").innerText);
            },
            // 第三個生命周期函數(shù),模板結構已經在內存中編譯完成,但還沒有渲染到頁面上,仍然無法獲得模板中的內容,頁面看到的還是一個插值表達式
            beforeMount() {
                console.log("=========beforeMount=============");
                console.log("html模板未渲染: "+document.getElementById("num").innerText);
            },
            // 組件創(chuàng)建階段的最后一個生命周期函數(shù),頁面真正被渲染了,用戶能看到真實頁面數(shù)據(jù)
            mounted() {
                console.log("=========mounted=============");
                console.log("html模板已渲染: "+document.getElementById("num").innerText);
            },

            //更新部分的生命周期
            beforeUpdate() {
                console.log("=========beforeUpdate=============");
                console.log("數(shù)據(jù)模型已更新:"+this.num);
                console.log("html模板未更新:"+document.getElementById("num").innerText);
            },
            updated() {
                console.log("=========updated=============");
                console.log("數(shù)據(jù)模型已更新:"+this.num);
                console.log("html模板已更新:"+document.getElementById("num").innerText);
            },

        })
    </script>    
</body>
</html>

創(chuàng)建部分的生命周期

beforeCreate

此時,組件的data和methods以及頁面DOM結構都還沒有初始化

created

此時,組件的data和methods可用。但頁面還沒被渲染出來,在該函數(shù)中,我們經常會發(fā)起ajax請求

beforeMount

此時,模板結構已經在內存中編譯完成,但還沒有真正渲染到頁面上。頁面上看不到真實的數(shù)據(jù),能看到的只是一個模板而已,仍然無法獲得模板中的內容,仍然是一個插值表達式

mounted

組件創(chuàng)建階段的最后一個生命周期。此時,頁面已經真正渲染好了,用戶可以看到真實頁面數(shù)據(jù)。


以上執(zhí)行完,組件就離開了創(chuàng)建階段,進入運行階段。如果用到了一些第三方UI插件,必須在mounted中來初始化插件。

運行中的生命周期函數(shù),會根據(jù)data數(shù)據(jù)的變化有選擇性的觸發(fā)0次或n次

更新部分的生命周期

以后當每點一次贊,num就會變化,就會觸發(fā)下面的兩個鉤子函數(shù)

beforeUpdate

此時數(shù)據(jù)是最新的,但頁面上呈現(xiàn)的數(shù)據(jù)還是舊的

updated

頁面已經完成了更新,此時data數(shù)據(jù)是最新的,同時頁面上呈現(xiàn)的數(shù)據(jù)也是最新的

beforeDestroy

執(zhí)行該函數(shù)的時候,組件即將被銷毀但還沒有真正銷毀,此時組件(data、methods等數(shù)據(jù)或方法)還可以正常用。

destroyed

組件完成銷毀,組件廢了

二 使用Vue腳手架進行模塊化開發(fā)

我們實際在使用vue開發(fā)項目的時候,大多使用其模塊化的開發(fā)環(huán)境。我們去做一個后臺管理系統(tǒng),也是通過其模塊化的開發(fā)環(huán)境搭建了一個單頁應用,我們會發(fā)現(xiàn)項目中實際上只有一個html頁面(index.html),其他所有的功能都是通過編寫vue相關的組件(.vue結尾的文件),來完成最后的功能

2.1 搭建模塊化環(huán)境測試

  1. 全局安裝webpack,webpack是一個項目打包工具。-g是指全局安裝
    npm install webpack -g
  2. 全局安裝vue腳手架
    npm install -g @vue/cli-init
  3. 初始化vue項目。vue腳手架使用webpack模塊初始化一個appname項目
    vue init webpack appname
    桌面創(chuàng)建項目文件夾名稱,如vue-demo,然后進入該文件夾,在文件路徑地址上輸入cmd,回車就可以在當前目錄中打開cmd窗口,在當前目錄執(zhí)行上面的命令
    初始化的時候有幾項配置
    項目名稱,項目描述,作者,vue構建版本(使用standalone),安裝vue-router,不適用eslint,不使用單元測試,不安裝e2e tests,選擇npm為包管理工具

如果出現(xiàn)vue不是內部或者外部命令等錯誤,使用cnpm或者配置npm路徑環(huán)境變量

npm config list

然后打開上面的地址,查看是否有vue.cmd

如果一直處于downloading template然后最后超時報錯如下:

是因為github被墻了,無法訪問,解決方法:https://www.cnblogs.com/liufqiang/p/13697531.html,按照要求更改后可以正常初始化

  1. 啟動vue項目

上一步構建完后,再cd進入下一層目錄(vue-demo目錄下還有一層vue-demo,需要進入第二層實際項目路徑),執(zhí)行如下的命令來運行腳手架工程
npm run dev
項目的package.json中有scripts,代表我們能運行的命令

2.2 vue腳手架工程目錄介紹

在 vscode中打開vue-demo項目,可以看到如下目錄

目錄/文件 作用 圖片
build 與打包工具webpack有關的代碼
config 主要是一些配置信息,如項目訪問端口號
node_modules 使用npm install 給項目安裝的所有依賴
src 這里是我們要開發(fā)的目錄,基本上要做的事情都在這個目錄里
static 靜態(tài)資源文件,如圖片,字體
index.html 首頁內容,只有一個id為app的div
package.json npm安裝的依賴包的信息,我們每安裝一個依賴,在package.json中都會有devDependencies依賴聲明,包括它在哪里下載,它的版本號是多少,都有

src里面包含了幾個目錄及文件:

  • assets: 放置一些圖片,如logo等
  • components: 目錄里面放了一個組件文件,可以不用
  • App.vue: 項目入口文件,我們也可以直接將組件寫這里,而不使用 components 目錄
  • main.js: 項目的核心文件

總結:一句話,開發(fā)期間關注src里面的代碼以及src里面編寫相應的功能

2.3 vue腳手架項目運行流程

  • index.html
    聲明簡單的id為 app 的div給 vue 掛載
  • src下的main.js主程序
    主程序中引入了 vue、App 和 router 模塊, 創(chuàng)建了一個 Vue實例,并把 App.vue 模板的內容掛載到 index.html 的 id 為 app 的 div 標簽下, 并綁定了一個路由配置
  • App.vue
    上面 main.js 把 App.vue 模板的內容,放置在了 index.html 的 div 標簽下面。查看 App.vue 的內容我們看到,這個頁面的內容由一個 logo 和一個待放置內容的 router-view,router-view 的內容將由 router 配置決定
  • router下的index.js
    查看 route 目錄下的 index.js,我們發(fā)現(xiàn)這里配置了一個路由, 在訪問路徑 / 的時候, 會把 HelloWorld 模板的內容放置到上面的 router-view中

如果我們自定義了一個Hello路由,那么我們訪問/hello的時候,會把Hello 模板的內容放置到上面的router-view中,即:如果不需要首頁a標簽跳轉,只是輸入地址訪問的話,直接改路由即可

關于APP.vue文件:可以發(fā)現(xiàn)內容分為3個部分,

  • template(模板,頁面要顯示成什么),
  • script(vue實例的methods,data等),
  • style(當前template的樣式)。這是一個標準的vue單文件組件
    https://cn.vuejs.org/v2/guide/single-file-components.html
    模塊化開發(fā)的時候,我們會寫大量的.vue的單模塊組件,格式就是上面的3個部分

    上面的router-view是路由視圖的意思,意思是當前頁面上面顯示的是圖片,下面顯示什么,要根據(jù)我們訪問路徑動態(tài)決定。默認是/*/(url哈希的訪問方式) ,所以這個是一個動態(tài)的視圖,* 后的/是默認要顯示的視圖

訪問/的定義在route目錄的index.js中,訪問/,會使用我們名稱為HelloWorld的組件,而Helloworld組件從哪來,我們從下圖可以看到也是從外面導入的

導入Helloworld的from后面有個@符號,@符號代表當前src整個目錄的根目錄,然后從src下面的components下找HelloWorld.vue

如果我們想自己編寫一個Hello.vue組件,來訪問,我們同樣在components目錄下編寫Hello.vue,編寫3要素,template,script,style

<template>
    <div>
        <h1>你好啊,hello,{{name}}</h1>
    </div>
</template>
<script>
// 導出vue實例,推薦data寫函數(shù)的方式,return 一個對象,對象有個name值
export default {
    data(){
        return {
            name:"周杰倫"
        }
    }
}
</script>
<style></style>

組件寫好以后,要想使用,而且是路徑/hello使用,那么接下來我們需要編寫路由,在main.js中,我們可以看到導入的路由都在router目錄下,因此我們在router目錄下的index.js中添加一個路由path指向訪問地址,name是訪問path的地址,要展示哪個組件,使用之前都得先導入

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hello from '@/components/Hello'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path:'/hello', 
      name:'Hello',
      component:Hello
    }
  ]
})

然后保存,我們訪問/hello路徑

然后我們再訪問/,會發(fā)現(xiàn)又變回了helloworld組件,而我們可以發(fā)現(xiàn)上面的圖片不變,原因就是因為訪問不同的組件只會改變路由視圖的部分,不會改變路由視圖上面的圖片

我們如果想點擊一個超鏈接就去我們的hello組件,那么需要在App.vue中修改如下

app.vue只有路由視圖可以變,上面的圖片是不會變的

三 使用Vue整合element-ui

element-ui是一個使用比較廣泛的vue組件庫,幫我們抽取了常用的如單選框,輸入框,按鈕之類的各種組件,可以簡化我們的開發(fā)

3.1 npm安裝與引入

  1. 安裝elementUI:i是install的簡寫 npm i element-ui
  2. 安裝完后,在我們vue-demo項目的package.json中的依賴列表會列出剛剛安裝的element-ui,可以看到是2.15.6版本

然后,我們在main.js主程序中將element-ui組件以及它的css樣式導入
因為我們引入了,所以我們可以直接導入,類似于java中pom文件添加完依賴,就可以直接import進去
最后我們需要讓vue使用我們的element-ui組件,添加一行代碼Vue.use

未來我們需要用到其他組件庫,也是在main.js中采用上述方法導入使用

3.2 使用element-ui組件

3.2.1 簡單引入

我們在我們之前編寫的Hello.vue組件中使用Elementui,添加一個單選框,單選框組件代碼復制下面鏈接的文檔 https://element.eleme.cn/#/zh-CN/component/installation

el-radio其實本質上就是elementUI抽取的組件,之前不是學過組件化么,等于以前我們要自己做很多設定,現(xiàn)在elementUI幫我們做好了

要使用 Radio 組件,只需要設置v-model綁定變量,選中意味著變量的值為相應 Radio label屬性的值,label可以是String、Number或Boolean。

如上文檔所示,我們修改Hello.vue組件內容,添加單選框,label就是單選框的value值,通過data中設置radio值來默認讓某個選中

// 0. 如果使用模塊化機制編程,導入 Vue 和 VueRouter,要調用 Vue.use(VueRouter)

// 1. 定義(路由)組件。
// 可以從其他文件 import 進來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定義路由
// 每個路由應該映射一個組件。 其中"component" 可以是
// 通過 Vue.extend() 創(chuàng)建的組件構造器,
// 或者,只是一個組件配置對象。
// 我們晚點再討論嵌套路由。
const routes = [
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
]

// 3. 創(chuàng)建 router 實例,然后傳 `routes` 配置
// 你還可以傳別的配置參數(shù), 不過先這么簡單著吧。
const router = new VueRouter({
    routes // (縮寫)相當于 routes: routes
})

// 4. 創(chuàng)建和掛載根實例。
// 記得要通過 router 配置參數(shù)注入路由,
// 從而讓整個應用都有路由功能
const app = new Vue({
    router
}).$mount('#app')

// 現(xiàn)在,應用已經啟動了!

3.2 簡單后臺管理界面

https://element.eleme.cn/#/zh-CN/component/container
在elementui官方文檔的基本組件中選擇container布局容器,elementui幫我們寫好了常見的幾個頁面布局,我們使用如下的布局,分左右上三部分

復制template部分代碼到App.vue里面,因為頁面一進來就是index.html頁面,是一個id為app的div,在main.js中配置了在這個div里面加載App.vue組件,相當于一進來就展示的是App.vue的template部分,因此我們將App.vue的template部分完全替換

然后將scripts部分的代碼和style部分的代碼復制并覆蓋之前的App.vue的script和style中的代碼

data就是v-bind:data的縮寫,也就是它綁定了一個自定義屬性data,這個data的值關聯(lián)export default {data}中的data,這個data函數(shù),返回了一個對象,對象中有個屬性tableData數(shù)組
然后每一列el-table-column使用prop指定取出數(shù)組中每一個對象的哪個元素的值作為顯示,label就是表頭顯示的字

當el-table元素中注入data對象數(shù)組后,在el-table-column中用prop屬性來對應對象中的鍵名即可填入數(shù)據(jù),用label屬性來定義表格的列名??梢允褂脀idth屬性來定義列寬

修改完后,再次訪問,發(fā)現(xiàn)效果如下:

我們下面去實現(xiàn)點擊左側的選項1,右邊顯示默認給的用戶列表,點擊選項2,右邊顯示hello組件的內容

通過修改el-main標簽,el-main就是右邊的內容區(qū),是需要根據(jù)路徑的不同顯示不同的內容,因此我們需要將它抽取出來。首先注釋掉表格部分內容,然后改為如下

然后將表格部分內容抽取為一個組件,叫做MyTable組件,MyTable.vue文件

后來我們要經常編寫vue組件,自己每次都寫template,script,style這3部分太麻煩了,可以快捷的讓vscode給我們生成這樣一個模板

很簡單:創(chuàng)建vue對應的代碼片段,可以幫我們快速的生成vue模板
vue.json
文件–首選項–用戶代碼片段–新建代碼片段–取名vue.json

// https://www.cnblogs.com/songjilong/p/12635448.html
{
    "Print to console": {
        "prefix": "vue",
        "body": [
            "<!-- $1 -->",
            "<template>",
            "<div class='$2'>$5</div>",
            "</template>",
            "",
            "<script>",
            "http://這里可以導入其他文件(比如:組件,工具js,第三方插件js,json文件,圖片文件等等)",
            "http://例如:import 《組件名稱》 from '《組件路徑》';",
            "",
            "export default {",
            "http://import引入的組件需要注入到對象中才能使用",
            "components: {},",
            "data() {",
            "http://這里存放數(shù)據(jù)",
            "return {",
            "",
            "};",
            "},",
            "http://監(jiān)聽屬性 類似于data概念",
            "computed: {},",
            "http://監(jiān)控data中的數(shù)據(jù)變化",
            "watch: {},",
            "http://方法集合",
            "methods: {",
            "",
            "},",
            "http://生命周期 - 創(chuàng)建完成(可以訪問當前this實例)",
            "created() {",
            "",
            "},",
            "http://生命周期 - 掛載完成(可以訪問DOM元素)",
            "mounted() {",
            "",
            "},",
            "beforeCreate() {}, //生命周期 - 創(chuàng)建之前",
            "beforeMount() {}, //生命周期 - 掛載之前",
            "beforeUpdate() {}, //生命周期 - 更新之前",
            "updated() {}, //生命周期 - 更新之后",
            "beforeDestroy() {}, //生命周期 - 銷毀之前",
            "destroyed() {}, //生命周期 - 銷毀完成",
            "activated() {}, //如果頁面有keep-alive緩存功能,這個函數(shù)會觸發(fā)",
            "}",
            "</script>",
            "<style scoped>",
       (這一行復制的時候需要刪掉)     "http://@import url($3); 引入公共css類",
            "$4",
            "</style>"
        ],
        "description": "生成vue模板"
    },
    "http-get請求": {
    "prefix": "httpget",
    "body": [
        "this.\\$http({",
        "url: this.\\$http.adornUrl(''),",
        "method: 'get',",
        "params: this.\\$http.adornParams({})",
        "}).then(({ data }) => {",
        "})"
    ],
    "description": "httpGET請求"
    },
    "http-post請求": {
    "prefix": "httppost",
    "body": [
        "this.\\$http({",
        "url: this.\\$http.adornUrl(''),",
        "method: 'post',",
        "data: this.\\$http.adornData(data, false)",
        "}).then(({ data }) => { });" 
    ],
    "description": "httpPOST請求"
    }
}

然后以后我們寫一個vue,就會快捷的幫我們提示生成全部的3部分內容

<template>
    <div>
        <el-table :data="tableData">
        <el-table-column prop="date" label="日期" width="140">
        </el-table-column>
        <el-table-column prop="name" label="姓名" width="120">
        </el-table-column>
        <el-table-column prop="address" label="地址">
        </el-table-column>
      </el-table>
    </div>
</template>

<script>
 export default {
    data() {
      const item = {
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀區(qū)金沙江路 1518 弄'
      };
      return {
        tableData: Array(20).fill(item)
      }
    }
  };
</script>

然后修改路由,通過點擊左側連接,右邊內容頁顯示具體內容。
左邊點擊選項1,發(fā)送table請求,點擊選項2,發(fā)送hello請求

修改router目錄下的index.js文件,增加路由:

import MyTable from '@/components/MyTable'
    {
      path: '/table',
      name: 'MyTable',
      component: MyTable
    }

然后修改導航一種分組一的選項1和選項2的index并且開發(fā)menu的屬性router為true

然后再次點擊左側導航1的分組一的選項1和選項2可以看到正確的跳轉了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容