vue組件化

  • 什么是組件化
    將一個完整的頁面分成很多個組件,每個組件用于實現(xiàn)頁面的一個功能塊,每一個組件又可以細(xì)分。
  • 組件化基本使用
    • 組件化使用三個步驟:
      1.創(chuàng)建組件構(gòu)造器
      2.注冊組件
      3.使用組件


      組件化使用步驟
<div id="app">
  <!--  3.使用組件-->
  <my-cpn></my-cpn>
</div>
<script>
  // 用``定義字符串可以換行
  // 1.創(chuàng)建組件構(gòu)造器對象
  const cpnC = Vue.extend({
    template: `
      <div>
        <h2>我是標(biāo)題1</h2>
        <p>我是內(nèi)容111</p>
        <p>我是內(nèi)容222</p>
      </div>`
  })
  // 2.注冊組件
  Vue.component('my-cpn', cpnC);

  const app = new Vue({
    el: '#app',
    data: {
      
    }
  })
</script>
  • 全局組件
    全局組件:
// 注冊組件(全局組件),可以在多個vue實例下使用
Vue.component('my-cpn', cpnC);

局部組件:

  const app = new Vue({
    el: '#app',
    data: {

    },
    // 注冊局部組件,只能在該vue實例中使用
    components: {
      my_cpn: cpnC
    }
  })
  • 父組件和子組件
<div id="app">
  <my_cpn2></my_cpn2>
</div>
<script>
  // 創(chuàng)建第一個組件構(gòu)造器(子組件)
  const cpn_c1 = Vue.extend({
    template:`
      <div>
        <h2>標(biāo)題1</h2>
        <p>內(nèi)容1</p>
      </div>`
  })
  // 創(chuàng)建第二個組件構(gòu)造器(父組件)
  const cpn_c2 = Vue.extend({
    template:`
      <div>
        <h2>標(biāo)題2</h2>
        <p>內(nèi)容2</p>
        <my_cpn1></my_cpn1>
      </div>`,
    // 在組件2中注冊組件1,就可以在組件2中使用組件1
    components: {
      my_cpn1: cpn_c1
    }
  })

  const app = new Vue({
    el: '#app',
    data: {

    },
    components: {
      my_cpn2: cpn_c2
    }
  })
</script>
  • 注冊組件語法糖和組件模板抽離寫法
<div id="app">
  <my-cpn1></my-cpn1>
  <my_cpn2></my_cpn2>
</div>

<template id="my-cpn">
  <div>
    <h2>我是標(biāo)題1</h2>
    <p>我是內(nèi)容111</p>
  </div>
</template>
<script>
  // 注冊全局組件
  Vue.component('my-cpn1', {
    template: '#my-cpn'
  });
  const app = new Vue({
    el: '#app',
    data: {

    },
    // 注冊局部組件,只能在該vue中使用
    components: {
      'my_cpn2': {
        template: '#my-cpn'
      }
    }
  })
</script>
  • 組件中的data和方法
<div id="app">
  <my_cpn></my_cpn>
  <my_cpn></my_cpn>
</div>

