Vue快速入門

望穿先生發表於2022-04-10

Vue入門

1.什麼是MVVM?

MVVM(Model-View-ViewModel)是一種軟體架構設計模式,是一種簡化使用者介面的事件驅動程式設計方式。它源自與經典的MVC模式,MVVM的核心是ViewModel層,負責轉換Model中的資料物件來讓資料變得更容易管理和使用

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-0kcy9wSJ-1649604741713)(C:\Users\28905\AppData\Roaming\Typora\typora-user-images\image-20220408130830448.png)]

為什麼要使用MVVM?

MVVM模式和MVC模式一樣,主要目的是分離檢視(View)和模型(Model)

  • 低耦合:檢視(View)可以獨立於Model變化和修改,一個ViewModel可以繫結到不同的View上,當View變化的時候Model可以不變,當Model變化的時候,View也可以不變。

  • 可複用:你可以把一些檢視邏輯放在一個ViewModel裡面,讓很多View重用這段檢視邏輯。

  • 獨立開發:開發人員可以專注於業務邏輯和資料的開發(ViewModel),設計人員可以專注於頁面設計。

  • 可測試:介面向來是比較難於測試的,而現在測試可以針對ViewModel來寫

2.第一個Vue專案

第一個Vue程式

1.匯入Vue.js

CDN匯入

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

2.new 一個vue物件

3.繫結一個元素

4.放資料

5.從模板裡取出來

<!--View層 模板-->
<div id="app">
    {{message}}
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
    var vm = new Vue({
       el:"#app",
        //Model:資料
       data:{
           message:"hello,vue!"
       }
    });
</script>

3.Vue基本語法

v-bind

使用v-bind來繫結元素特性!

v-開頭的被稱為指令

v-bind這個指令的意思是“將這個元素節點的title特性和Vue例項的message屬性保持一致

<!--View層 模板-->
<div id="app">
    <span v-bind:title="message">滑鼠懸停在此處,可以檢視動態繫結的資訊</span>
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
    var vm = new Vue({
       el:"#app",
        //Model:資料
       data:{
           message:"hello,vue!"
       }
    });
</script>

v-if、v-else

<!--View層 模板-->
<div id="app">
   <h1 v-if ok==="lyl">我是true</h1>
   <h1 v-else>我是flase</h1>
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
    var vm = new Vue({
        el:"#app",
        //Model:資料
        data:{
            ok: "lyl"
        }
    });
</script>

v-for

<!--View層 模板-->
<div id="app">
  <li v-for="item in items">
    {{item.message}}
  </li>

</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  var vm = new Vue({
    el:"#app",
    //Model:資料
    data:{
      items:[
        {message: "我是itme1"},
        {message: "我是itme2"}
      ]
    }
  });
</script>

methods

<div id="app">
<button v-on:click="say">click me</button>

</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  var vm = new Vue({
    el:"#app",
    //Model:資料
    data:{
        message: "我是Vue"
    },
    methods:{//方法必須定義在Vue的method物件中
      say:function (event){
        alert(this.message);
      }
    }
  });
</script>

4.Vue的雙向繫結

什麼是雙向資料繫結?

Vue.js是一個MVVM框架,即資料雙向繫結,即當資料發生變化的時候,檢視也就發生變化,當檢視發生變化的時候,資料也會跟著同步變化,這也是Vue的精髓之處。

注意,我們所說的資料雙向繫結,一定是對於Ui控制元件來說的,非UI控制元件不會涉及到資料的雙向繫結,單項資料繫結是使用狀態管理工具的前提,如果我們使用vuex,那麼資料流也是單項的,這時就會和雙向資料繫結有衝突。

為什麼要實現資料的雙向繫結?

在vue.js 中,如果使用vuex,實際上資料還是單向的,之所以說是資料雙向繫結,這是用的UI控制元件來說,對於我們處理表單,Vue.js
的雙向資料繫結用起來就特別舒服了。即兩者並不互斥,在全域性性資料流使用單項,方便跟蹤;區域性性資料流使用雙向,簡單易操作。

在表單中使用雙向資料繫結?

