十一、VUE基礎學習篇(組件化component、components)-全局/局部組件、父組件/子組件、動態數據綁定/數據存放問題

碼雲實時更新學習demo地址:https://gitee.com/dxl96/vuexuexi

VUE基礎篇(組件化component、components)

1、組件化的概念

■人面對複雜問題的處理方式
  口任何一個人處理信息的邏輯能力都是有限的
  口所以,當面對一個非常複雜的問題時,我們不太可能一次性搞定一大堆的內容。
  口但是,我們人有一種天生的能力,就是將問題進行拆解。
  口如果將一個複雜的問題,拆分成很多個可以處理的小問題,再將其放在整體當中,你會發現大的問題也會迎刃而解。
■組件化也是類似的思想
  口如果我們將一個頁面中所有的處理邏輯全部放在一起,處理起來就會變得非常複雜,而且不利於後續的管理以及擴展。
  口但如果,我們講一個頁面拆分成一個個小的功能塊每個功能塊完成屬於自己這部分獨立的功能,那麼之後整個頁面的管理和維護就變得非常容易了。

■組件化是Vue.js中的重要思想
  口它提供了一種抽象,讓我們可以開發出一個個獨立可複用的小組件來構造我們的應用。
  口任何的應用都會被抽象成一顆組件樹。
■組件化思想的應用:
  口有了組件化的思想,我們在之後的開發中就要充分的利用它。
  口儘可能的將頁面拆分成一個個小的、可複用的組件。
  口這樣讓我們的代碼更加方便組織和管理,並且擴展性也更強。

2、組件的基本使用

■組件的使用分成三個步驟
  口創建組件構造器
  口註冊組件
  口使用組件。
■我們來看看通過代碼如何註冊組件
■查看運行結果:
  口和直接使用一個div看起來並沒有什麼區別。
  口但是我們可以設想,如果很多地方都要顯示這樣的信息,我們是不是就可以直接使用來完成呢?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>組件的基本使用</title>
</head>
<body>
<!--
■人面對複雜問題的處理方式
  口任何一個人處理信息的邏輯能力都是有限的
  口所以,當面對一個非常複雜的問題時,我們不太可能一次性搞定一大堆的內容。
  口但是,我們人有一種天生的能力,就是將問題進行拆解。
  口如果將一個複雜的問題,拆分成很多個可以處理的小問題,再將其放在整體當中,你會發現大的問題也會迎刃而解。
■組件化也是類似的思想:
  口如果我們將一個頁面中所有的處理邏輯全部放在一起,處理起來就會變得非常複雜,而且不利於後續的管理以及擴展。
  口但如果,我們講一個頁面拆分成一個個小的功能塊每個功能塊完成屬於自己這部分獨立的功能,那麼之後整個頁面的管理和維護就變得非常容易了。
-->

<!--
■組件化是Vue.js中的重要思想
  口它提供了一種抽象,讓我們可以開發出一個個獨立可複用的小組件來構造我們的應用。
  口任何的應用都會被抽象成一顆組件樹。
■組件化思想的應用:
  口有了組件化的思想,我們在之後的開發中就要充分的利用它。
  口儘可能的將頁面拆分成一個個小的、可複用的組件。
  口這樣讓我們的代碼更加方便組織和管理,並且擴展性也更強。
-->

<!--
■組件的使用分成三個步驟
  口創建組件構造器
  口註冊組件
  口使用組件。
■我們來看看通過代碼如何註冊組件
■查看運行結果:
  口和直接使用一個div看起來並沒有什麼區別。
  口但是我們可以設想,如果很多地方都要顯示這樣的信息,我們是不是就可以直接使用<my-cpn></my-cpn>來完成呢?
-->

<div id="app">

  <!--  3、組件的使用,註冊組件時如果組件名稱是駝峯命名,會按照駝峯拆分爲以-拼接的名稱-->
  <my-div></my-div>
</div>

<script src="../js/vue.js"></script>
<script>

  // 1、創建組件構造器,extend方法,傳入一個對象,對象有個template屬性,它的值就是我們要用的模板內容
  const myDiv = Vue.extend({
    template: `
       <div>
         <h2>我是標題</h2>
         <p>我是內容一</p>
         <p>我是內容二</p>
       </div>`
  })

  // 2、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲構造的組件對象
  Vue.component('myDiv', myDiv)

  const app = new Vue({
    el: "#app",
    data: {}
  });
</script>
</body>
</html>

效果
在這裏插入圖片描述