<template id="cpn">
  <div>
    <h2>當(dāng)前計數(shù):{{counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

<script>
  const app = new Vue({
    el: '#app',
    components: {
      'my_cpn': {
        template: '#cpn',
        // 存放組件的數(shù)據(jù)
        data() {
          return {
            counter: 0
          }
        },
        methods: {
          increment() {
            this.counter ++;
          },
          decrement() {
            this.counter --;
          }
        }
      }
    }
  })
</script>
  • 組件通信
    1.父傳子props
    父子組件通信

    在組件中使用props來聲明需要從父級接收的數(shù)據(jù)
    props的值有兩種方式:
    方式一:字符串?dāng)?shù)組,數(shù)組中的字符串就是傳遞時的名稱
    方式二:對象,對象可以設(shè)置傳遞時的類型,也可以設(shè)置默認(rèn)值等
  function Person(name){
    this.name = name
  }
  Vue.component('my-conmponent', {
    props: {
      // 基礎(chǔ)類型檢查(null匹配任何類型)
      itemA: Number,
      // 多個可能的類型
      itemB: [String, Number],
      // 必須傳的
      itemC: {
        type: String,
        required: true
      },
      // 有默認(rèn)值的
      itemD: {
        type: String,
        default: 'ABC'
      },
      // 有默認(rèn)值的數(shù)組
      itemE: {
        type: Array,
        default() {
          return [];
        }
      },
      // 有默認(rèn)值的對象
      itemF: {
        type: Object,
        default() {
          return {message: 'hello'}
        }
      },
      // 自定義驗證函數(shù)
      itemG: {
        validator(value) {
          return ['success','warning','danger'].indexOf(value) !== -1
        }
      },
      // 驗證自定義類型
      itemH: Preson
    }
  })

舉例:

<div id="app">
  <my_cpn v-bind:cmovies="movies" :msg="message"></my_cpn>
</div>
<template id="cpn">
  <ul>
    <li v-for="item in cmovies">{{item}}</li>
  </ul>
  <h3>{{msg}}</h3>
</template>
<script>
  const my_cpn = {
    template: '#cpn',
    // props: ['cmovies', 'msg']
    props: {
      // 1.類型限制
      // cmovies: Array,
      // msg: String
      // 2.提供默認(rèn)值
      msg: {
        type:String,
        default: 'hi',
        // 必傳值(要使用my_cpn組件,必須傳msg)
        required: true
      },
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
    }
  }
  const app = new Vue({
    el: '#app',
    data: {
      movies: ['送你一朵小紅花', '金剛川', '少年的你'],
      message: 'hello'
    },
    components: {
      my_cpn
    }
  })
</script>

2.子傳父

<div id="app">
  <my_cpn @item-click="in_cpn_click"></my_cpn>
</div>

<template id="cpn">
  <div>
    <button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
  </div>
</template>

<script>
  // 子組件
  const my_cpn = {
    template: '#cpn',
    data() {
      return {
        categories: [
          {id: 1, name: '熱門推薦'},
          {id: 2, name: '手機數(shù)碼'},
          {id: 3, name: '美妝護(hù)膚'}
        ]
      }
    },
    methods: {
      btnClick(item) {
        console.log(item.name + '被點擊');
        // 告訴父組件被點擊的是哪一個item
        // 發(fā)射事件
        this.$emit('item-click', item)
      }
    }
  }

  // 父組件
  const app = new Vue({
    el: '#app',
    components: {
      my_cpn
    },
    methods: {
      in_cpn_click(item) {
        console.log('子組件中的' + item.name + '被點擊');
      }
    }
  })
</script>
  • 組件訪問
    1.父訪問子
  <div id="app">
    <cpn></cpn>
    <!-- refs方式需要在使用組件時,添加ref屬性 -->
    <cpn ref="cpn2"></cpn>
    <button @click="btnClick()">按鈕</button>
  </div>

  <template id="cpn">
    <div>我是子組件</div>
  </template>
  <script>
    
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello world'
      },
      methods: {
        btnClick() {
          // $children較少用,一般用refs
          // console.log(this.$children);
          // this.$children[0].showMessage()
          // console.log(this.$children[0].name)

          console.log(this.$refs.cpn2.name);
          this.$refs.cpn2.showMessage();
        }
      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              name: 'Naruto'
            }
          },
          methods: {
            showMessage() {
              console.log('showMessage');
            }
          },
        }
      }
    })
  </script>