你可以用v-model 指令在表單<input> ,
<textarea><select>元素上建立雙向資料繫結。它會根據控制元件型別自動選取正確的方法來更新元素。儘管有些神奇,但v-model本質上不過是語法糖。它負責監聽使用者的輸入事件以更新資料,並對一些極端場景進行一些特殊處理。
注意: v-model 會忽略所有表單元素的.value、checked、selected
特性的初始值而總是將Vue例項的資料作為資料來源。你應該通過JavaScript在元件的data選項中宣告初始值!

通過v-model實現資料繫結

<div id="app">
  請輸入文字:<input type="text" v-model="message">{{message}}
  
      <!--也可以使用selected實現預設選值-->
    <select name="" id="" v-model="selected">
        <option disabled value="">--請選擇--</option>
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
    </select>
    {{selected}}
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  var vm = new Vue({
    el:"#app",
    //Model:資料
    data:{
      message: "我是Vue"
      selected: "C"      //預設下拉選單選中為C
    },
    methods:{//方法必須定義在Vue的method物件中
    }
  });
</script>

v-bind和v-model區分

(1)v-bind是單項資料繫結,對映關係是Model->View,我們通過Model操作就可以實現檢視的聯動更新。

  • 格式:v-bind:(props)="(message)"

  • props就是元件component的元素

  • message就是vm中Data物件的資料

  • 繫結一個屬性<img v-bind:src="imagesrc"/>

(2)v-model是雙向資料繫結,對映關係是 View接受的資料,傳給model,model的資料再傳給view ,用於表單控制元件

5.Vue元件

通過component定義一個元件,component有兩個元素:props(引數)、template(模板)

元件lyl中的v-bind繫結了props屬性中的引數

<div id="app">
<lyl v-for="item in items" v-bind:zujian="item"></lyl>
</div>


<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  //定義一個Vue元件component
  Vue.component("lyl",{
    props: ['zujian'],
    template:'<li>{{zujian}}</li>'
  })

  var vm = new Vue({
    el:"#app",
    //Model:資料
    data:{
      items: ["西瓜","蘋果","橘子"]
    }
  });
</script>

6.Axios非同步通訊

什麼是Axios?

Axios是一個開源的可以用在瀏覽器端和node.js的非同步通訊框架,它的主要作用就是實現 AJAX非同步通訊,其功能特點如下:

  • 從瀏覽器中建立XMLHttpRequests

  • 從node.js 建立http請求

  • 支援Promise API[ JS中鏈式程式設計 ]攔截請求和響應

  • 轉換請求資料和響應資料取消請求

  • 自動轉換JSON資料

  • 客戶端支援防禦XSRF(跨站請求偽造)

為什麼要使用Axios?

由於Vue.js是一個檢視層框架並且作者(尤雨溪)嚴格準守SoC (關注度分離原則),所以Vue.js並不包含AJAX的通訊功能,為了解決通訊問題,作者單獨開發了一個名為 vue-resource的外掛,不過在進入2.0版本以後停止了對該外掛的維護並推薦了Axios框架。少用jQuery,因為它操作Dom太頻繁!

Axios的CDN引入:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Vue例項有一個完整的生命週期,也就是從開始建立、初始化資料、編譯模板、掛載DOM、渲染→更新→渲染、解除安裝等一系列過程,我們稱這是Vue的生命週期。通俗說就是Vue
例項從建立到銷燬的過程,就是生命週期。

在這裡插入圖片描述

例項測試:

<div id="app">
  <div>{{info.address.country}}</div>
  <div>{{info.name}}</div>
  <a v-bind:href="info.url">跳轉</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
  var vm = new Vue({
    el:"#app",
    //data:是vm的屬性,此處用的是data()
    data(){
      return{
        //請求返回的引數格式,必須和json字串一樣
        info: {
          name: null,
          address: {
            street: null,
            city: null,
            country: null
          },
          url:null
        }
      }
    },
    mounted(){//鉤子函式,鏈式程式設計,Es6新特性
      axios.get('../data.json').then(response=>(this.info=response.data))
    },
  });
