Vue.js 第4章 組件與路由

組件

  • 什麼是組件:組件就是一些標籤結構的封裝,同時爲這些結構添加須要的業務邏輯,設置你想要的樣式html

    • 一個組件中通常能夠設置:結構,功能和樣式vue

  • 爲何要使用組件:vue-router

    • 使用方便數組

    • 複用服務器

組件的建立和使用
  • 組件的分類:app

    • 全局組件:在vm實例外經過Vue.component來建立的組件,在當前vm實例指定的app模板範圍內都能使用ide

    • 子組件:在組件內部經過components屬性來建立的組件函數

  • 在vue中如何建立組件佈局

    • 組件是可複用的 Vue 實例:這句話告訴咱們組件就是一個vue實例,那麼就意味着在以前建立vue實例中的配置成員在組件中彷佛都能寫,也就說明了如何配置Vue實例就如何配置組件實例ui

    • 經過Vue.component(名稱,{配置})來建立組件

    • 在頁面中經過組件名稱來使用,使用的時候就像使用標籤同樣

    • 重點說明:在vm實例外來建立

<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>Document</title>
  <script src="./js/vue.js"></script>
</head>

<body>
  <!-- 建立父組件模版 -->
  <template id="father">
    <div>
      <h2>我是爸爸</h2>
      <!-- 將子組件放在這裏 -->
      <son></son>

    </div>
  </template>

  <!-- 建立子組件模版 -->
  <template id="son">
    <h2>我是兒子</h2>
  </template>
  <div id='app'>
    <!-- 將父組件放在這裏 -->
    <father></father>
  </div>
  <script>
    // 建立一個父組件
    Vue.component('father', {
      template: '#father',
      data(){
        // 注意:這裏若是寫了data函數,內部就必須return一個對象(沒有數據就寫個空對象),不然服務器會爆炸!
        return {
        }
      },

      // 使用components建立子組件
      components: {
        // 子組件名稱
        son:{
          template: '#son',
          data(){
            return {}
          }
        }
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {}
    })  
  </script>
</body>

</html>
建立並使用組件

 

  • 在Vue中如何使用組件,重點關注使用的細節

  • 常見錯誤:

 

緣由

你的組件的確沒有定義

你定義了,可是定義的位置不對,如放在vm實例後定義就會出現這個錯誤

重點:在組件中如何添加更多 配置

到底能夠添加那些配置

  以前vm實例能夠添加的配置這邊基本上都能添加,除了el

  el在以前的做用是指定模板,在組件中指定模板是經過template屬性

 

配置具體應該如何進行

  template:指定模板

  在template屬性中直接建立模板

  使用template標籤建立模板,在template屬性中指定

  建立模板結構,設置標識id

<template id='lwtemp'>
    <p style="color: red">我是隔壁老王~~~~!!!!</p>
</template>

 

在template屬性中指定這個模板

 Vue.component('laowang', {
     // 指定模板
     // 沒有語法高亮,沒有代碼提示,沒有層次結構,不方便修改
     template: "#lwtemp"
 })

 

細節:

這個錯誤告訴咱們組件只能有一個根元素,若是有多個則會出現這個錯誤,如何解決,將這多個元素再包含在到一個根元素中

 data:

  • 能夠定義當前組件中使用到的變量

  • data必須是一個函數

    • 一個組件的 data 選項必須是一個函數,所以每一個實例能夠維護一份被返回對象的獨立的拷貝

    • 若是不是一個函數,那麼有可能形成組件複用的時候,多個組件指向同一個對象,形成操做其中任何一個組件,其它組件會有莫名其妙的變化

    • 函數有做用域,在一個函數中生成的數據與其它的函數沒有關係,若是使用函數,就能夠作到一個組件內部的數據操做不會影響其它的組件,同時也不會影響組件的複用

    • data函數中必須返回 一個對象

在函數中必須返回一個對象

錯誤信息

  

緣由:你在組件中使用到了某些成員,可是這個成員在組件中卻沒有定義

1.組件是一個單獨的結構,一個組件默認不能使用另一個組件中定義的成員

緣由:組件中的Data選項必須是一個函數,這個函數還必須返回 一個對象,咱們定義的數據必須寫在這個返回的對象中

 

緣由:data函數必須返回一個對象,若是沒有成員,也須要返回一個{}

 

  • methods:

  • mounted:

  • watch:

  • computed:

// vm外面建立組件
Vue.component('laowang', {
    // 指定模板
    // 沒有語法高亮,沒有代碼提示,沒有層次結構,不方便修改
    template: "#lwtemp",
    // 添加設置數據
    data(){
        return {
            age:0,
            myname:'隔壁老李'
        }
    },
    methods:{
        sayHi(){
            alert('你好啊')
        }
    },
    mounted(){
        alert('頁面打開馬上執行')
    },
    computed:{
        myage(){
            return this.age - 0 + 10
        }
    }
})

 

組件的組織結構

之後真正進行開發的時候,頁面可能會比較的複雜,常常會看到元素嵌套的場景出現,若是你將一些結構封裝爲組件,那麼勢必會形成組件的嵌套,這樣就產生了一個組件相關的組織結構

  • 什麼是父組件,什麼是子組件

    • 外層組件就能夠認爲是父組件

    • 父組件中建立的組件就能夠認爲是這個父組件的子組件

    • 父子只是一個組織結構佈局

  • 爲何會出現父子組件這種結構

  • 建立父子組件

    • 先建立父組件

    • 在父組件內部經過components建立子組件

    • 子組件的建立方式和父組件徹底一致

Vue.component('father', {
     template: '#father',
     data() {
         return {
             fname: '老王'
         }
     },
     // 經過components屬性來建立子組件,它是一個對象
     components: {
         // 定義一個一個的子組件
         // 3.定義第一個子組件son
         son: {
             // 4.能夠寫與父組件相同的成員
             template: '#son',
             data() {
                 return {
                     sname: '小王'
                 }
             }
         }
     }
 })

 

  • components的兩個做用

    • 建立子組件

    • 組件註冊:若是你從其它地方引入一個組件那麼就必須先註冊才能使用

  • 使用子組件

    • 在某個父組件中建立的子組件只有在這個父組件中可使用

    • 所謂在父組件中使用是指在這個父組件的模板中使用

<!-- 2.父組件模板 -->
<template id='father'>
    <div class="father">
        <p>我是父組件:{{fname}}</p>
        <son></son>
    </div>
</template>

 

因爲上面的組件的組織結構,在真正進行開發的時候,咱們常常須要實現不一樣的組件之間的數據交互,那麼就必需要實現組件之間的數據傳遞

在一個組件中定義的數據只有在當前組件中可使用

父子組件之間的數據傳遞

父傳子

  • 父組件中數據要傳遞給子組件來使用

  • 若是要實現父傳子,子組件須要作什麼

    • 在子組件中定義props屬性,它是一個獨立的屬性

    • props是一個數組

    • 在props中定義的成員就至關於在data中定義的成員

    • 在props通常就是你想定義的屬性的名稱,它們的類型是字符串

    • 這個props至關於一個父組件爲子組件賦值的接口,在父組件中能夠爲子組件的props中定義的成員賦值

  • 若是要實現父傳子,在父組件中須要作什麼

    • 父組件中要使用子組件

    • 在父組件中使用子組件的位置,使用v-bind爲子組件中的prop屬性賦值

 

 

子傳父

  • 大體瞭解子傳父的場景

  • 經過this.$emit能夠發射事件

  • 子傳父在子組件中須要作什麼

    • 添加按鈕事件,在事件處理函數中去發射一個事件

    • 發射事件並傳入相應的數據,它是經過事件發射向父組件傳遞數據

  • 子傳父在父組件中又須要作什麼

    • 父組件中進行指定事件的監聽

    • 發現有指定的事件發射,就監聽並進行處理

    • 在父組件中使用子組件的位置使用v-on進行監聽,在監聽處理函數中有一個默認的參數,這個參數就是從子組件事件發射時傳遞的數據

 

 

兄弟組件之間的傳值

  • 查看使用場景

  • 爲何不能再使用this

    • this是指向當前組件,意味着事件只能由father組件進行監聽,與咱們要求不相合

    • this咱們知道它的本質就是一個vue實例,那麼咱們能不能直接建立一個全局的Vue實例來進行這個場景的事件發射呢?

  • 建立事件總線:new Vue()

    • 事件總線就是說明全部事件都能經過它來進行發射和監聽

    • 說白了,事件總線就是一個單獨的全局的Vue實例

  • 源組件中須要作什麼事情

    • 發射事件,傳遞數據

  • 目標組件須要作什麼事情

    • 監聽事件,接收數據

 

父傳子demo

<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>Document</title>
  <script src="./js/vue.js"></script>
</head>

<body>
  <!-- 建立父組件模版 -->
  <template id="father">
    <div>
      <h2>告訴兒子明天去{{surfing}}!</h2>
      <son :surfing="surfing"></son>
    </div>
  </template>
  
  <!-- 建立子組件模版 -->
  <template id="son">
    <h2>我爸爸告訴我明天去{{surfing}}</h2>
  </template>
  <div id='app'>
    <father></father>
  </div>
  <script>
    // 建立父組件
    Vue.component('father',{
      template: '#father',
      
      data(){
        return {surfing:'海上衝浪'}  
      },
      methods: {
        
      },
      // 建立子組件
      components: {
        son:{
          template: '#son',
          props: ['surfing'],
          data(){
            return {}
          },
          methods: {
            
          }
        }
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {}
    })  
  </script>
</body>

</html>

 

子傳父demo

<!-- 
  思路:
    1.子組件發射事件,傳遞數據
    2.父組件中使用子組件的位置進行監聽,經過v-on:事件名='事件處理函數'
 -->
<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>Document</title>
  <script src="./js/vue.js"></script>
</head>

<body>
  <!-- 建立父組件模板 -->
  <template id="father">
    <div>
      <h2>I am Father,我兒子的女友是:{{gfname}}</h2>
      <son v-on:emitname='getname'></son>
    </div>
  </template>

  <!-- 建立子組件模版 -->
  <template id="son">
    <div>
        <h2>I am Son</h2>
        <button @click="sendName">點我發送女友楊冪給我爸爸</button>
    </div>
  </template>
  <div id='app'>
    <father></father>
  </div>
  <script>
    // 建立父組件
    Vue.component('father', {
      template: '#father',
      data() {
        return {
          gfname: ''
        }
      },
      methods: {
        getname(data){
          console.log(data)
          this.gfname = data;
        }
      },
      // 建立子組件
      components: {
        son: {
          template: '#son',
          data() {
            return {
              gfname: '楊冪'
            }
          },
          methods: {
            sendName(){
              // $emit能夠發射事件
              // this.$emit(事件名稱,事件參數(數據))
              // 注意:在子組件函數中發射一個事件並不須要關心誰去作監聽
              this.$emit('emitname',this.gfname)
            }
          }
        }
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {}
    })  
  </script>
</body>

</html>

 

兄弟組件傳值demo

<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>Document</title>
  <script src="./js/vue.js"></script>
</head>

<body>
  <!-- 建立父組件模版 -->
  <template id="father">
    <div>
      <alex></alex>
      <roger></roger>
    </div>
  </template>

  <!-- 建立2個兄弟組件模版 -->
  <template id="alex">
    <div>
        <h2>我要告訴我兄弟今天去{{dosomething}}</h2>
        <button @click="tellinfo">點擊發送短信</button>
    </div>
  </template>

  <template id="roger">
    <h2>WoW,我兄弟告訴我今天要去{{dosome}},好興奮!</h2>
  </template>
  <div id='app'>
    <father></father>
  </div>
  <script>
    //建立事件總線bus實例
    var bus = new Vue();

    // 建立父組件
    Vue.component('father',{
      template: '#father',
      data(){
        return {}
      },
      methods: {
        
      },
      // 建立2個兄弟組件
      components: {
        alex: {
          template: '#alex',
          data(){
            return {
              dosomething: '釣魚',
            }
          },
          methods: {
            tellinfo(){
              // 使用事件總線來發送事件
              bus.$emit('emitname', this.dosomething)
            }
          }
        },
        roger:{
          template: '#roger',
          data(){
            return {
              dosome:'??'
            }
          },
          methods: {

          },
          mounted () {
            bus.$on('emitname', data=>{
              console.log(data)
              this.dosome = data
            })
          }
        }
      }
    })

    var vm = new Vue({
      el: '#app',
      data: {}
    })  
  </script>
</body>

</html>

 

路由

能夠實現導航跳轉(頁面跳轉)的一種方式,在vue組件的跳轉都是經過路由來實現的

https://router.vuejs.org/zh/

  • 爲何要使用路由

    • 由於咱們不想實現頁面的跳轉

    • 可是咱們又想展現不一樣的頁面的不一樣的內容

  • 咱們要作什麼

    • 咱們須要作的是,將組件 (components) 映射到路由 (routes),而後告訴 Vue Router 在哪裏渲染它們

  • 基本路由的添加方式

    • 你得路由如何添加:它是一個單獨的結構

    • 經過VueRouter進行路由對象的建立

    • 經過routes進行路由配置

    • 路由和組件如何映射

    • 如何指定你組件內容的展現區域

  • 如何使用路由

    • 掛載路由=注入路由

    • 添加router-view結構,指定路由映射組件的展現區域

demo

<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>Document</title>
  <script src="./js/vue.js"></script>
  <script src="./js/vue-router.js"></script>
</head>

<body>

  <div id='app'>
    <router-link to="/index">首頁</router-link>
    <router-link to="/product">產品頁</router-link>
    <h3>路由匹配到的組件將渲染在這裏</h3>
    <div style="width:600px; height: 400px; border: solid">
      <router-view></router-view>
    </div>
  </div>
  <script>
    // 每一個路由對象映射着一個單獨的組件,因此咱們第一步建立好組件
    // 1.建立幾個組件
    var Index = Vue.component('index', {
      template: '<div>首頁</div>'
    })
    var Product = Vue.component('product', {
      template: '<div>產品</div>'
    })
    // 2.建立路由對象,建立以前不要忘了引入vue-router.js文件
    // 經過new VueRouter()來建立路由對象,在構造函數中添加路由配置
    var router = new VueRouter({
      // 3.添加路由配置
      // 咱們能夠配置多個路由,因此使用routes來進行多個路由的配置
      routes: [
        // 4.添加單個路由配置,俺哥路由都是以對象的方式存在,對於單個路由通常咱們
        //會配置下面幾個屬性
        {
          name: 'Index',
          path: '/index',
          component: Index
        },
        {
          name: 'Product',
          path: '/product',
          component: Product
        }
      ]
    })

    var vm = new Vue({
      el: '#app',
      // 5.注入/掛載路由
      router: router,
      data: {}
    })  
  </script>
</body>

</html>

 

思惟腦圖總結:

 

相關文章
相關標籤/搜索