2.子訪問父
不建議使用

  • 組件的插槽
    組件的插槽是為了讓我們封裝的組件更具擴展性,讓使用者可以決定組件內(nèi)部的一些內(nèi)容到底展示什么。
    將共性抽取到組件中,將不同暴露為插槽??梢宰屖褂谜吒鶕?jù)自己的需求,決定插槽中插入的內(nèi)容。
  <div id="app">
    <cpn><button>按鈕</button></cpn>
    <cpn><span>哈哈哈</span></cpn>
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是組件標(biāo)題</h2>
      <p>我是組件內(nèi)容</p>
      <!-- 插槽即預(yù)留一些空間,使用時可以在組件中插入其它標(biāo)簽 -->
      <!-- <slot></slot> -->
      <!-- 如果使用時沒有插入標(biāo)簽,則默認(rèn)顯示插槽中的標(biāo)簽 -->
      <slot><button>插槽默認(rèn)按鈕</button></slot>
    </div>
  </template>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello world'
      },
      components: {
        cpn: {
          template: '#cpn'
        }
      }
    })
  </script>
插槽
  • 具名插槽
  <div id="app">
    <!-- 替換沒有name的slot -->
    <cpn><span>span</span></cpn>
    <cpn>
      <template v-slot:left>
        <span>替換左邊slot</span>
      </template>
      <template v-slot:right>
        <span>替換右邊內(nèi)容</span>
      </template>
    </cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>組件標(biāo)題</h2>
      <p>組件內(nèi)容</p>
      <slot name="left">左邊</slot>
      <slot name="center">中間</slot>
      <slot name="right">右邊</slot>
      <slot></slot>
    </div>
  </template>

  <script>
    const app = new Vue({
      el: '#app',
      components: {
        cpn: {
          template: '#cpn'
        }
      }
    })
  </script>
具名插槽
  • 作用域插槽
    父組件替換插槽的標(biāo)簽,但是內(nèi)容由子組件來提供。
  <!-- 父組件替換插槽的標(biāo)簽,但是內(nèi)容由子組件來提供 -->
  <div id="app">
    <cpn></cpn>
    <cpn>
      <!-- 獲取子組件中的pLanguages -->
      <template v-slot:default="slotProps">
      <span v-for="item in slotProps.languages">{{item}} - </span>
      </template>
    </cpn>
  </div>

  <template id="cpn">
    <div>
      <!-- 將子組件的數(shù)據(jù)傳給父組件 -->
      <slot :languages="pLanguages">
        <ul>
          <li v-for="item in pLanguages">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>
  <script>
    const app = new Vue({
      el: '#app',
      data: {

      },
      components: {
        cpn: {
          template: '#cpn',
          data() {
            return {
              pLanguages: ['JavaScript', 'Java', 'Python', 'c++', 'go', 'Swift']
            }
          }
        }
      }
    })
  </script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Vue的組件化 經(jīng)過兩天的學(xué)習(xí),現(xiàn)在終于來到了組件化開發(fā)的環(huán)節(jié),Vue的組件化是很重要的一個點,一定要認(rèn)真學(xué)習(xí)??!...
    waigo閱讀 435評論 0 1
  • 認(rèn)識組件 組件化開發(fā): ? 將一個完成的頁面,劃分成一個個的組件,最終由一個個組件來完成整個頁面你的開發(fā),這個...
    cj_jax閱讀 241評論 0 1
  • Vue 組件官網(wǎng):https://cn.vuejs.org/v2/guide/components.html 組件...
    瓔珞紈瀾閱讀 503評論 0 1
  • 前言 在工作中經(jīng)常會用到Vue,包括也會用到很多重要的點例如組件化等等,現(xiàn)在也想對于之前的應(yīng)用和學(xué)習(xí)做一個小小的總...
    羊駝駝駝駝閱讀 508評論 0 2
  • 一、組件注冊使用 組件使用步驟 (全局組件)①創(chuàng)建組件構(gòu)造器 ②注冊組件 ③使用組件 在vue實例對象管理的 域 ...
    shaoyf閱讀 196評論 0 1

友情鏈接更多精彩內(nèi)容