</script>

7.計算屬性

計算出來的結果,儲存在屬性中(簡單來說,就是能夠將計算結果快取起來的屬性)

記憶體中執行:虛擬DOM

<div id="app">
  <div>time:{{time()}}</div>
  <div>time1:{{time1}}</div>
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  var vm = new Vue({
    el:"#app",
    //Model:資料
    data:{
      message:"你好"
    },
    methods:{
      time:function (){
        return Date.now();  //返回一個時間戳
      }
    },
    computed:{//計算屬性
      time1:function (){
        this.message;
        return Date.now();
      }
    }
  });
</script>
  • methods:定義方法,呼叫方法使用time(),需要帶括號
  • computed:定義計算屬性,呼叫屬性使用time1,不需要帶括號; this.message 是為了能夠讓time1觀察到資料變化而變化
  • 如何在方法中的值發生了變化,則快取就會重新整理! 可以在控制檯使用vm.message="lyl" ,改變下資料的值,再次測試觀察效果!

8.插槽slot

在vue.js中我們使用<slot>元素作為承載分發內容的出口,作者稱其為插槽,可以應用在組合元件的場景中;

通過插槽<slot>的name屬性進行值的繫結

<div id="app">
<todo>
  <todo-title slot="todo-title" v-bind:title="title"></todo-title>
  <todo-item slot="todo-item" v-for="item in items" v-bind:item="item"></todo-item>
</todo>
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  //slot插槽
  Vue.component("todo",{         
    //通過slot中的name屬性繫結標籤中的slot
    template: `<div>`+
                    `<slot name="todo-title"></slot>`+
                      `<ul>\
                           <slot name="todo-item"></slot>
                       </ul>`+
                `</div>`
  });
  
  //一個title元件,props中的引數要加引號
  Vue.component("todo-title",{
    props: ['title'],
    template: '<div>{{title}}</div>'
  });
  
  //一個item元件
  Vue.component("todo-item",{
    props: ['item'],
    template: '<li>{{item}}</li>'
  })
  var vm = new Vue({
    el:"#app",
    data:{
      title: "title:lyl測試",
      items:['java','python','C']
    },
  });
</script>

9.自定義事件內容分發

補充:

(1)v-for可以遍歷出陣列的下標

v-for="(item,index) in items"

(2)元件中也可以有methods:物件

(3)通過this.$emit()自定義事件內容分發

(4)v-on等價於@click

<div id="app">
  <todo>
    <todo-title slot="todo-title" v-bind:title="title"></todo-title>
    <todo-item slot="todo-item"
               v-for="(item,index) in items"
               v-bind:item="item"
               v-bind:index="index"
               v-on:remove_self="removeitems(index)">
    </todo-item>
  </todo>
</div>

<!--匯入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

<script>
  //slot插槽
  Vue.component("todo",{
    //通過slot中的name屬性繫結標籤中的slot
    template: `<div>`+
            `<slot name="todo-title"></slot>`+
            `<ul>\
                           <slot name="todo-item"></slot>
                       </ul>`+
            `</div>`
  });

  //一個title元件,props中的引數要加引號
  Vue.component("todo-title",{
    props: ['title'],
    template: '<div>{{title}}</div>'
  });

  //一個item元件
  Vue.component("todo-item",{
    props: ['item','index'],
    //元件只可以繫結元件內部自己的methods的方法,不能繫結vue物件的方法
    template: '<li>索引:{{index}}---》{{item}} <button v-on:click="remove">刪除</button></li>',
    methods: {
      remove:function (index){
        //通過this.$emit 自定義事件分發,呼叫vue物件中的removeitems
        this.$emit('remove_self',index)
      }
    }
  })
  var vm = new Vue({
    el:"#app",
    data:{
      title: "title:lyl測試",
      items:['java','python','C']
    },
    methods: {
      removeitems:function (index){
        console.log("刪除了"+this.items[index]+"成功")
        this.items.splice(index,1) //通過js的splice方法,從index開始,一次刪除一個元素
      }
    }
  });
</script>

自定義事件分發小結:

(前端作為轉接媒介)

(1)在實現插槽的元件中可以呼叫自身的methods方法,但是無法呼叫Vue物件的methods方法

(2)通過在元件的方法中,this.$emit('remove_self',index)實現事件轉發

(3)在元件的標籤中,通過事件轉發的方法 v-on:remove_self="removeitems(index)"繫結到Vue物件中的methods方法

第一個Vue-cli專案

1.什麼是vue-cli?

vue-cli官方提供的一個腳手架,用於快速生成一個vue的專案模板;

預先定義好的目錄結構及基礎程式碼,就好比我們們在建立Maven專案時可以選擇建立一個骨架專案,這個骨架專案就是腳手架,我們的開發更加的快速;

主要的功能:

  • 統一的目錄結構
  • 本地除錯
  • 熱部署
  • 單元測試
  • 整合打包上線

2.環境配置

  • Node.js

下載地址: http://nodejs.cn/download/ 安裝的時候一直下一步直到結束

確認是否安裝成功:

  • 在cmd中執行node -v命令,檢視是否能夠輸出版本號
  • 在cmd中執行npm -v命令,檢視是否能夠輸出版本號

在這裡插入圖片描述

  • 安裝node.js淘寶映象加速器(cnpm)
# -g 就是全域性安裝
npm install cnpm -g

# 或使用如下語句解決npm速度慢的問題,但是每次install都需要(媽發)
npm install --registry=https://registry.npm.taobao.org
  • 安裝vue-cli
cnpm instal1 vue-cli-g
#測試是否安裝成功#檢視可以基於哪些模板建立vue應用程式,通常我們選擇webpack
vue list

在這裡插入圖片描述

2.2 第一個vue-cli應用程式

  • 找到一個專案路徑(空資料夾)
  • 建立一個基於webpack模板的vue應用程式
#1、首先需要進入到對應的目錄 cd E:\study\Java\workspace\workspace_vue
#2、這裡的myvue是頂日名稱,可以根據自己的需求起名
vue init webpack myvue
  • 建立過程需要的操作

    一路選no
    在這裡插入圖片描述

Project name:專案名稱,預設回車即可
Project description:專案描述,預設回車即可
Author:專案作者,預設回車即可
Install vue-router:是否安裝vue-router,選擇n不安裝(後期需要再手動新增)
Use ESLint to lint your code:是否使用ESLint做程式碼檢查,選擇n不安裝(後期需要再手動新增)
Set up unit tests:單元測試相關,選擇n不安裝(後期需要再手動新增)
Setupe2etests with Nightwatch:單元測試相關,選擇n不安裝(後期需要再手動新增)
Should we run npm install for you after the,project has been created:建立完成後直接初始化,選擇n,我們手動執行;執行結果

當出現問題時,它會給出提示我們按照提示來就行
在這裡插入圖片描述

  • 初始化並執行
cd myvue
npm install
npm run dev

在這裡插入圖片描述

訪問localhost:8080即可

Webpack

什麼是webpack?

本質上,webpack是一個現代JavaScript應用程式的靜態模組打包器(module
bundler)。當webpack處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency
graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個bundle.
Webpack是當下最熱門的前端資源模組化管理和打包工具,它可以將許多鬆散耦合的模組按照依賴和規則打包成符合生產環境部署的前端資源。還可以將按需載入的模組進行程式碼分離,等到實際需要時再非同步載入。通過loader轉換,任何形式的資源都可以當做模組,比如CommonsJS.AMD、ES6、css、JSON、CoffeeScript、LESS等;

安裝Webpack

WebPack是一款模組載入器兼打包工具, 它能把各種資源, 如JS、JSX、ES 6、SASS、LESS、圖片等都作為模組來處理和使用

安裝

npm install webpack -g
npm install webpack-cli -g

測試安裝成功:

webpack -v
webpack-cli -v

配置:

建立webpack .config.js配置檔案

entry: 入口檔案,指定WebPack 用哪個檔案作為專案的入口

output:輸出,指定WebPack把處理完成的檔案放置到指定路徑