3、全局組件和局部組件

全局組件是可以在所有的vue對象實例對應的標籤內使用的,而局部組件只能在局部組件所在的vue對象實例對應的標籤中使用
全局組件註冊:
Vue.component(組件名, 組件對象)

  // 2、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲構造的組件對象
  Vue.component('myDiv', myDiv)

局部組件註冊:
components: {組件名1:組件對象,組件名2:組件對象2…}

  const app2 = new Vue({
    el: "#app2",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 2、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    components: {
      myDiv2: myDiv
    }
  });

代碼示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>全局組件和局部組件</title>
</head>
<body>
<div id="app">
  <!--  3、組件的使用-->
  <!--  全局組件的使用-->
  <span style="color: red">全局組件</span>
  <my-div></my-div>
  <my-div></my-div>

  <!--  局部組件,在本實例對象中不會生效,該組件定義在app2中-->
  <span style="color: red">my-div2局部組件不在非註冊vue實例中顯示</span>
  <my-div2></my-div2>
</div>
<hr>
<div id="app2">
  <!--  3、組件的使用-->
  <!--  全局組件,在任何vue實例都可以使用-->
  <span style="color: red">全局組件</span>
  <my-div></my-div>

  <!--  局部組件,只在本實例對象中生效-->
  <span style="color: red">my-div2局部組件顯示(在註冊vue實例對象中)</span>
  <my-div2></my-div2>
</div>

<script src="../js/vue.js"></script>
<script>

  // ■【全局組件的方式,可以在多個vue實例使用】
  // 1、創建組件構造器,extend方法,傳入一個對象,對象有個template屬性,它的值就是我們要用的模板內容
  const myDiv = Vue.extend({
    template: `
       <div>
         <h2>我是標題</h2>
         <p>我是內容一</p>
         <p>我是內容二</p>
       </div>`
  })

  // 2、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲構造的組件對象
  Vue.component('myDiv', myDiv)

  // -----------------------------------------------------------------------------------------------


  // vue實例1
  const app = new Vue({
    el: "#app",
    data: {}
  });

  // vue實例2
  const app2 = new Vue({
    el: "#app2",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 2、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    components: {
      myDiv2: myDiv
    }
  });
</script>
</body>
</html>

效果
在這裏插入圖片描述

3、父子組件

所謂父子組件就是組件的嵌套,假設:組件2嵌套組件1(也就是組件2中包含組件1),父組件就是組件1,子組件就是組件2

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>父組件和子組件</title>
</head>
<body>
<div id="app">

  <!--  3、組件的使用-->
  <!--  組件2中包含組件1-->
  <my-div2></my-div2>

  <!--  該組件1是不可直接使用的,因爲沒有在root組件中註冊過-->
  <my-div1></my-div1>
</div>

<script src="../js/vue.js"></script>
<script>
  // 1、創建組件構造器,創建一個組件對象
  
  // 【子組件】
  // 創建組件構造器,extend方法,傳入一個對象,對象有個template屬性,它的值就是我們要用的模板內容
  const myDiv1 = Vue.extend({
    template: `
       <div>
         <h2>我是標題1</h2>
         <p>我是內容1</p>
       </div>`
  })

  // 【父組件】
  // 嵌套子組件,extend方法傳入對象,對象裏面的components屬性,也是可以將另一個組件對象添加進該組件的,components對應對象的屬性名稱是組件的名稱,屬性值是已經創建的組件對象
  // 這裏的子組件是上面創建的組件對象
  const myDiv2 = Vue.extend({
    template: `
      <div>
        <h2>我是標題2</h2>
        <p>我是內容2</p>
        <my-div1></my-div1>
      </div>`,
    components: {
      myDiv1: myDiv1
    }
  })

  /*------------------------------------------------------------------------------------------------------------------------*/
  
  // root組件
  const app = new Vue({
    el: "#app",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 2、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    //這裏註冊組件2即可,組件1已經註冊進了組件2,所以使用組件2時就是組件2嵌套組件1的樣子
    components: {
      myDiv2: myDiv2
    }
  });
</script>
</body>
</html>

效果
在這裏插入圖片描述

4、組件語法糖

●在之前註冊組件的方式,可能會有些繁瑣。
  口Vue爲了簡化這個過程,提供了註冊的語法糖。
  口主要是省去了調用Vue.extend()的步驟,也就是構造組件對象這個步驟,而是可以直接使用一個組件對象來代替。說的再直白點就是將組件的對象的構造和註冊合而爲一了,在註冊組件時,直接傳入組件對象即可
  口全局組件對象和局部組件對象的結構是一樣的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>組件語法糖</title>