module:模組,用於處理各種型別的檔案

plugins:外掛,如:熱更新、程式碼重用等r

resolve:設定路徑指向

watch:監聽,用於設定檔案改動後直接打包

  • 建立專案

在自己的目錄中,新建資料夾webpack-study,然後用IDEA開啟

  • 建立一個名為modules的目錄,用於放置JS模組等資原始檔
  • 在modules下建立模組檔案hello.js
//暴露一個方法:sayHi
exports.sayHi = function(){
    document.write("<div>Hello Webpack</div>");
}
  • 在modules下建立一個名為main.js的入口檔案main.js,用於打包時設定entry屬性
//require 匯入一個模組,就可以呼叫這個模組中的方法了
var hello = require("./hello");
hello.sayHi();
  • 在專案目錄下建立webpack.config.js配置檔案,
module.exports = {
    entry:"./modules/main.js",
    output:{
        filename:"./js/bundle.js"
    }
}
  • 使用webpack命令打包(命令列狀態下),打包成功後會生成一個dist資料夾

打包:

說明:打包如果失敗,就用管理員許可權執行webpack

  • 在專案目錄下建立HTML頁面,index.html,通過script匯入webpack打包後的JS檔案
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="./dist/js/bundel.js"></script>
</body>
</html>

補充:

webpack -watch

引數--watch 用於監聽變化,如果要打包的東西有變化,就重新打包

Vue-router路由

Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度整合,讓構建單頁面應用變得易如反掌。包含的功能有:

  • 巢狀的路由/檢視表

  • 模組化的、基於元件的路由配置路由引數、查詢、萬用字元

  • 基於Vue.js 過渡系統的檢視過渡效果

  • 細粒度的導航控制

  • 帶有自動啟用的Css classt的連結

  • HTML5歷史模式或hash模式,在IE9中自動降級

  • 自定義的滾動條行為

安裝

  • 基於第一個vue-cli進行測試學習; 先檢視node modules中是否存在vue-router, vue-router是一個外掛包, 所以我們還是需要用npm/cnpm來進行安裝的
npm install vue-router --save-dev
  • 如果在一個模組化工程中使用它,必須要通過Vue.use()明確地安裝路由功能
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

問題解決:

npm run dev時候提示好多警告,Router is not found in vue-router,並且無法載入出頁面

原因:vue-router的版本太高

解決方案:更換低版本的vue-router

cnpm install vue-router@3.1.3 --save-dev

測試路由

  • 在src目錄下新建cpmponents資料夾用於存放我們自己編寫的元件
  • 定義自己的元件Content.vue、Main.vue

Content.vue

<template>
<h1>內容頁</h1>
</template>

<script>
export default {
  name: "Content"
}
</script>

<style scoped>

</style>

Main.vue

<template>
<h1>首頁</h1>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped>

</style>
  • 新建router資料夾,用於存放路由,在資料夾下編寫index.js,用於配置路由

index.js

import Vue from 'vue'
//匯入路由外掛
import Router from "vue-router";
//匯入自定義的元件
import Content from "../components/Content";
import Main from "../components/Main";
//安裝路由
Vue.use(Router);
//配置匯出路由
export default new Router({
  routes:[
    {
      //路由路徑
      path:'/content',
      name:'content',
      //跳轉的元件
      component:Content
    },
    {
      path:'/main',
      name:'main',
      component: Main
    }
  ]
});
  • 在main.js中配置路由(import路由的時候路徑寫到資料夾即可,因為寫的是index.js會被預設掃描)

main.js

import Vue from 'vue'
import App from './App'
import router from './router'  //自動掃描裡面的路由配置
Vue.config.productionTip = false;

//顯示宣告引用VueRouter
new Vue({
  el: '#app',
  //配置路由
  router,
  components: { App },
  template: '<App/>'
})
  • app.vue中使用路由
<template>
  <div id="app">
    <!--
      router-link:預設會被渲染成一個<a>標籤,to屬性為指定連結
      router-view:用於渲染路由匹配到的元件
    -->
    <router-link to="/main">首頁</router-link>
    <router-link to="/content">內容頁</router-link>
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: 'App',
}
</script>
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
  • 通過命令npm run dev執行,通過瀏覽器進行訪問

Vue+Element小例子

1.建立工程

  • 建立一個名為hello-vue的工程vue init webpack hello-vue
  • 安裝依賴,我們需要安裝vue-router、element-ui、sass-loader、node-sass四個外掛
#進入工程目錄
cd hello-vue
#安裝vue-routern 
npm install vue-router --save-dev
#安裝element-ui
npm i element-ui -S
#安裝依賴
npm install
# 安裝SASS載入器
cnpm install sass-loader node-sass --save-dev
#啟功測試
npm run dev

npm命令說明

  • npm install moduleName:安裝模組到專案目錄下

  • npm install -g moduleName:-g的意思是將模組安裝到全域性,具體安裝到磁碟哪個位置要看npm

    config prefix的位置

  • npm install -save moduleName:–save的意思是將模組安裝到專案目錄下, 並在package檔案的dependencies節點寫入依賴,-S為該命令的縮寫

  • npm install -save-dev moduleName:–save-dev的意思是將模組安裝到專案目錄下,並在package檔案的devDependencies節點寫入依賴,-D為該命令的縮寫

問題解決:

在最後npm run dev的時候,出現sass版本問題

解決方案:將package.json檔案中的"sass-loader": "^7.3.1"版本改成7.3.1

重新執行以下命令:

npm uninstall node-sass
npm i -D sass
  • 用IDEA開啟新建的專案,在src下新建routers、views資料夾

  • 說明:

    • assets:用於存放資原始檔
    • components:用於存放Vue功能元件
    • views:用於存放Vue檢視元件
    • router:用於存放vue-router配置
  • 在views資料夾下新建Login.vue和Main.vue元件

Login.vue

<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">歡迎登入</h3>
      <el-form-item label="賬號" prop="username">
        <el-input type="text" placeholder="請輸入賬號" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密碼" prop="password">
        <el-input type="password" placeholder="請輸入密碼" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登入</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="溫馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>請輸入賬號和密碼</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">確 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: "Login",
  data() {
    return {
      form: {
        username: '',
        password: ''
      },
      //表單驗證,需要在el-form-item 元素中增加prop 屬性
      rules: {
        username: [
          {required: true, message: " 賬號不可為空", trigger: 'blur'}
        ],
        password: [
          {required: true, message: " 密碼不可為空 ", trigger: 'blur'}
        ]
      },
//對話方塊顯示和隱藏
      dialogVisible: false
    }
  },
  methods: {
    onSubmit(formName) {
//為表單繫結驗證功能
      this.$refs [formName].validate((valid) => {
        if (valid) {
//使用vue-router路由到指定頁面,該方式稱之為程式設計式導航
          this.$router.push("/main");
        } else {
          this.dialogVisible = true;
          return false;
        }
      });
    }
  }
}
</script>
<style lang="scss" scoped>
.login-box {
  border: 1px solid #DCDFE6;
  width: 350px;
  margin: 180px auto;
  padding: 35px 35px 15px 35px;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  box-shadow: 0 0 25px #909399;
}

.login-title {
  text-align: center;
  margin: 0 auto 40px auto;
  color: #303133;
}
</style>

Main.vue

<template>
<h1>主頁</h1>
</template>

<script>
export default {
  name: "Main"
}
</script>

<style scoped>

</style>
  • 在routers資料夾下新建index.js檔案

index.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from "../views/Login";
import Main from "../views/Main";



Vue.use(Router);

export default new Router({
  routes: [
    {
      path : '/main',
      name : 'main',
      component: Main
    },
    {
      path: '/login',
      name: 'login',
      component:Login
    }
  ]
});
  • 在main.js中配置路由
import Vue from 'vue'
import App from './App'
import router from './routers'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false

Vue.use(router)
Vue.use(ElementUI)
new Vue({
  el: '#app',
  router,
  render: h => h(App) //ElementUI

})

2.路由巢狀

  • 新建views下的子元件,user/List.vue、和/user/Profile.vue