</head>
<body>

<div id="app">
  <!--  2、使用組件-->
  <my-div1></my-div1>

  <my-div2></my-div2>
</div>

<script src="../js/vue.js"></script>
<script>

  /*
    ●在之前註冊組件的方式,可能會有些繁瑣。
      口Vue爲了簡化這個過程,提供了註冊的語法糖。
      口主要是省去了調用Vue.extend()的步驟,而是可以直接使用一個組件對象來代替。
      口全局組件對象和局部組件對象的結構是一樣的
   */

  // ■【註冊全局組件的語法糖】
  // 1、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲組件對象,
  // 組件對象有一個template屬性,屬性值爲模板信息
  Vue.component('myDiv1', {
    template: `
            <div>
              <h2>我是標題1</h2>
              <p>我是內容1</p>
            </div>
            `
  })

  //■【註冊局部組件的語法糖】
  const app = new Vue({
    el: "#app",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 1、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    components: {
      //這裏相當於將組件的創建與註冊整合成了一個方式,註冊組件時可以直接綁定對象,對象有個template屬性,屬性值就是我們的模板信息
      myDiv2: {
        template: `
            <div>
              <h2>我是標題2</h2>
              <p>我是內容2</p>
            </div>
            `
      }
    }
  });
</script>
</body>
</html>

效果
在這裏插入圖片描述

4、組件對象與組件註冊的分離

■剛纔,我們通過語法糖簡化了Vue組件的註冊過程,另外還有一個地方的寫法比較麻煩,就是template模塊寫法
■如果我們能將其中的HTML分離出來寫,然後掛載到對應的組件上,必然結構會變得非常清晰。
■Vue提供了兩種方案來定義HTML模塊內容:
  口使用<script>標籤
  口使用<template>標籤

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>組件語法糖分離版本</title>
</head>
<body>

<div id="app">
  <!--  2、使用組件-->
  <my-div1></my-div1>
  <my-div2></my-div2>
</div>

<!--
■剛纔,我們通過語法糖簡化了Vue組件的註冊過程,另外還有一個地方的寫法比較麻煩,就是template模塊寫法
■如果我們能將其中的HTML分離出來寫,然後掛載到對應的組件上,必然結構會變得非常清晰。
■Vue提供了兩種方案來定義HTML模塊內容:
  口使用<script>標籤
  口使用<template>標籤
-->

<!--第一種寫法:template標籤-->
<template id="myDiv1">
  <div>
    <h2>我是標題1</h2>
    <p>我是內容1</p>
  </div>
</template>