List.vue

<template>
<h1>使用者列表</h1>
</template>

<script>
export default {
  name: "List"
}
</script>

<style scoped>

</style>

Profile.vue

<template>
<h1>個人資訊</h1>
</template>

<script>
export default {
  name: "Profile"
}
</script>

<style scoped>

</style>

通過在路由配置元件中配置子元素children屬性,實現巢狀

index.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from "../views/Login";
import Main from "../views/Main";
import Profile from "../views/user/Profile";
import List from "../views/user/List";

Vue.use(Router);

export default new Router({
  routes: [
    {
      path : '/main',
      name : 'main',
      component: Main,
      children:[         //子元素巢狀
        {
          path : '/user/list',
          name : 'list',
          component: List
        },
        {
          path : '/user/profile',
          name : 'profile',
          component: Profile
        }
      ]
    },
    {
      path: '/login',
      name: 'login',
      component:Login
    }
  ]
});

更新Main.vue中的內容為側邊欄樣式內容

Main.vue

<template>
  <div>
    <el-container>
      <el-aside width="200px">
        <el-menu :default-openeds="['1']">
          <el-submenu index="1">
            <template slot="title"><i class="el-icon-caret-right"></i>使用者管理</template>
            <el-menu-item-group>
              <el-menu-item index="1-1">
                <!--插入的地方-->
                <router-link to="/user/profile">個人資訊</router-link>
              </el-menu-item>
              <el-menu-item index="1-2">
                <!--插入的地方-->
                <router-link to="/user/list">使用者列表</router-link>
              </el-menu-item>
            </el-menu-item-group>
          </el-submenu>
          <el-submenu index="2">
            <template slot="title"><i class="el-icon-caret-right"></i>內容管理</template>
            <el-menu-item-group>
              <el-menu-item index="2-1">分類管理</el-menu-item>
              <el-menu-item index="2-2">內容列表</el-menu-item>
            </el-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>

      <el-container>
        <el-header style="text-align: right; font-size: 12px">
          <el-dropdown>
            <i class="el-icon-setting" style="margin-right: 15px"></i>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>個人資訊</el-dropdown-item>
              <el-dropdown-item>退出登入</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </el-header>
        <el-main>
          <!--在這裡展示檢視-->
          <router-view />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
export default {
  name: "Main"
}
</script>
<style scoped lang="scss">
.el-header {
  background-color: #B3C0D1;
  color: #333;
  line-height: 60px;
}
.el-aside {
  color: #333;
}
</style>

3.引數傳遞及重定向

引數傳遞方法1:

前端通過params傳遞,中間通過router接收,通過$router.params.id展示

(1)前端通過to屬性傳遞引數(注意:要對to屬性進行雙向繫結)

name傳元件名,params傳遞引數,需要物件:v-bind

<router-link v-bind:to="{name: 'profile',params:{id:1}}">個人資訊</router-link>

(2)通過路由(index.js)接收

routes: [
    {
      path : '/main',
      name : 'main',
      component: Main,
      children:[
        {
          path : '/user/list',
          name : 'list',
          component: List
        },
        {
          path : '/user/profile:id',       //通過id接收(如果使用name傳參
                                           //此處的:id可以不寫,但是在位址列中沒辦法改變id 的值)
          name : 'profile',
          component: Profile
        }
      ]
    },
    {
      path: '/login',
      name: 'login',
      component:Login
    }
  ]

(3)在Profile.vue中顯示傳遞的引數

注意:所有的元素不能直接在根節點下,必須至少有一個div標籤包裹,否則出錯

<template>
  <div>
    <h1>個人資訊</h1>
    {{$route.params.id}}
  </div>
</template>

引數傳遞方法2:

使用props減少耦合

(1)前端通過to屬性傳遞引數(注意:要對to屬性進行v-bind繫結)

name傳元件名,params傳遞引數,需要物件:v-bind

<router-link :to="{name: 'profile',params:{id:1,name:'望穿先生',age:'22'}}">個人資訊</router-link>

(2)通過路由(index.js)接收

在需要接收引數的路由後,新增屬性props:true

indes.js

routes: [
    {
      path : '/main',
      name : 'main',
      component: Main,
      children:[
        {
          path : '/user/list',
          name : 'list',
          component: List
        },
        {
          path : '/user/profile',      
          name : 'profile',
          component: Profile,
          props: true
        }
      ]
    },
    {
      path: '/login',
      name: 'login',
      component:Login
    }
  ]

(3)在Profile.vue中顯示傳遞的引數

需要的Profile.vue接收引數並且在export中增加props屬性

注意:所有的元素不能直接在根節點下,必須至少有一個div標籤包裹,否則出錯

Profile.vue

<template>

  <div>
    <h1>個人資訊</h1>
    <ul>
      <li>id:{{id}}</li>
      <li>姓名:{{name}}</li>
      <li>年齡:{{age}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  props:['id','name','age'],
  name: "Profile"
}
</script>

重定向

Vue 中的重定向是作用在路徑不同但元件相同的情況

  • 在router/index.js配置重定向路徑

index.js

routes: [
  {
    path : '/main',
    name : 'main',
    component: Main,
    children:[
      {
        path : '/user/list',
        name : 'list',
        component: List
      },
      {
        path : '/user/profile:id',
        name : 'profile',
        component: Profile,
        props : true
      }
    ]
  },
  {
    path: '/login',
    name: 'login',
    component:Login
  },
  {
    path: '/gohome',
    redirect : '/main'
  }
]

在前臺加入連結

<router-link to="/gohome">返回首頁</router-link>

路由模式與404

路由模式有兩種

修改路由配置

index.js

export default new Router({
  mode:'history',
  routes: []
  )}

在路由的配置中修改

路由鉤子

除了之前的鉤子函式還存在兩個鉤子函式

beforeRouteEnter:在進入路由前執行
beforeRouteLeave:在離開路由前執行

  • 在 Profile.vue 使用
<script>
    export default {
        name: "UserProfile",
        beforeRouteEnter: (to, from, next) => {
            console.log("準備進入個人資訊頁");
            next();
        },
        beforeRouteLeave: (to, from, next) => {
            console.log("準備離開個人資訊頁");
            next();
        }
    }
</script>

引數說明:

to:路由將要跳轉的路徑資訊

from:路徑跳轉前的路徑資訊
next:路由的控制引數
next() 跳入下一個頁面
next(’/path’) 改變路由的跳轉方向,使其跳到另一個路由
next(false) 返回原來的頁面
next((vm)=>{}) 僅在 beforeRouteEnter 中可用,vm 是元件例項

在鉤子函式中進行非同步請求

  • 安裝Axios
cnpm install --save vue-axios
  • main.js引用 Axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
  • 準備資料

data.json

{
  "name": "望穿先生",
  "url": "http://baidu.com",
  "page": "1",
  "isNonProfit": "true",
  "address": {
    "street": "含光門",
    "city": "陝西西安",
    "country": "中國"
  },
  "links": [
    {
      "name": "B站",
      "url": "https://www.bilibili.com/"
    },
    {
      "name": "4399",
      "url": "https://www.4399.com/"
    },
    {
      "name": "百度",
      "url": "https://www.baidu.com/"
    }
  ]
}

說明: 只有我們的 static 目錄下的檔案是可以被訪問到的,所以我們就把靜態檔案放入該目錄下

  • 在 beforeRouteEnter 中進行非同步請求
<script>
    export default {
        name: "UserProfile",
        beforeRouteEnter: (to, from, next) => {
            console.log("準備進入個人資訊頁");
            next(vm => {
                //進入路由之前執行getData方法
                vm.getData()
            });
        },
        beforeRouteLeave: (to, from, next) => {
            console.log("準備離開個人資訊頁");
            next();
        },
        //axios
        methods: {
            getData: function () {
                this.axios({
                    method: 'get',
                    url: 'http://localhost:8080/static/mock/data.json'
                }).then(function (response) {
                    console.log(response)
                })
            }
        }
    }
</script>
  • 測試

相關文章