<!--第二種寫法:script標籤,注意類型必須是text/x-template-->
<script type="text/x-template" id="myDiv2">
  <div>
    <h2>我是標題2</h2>
    <p>我是內容2</p>
  </div>`
</script>

<script src="../js/vue.js"></script>
<script>

  // ■【註冊全局組件的語法糖】
  // 1、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲組件對象,
  // 組件對象有一個template屬性,屬性值爲綁定template標籤或script標籤的id
  Vue.component('myDiv1', {
    template: "#myDiv1"
  })

  //■【註冊局部組件的語法糖】
  const app = new Vue({
    el: "#app",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 1、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    // 構造的組件有一個template屬性,值爲要綁定的template標籤或script標籤的id
    components: {
      myDiv2: {
        template: '#myDiv2'
      }
    }
  });
</script>


</body>
</html>

4、組件動態綁定數據-數據存放問題

之前我們的寫法中,組件內的數據都是寫死的,那麼怎麼綁定動態數據呢,還是用vue實例中的data屬性對應的數據對象?錯
■組件自己的數據存放在哪裏呢?
  口組件對象也有一個data屬性(也可以有methods等屬性,下面我們有用到)
  口只是這個data屬性必須是一個函數
  口而且這個函數返回一個對象,對象內部保存着數據
■爲什麼data屬性必須是一個函數,函數返回一個對象,對象內部保存着數據?
  口因爲要實現組件複用,實現組件複用就必須滿足組件指向的數據對象不能是同一個數據對象
  口因爲data是直接return返回的一個對象,所以這裏調用相當於創建實例時,每個data返回的都是一個單獨的data數據對象,這樣才能做到組件的複用,要是data指向同一個對象,可以想象,每次實例化組件對象時,每個data都指向的是同一個數據對象,就不能進行復用了,因爲只要其中一個組件改變了data數據,那麼其他組件也就跟着變化了,這很明顯是不符合邏輯的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>組件動態綁定數據</title>
</head>
<body>
<!--
■組件自己的數據存放在哪裏呢?
  口組件對象也有一個data屬性(也可以有methods等屬性,下面我們有用到)
  口只是這個data屬性必須是一個函數
  口而且這個函數返回一個對象,對象內部保存着數據
-->

<div id="app">
  <!--  2、使用組件-->

  <!--  全局組件-->
  <p>全局組件</p>
  <my-div1></my-div1>
  <hr>
  <!--  局部組件-->
  <p>局部組件</p>
  <my-div2></my-div2>

  <!--
    ■這裏是相當於創建了四個組件對象,每個組件對象是互不影響的,這和組件對象的data屬性爲什麼是函數有關?
      因爲data是直接return返回的一個對象,所以這裏調用相當於創建實例時,每個data返回的都是一個單獨的data數據對象,
      這樣才能做到組件的複用,要是data指向的一個對象,可以想象,每次實例化組件對象時,每個data都指向的是同一個數據對象,就不能
      進行復用了,因爲只要其中一個組件改變了data數據,那麼其他組件也就跟着變化了,這很明顯是不符合邏輯的
    -->
  <!--  <my-div1></my-div1>-->
  <!--  <my-div1></my-div1>-->
  <!--  <my-div2></my-div2>-->
  <!--  <my-div2></my-div2>-->
</div>


<!--第一種寫法:template標籤-->
<template id="myDiv1">
  <div>
    <!--    組件動態綁定屬性-->
    <h2>{{title1}}</h2>
    <p>{{content1}}</p>
    <p>{{counter}}</p>
    <button @click="counterAdd">-</button>
    <button @click="counterSub">-</button>
  </div>
</template>

<!--第二種寫法:script標籤,注意類型必須是text/x-template-->
<script type="text/x-template" id="myDiv2">
  <div>
    <!--    組件動態綁定屬性-->
    <h2>{{title2}}</h2>
    <p>{{content2}}</p>
    <p>{{counter2}}</p>
    <button @click="counterAdd2">-</button>
    <button @click="counterSub2">-</button>
  </div>
</script>

<script src="../js/vue.js"></script>
<script>

  // ■組件不能直接綁定VUE實例的屬性數據,只能通過組件內部的data屬性來進行動態綁定數據,和methods綁定組件方法

  // ■【註冊全局組件的語法糖】
  // 1、全局註冊組件,component方法,傳入兩個值,第一個參數爲組件的名稱,第二個參數爲組件對象,
  // 組件對象有一個template屬性,屬性值爲綁定template標籤或script標籤的id
  // 同時標籤動態綁定數據,需要用到組件對象中的data屬性,data屬性是一個函數,函數返回數據對象,數據對象裏面保存着數據
  Vue.component('myDiv1', { // 屬性名爲要註冊組件的名稱,隨便命名,給組件起一個名字
    template: "#myDiv1", //綁定需要註冊的組件
    data() { // 組件要綁定的數據
      return {
        title1: "我是標題1",
        content1: "我是內容1",
        counter: 0
      };
    },
    methods: { //組件綁定的方法
      counterAdd() {
        this.counter++
      },
      counterSub() {
        this.counter--
      }
    }
  })

  //■【註冊局部組件的語法糖】
  const app = new Vue({
    el: "#app",
    data: {},
    //■【局部組件的註冊方式,只在本實例中才會生效】
    // 1、註冊組件,components屬性,傳入對象,對象的屬性爲組件的名稱,值爲構造的組件
    // 構造的組件有一個template屬性,值爲要綁定的template標籤或script標籤的id
    // 同時標籤動態綁定數據,需要用到組件對象中的data屬性,data屬性是一個函數,函數返回數據對象,數據對象裏面保存着數據
    components: {
      myDiv2: { // 屬性名爲要註冊組件的名稱,隨便命名,給組件起一個名字
        template: "#myDiv2", //綁定需要註冊的組件
        data() { // 組件要綁定的數據
          return {
            title2: "我是標題2",
            content2: "我是內容2",
            counter2: 0
          }
        },
        methods: { //組件綁定的方法
          counterAdd2() {
            this.counter2++
          },
          counterSub2() {
            this.counter2--
          }
        }
      }
    }
  });
</script>
</body>
</html>

效果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章