Vue組件化開發(fā)

?目錄總覽:(組件化概念、組件注冊、數(shù)據(jù)存放、組件數(shù)據(jù)共享、組件插槽、使用步驟)

一、組件化概念

1. 組件化開發(fā)思想

組件化思想的特點:標準、分治、復用、組合

2. 組件定義

 **組件化**開發(fā):根據(jù)封裝的思想,把頁面上可重用的 UI 結(jié)構(gòu)封裝為組件,從而方便項目的開發(fā)和維護。

3. Vue中的組件化開發(fā)

 **vue** 是一個**支持組件化開發(fā)的前端框架**。

 **vue** 中規(guī)定:**組件的后綴名是 .vue**。之前接觸到的 App.vue 文件本質(zhì)上就是一個 vue 的組件,即**單組件**(單文件組件)。

4. Vue組件的三個組成部分

每個 .vue 組件都由 3 部分構(gòu)成,分別是:

  • template -> 組件的模板結(jié)構(gòu)
  • script -> 組件的 JavaScript 行為
  • style -> 組件的樣式

其中,每個組件中必須包含 template 模板結(jié)構(gòu),而 script 行為style 樣式可選的組成部分。

二、組件注冊

1. 全局組件??

//全局組件使用
<div id="app">
    <組件名稱></組件名稱>
</div>

//全局組件注冊
Vue.component(組件名稱, {
    data: 組件數(shù)據(jù),
    template: 組件模板內(nèi)容
})
  • 1.1 全局組件組件可以在app實例內(nèi)部任意地方使用:我們可以在 app 實例下使用,也可以在 home 實例下使用,也可以在 message 實例下使用。
<body>
  <div id="app">
    <div id="home">
      <span>首頁</span>
      <button-counter></button-counter>
    </div>
    <div id="message">
      <span>消息</span>
      <button-counter></button-counter>
    </div>
    <!--調(diào)用全局注冊組件-->
    <button-counter></button-counter>
  </div>

  <script src="../js/vue.js"></script>
  <script>
     // 2.定義一個組件(全局組件)
     app.component('button-counter',{
       data() {
         return {
           count: 0
         }
       },
       template: `
        <button @click="count++">你點擊了{{count}}次</button>`
     })
     // 1.創(chuàng)建Vue的實例對象
     const app = Vue.createApp({
      data(){
        return {
          msg: '你好,Vue3!'
        }
      }
     });
     // 3. 掛載vue實例
     app.mount('#app'); 
  </script>
</body>
  • 1.2 可以設(shè)置多個全局組件,代碼如下:
<body>
<div id="app">
  <div id="home">
    <span>首頁</span>
    <button-counter></button-counter>
  </div>
  <div id="message">
    <span>消息</span>
    <button-counter></button-counter>
    <!--調(diào)用第二個注冊組件-->
    <lk-box></lk-box>
  </div>
  <!--調(diào)用全局注冊組件-->
  <button-counter></button-counter>
</div>

<script src="../js/vue.js"></script>
<script>
  // 1.創(chuàng)建Vue的實例對象
  const app = Vue.createApp({
    data(){
      return {
        msg: '你好,Vue3!'
      }
    }
  });

  // 2.定義一個組件(全局組件)
  app.component('button-counter',{
    data() {
      return {
        count: 0
      }
    },
    template: `
        <button @click="count++">你點擊了{{count}}次</button>
       `
  })
  // 定義第二個全局組件
  app.component('lk-box',{
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子組件
        </div>
       `
  })

  // 3. 掛載vue實例
  app.mount('#app');
</script>
</body>

  • 1.3 全局組件之間可以相互使用,使用方式如下:我們在定義第二個全局組件,若向使用第一個全局組件,只需要將第一個全局組件的名稱標簽寫入模板template中即可。
// 定義第二個全局組件
app.component('lk-box',{
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子組件
        <button-counter></button-counter>
        </div>
       `
})

2. 局部組件??

  • 局部組件只能在注冊他的父組件中使用
//局部組件使用
<div id="app">
    <ComponentA></ComponentA>
    <ComponentB></ComponentB>
    <ComponentC></ComponentC>
</div>

//局部組件注冊
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
new Vue({
    el: '#app'
    components: {
        'component-a': ComponentA,
        'component-b': ComponentB,
        'component-c': ComponentC,
    }
})

實例:

//局部組件使用
<body>
<div id="app">
  <lk-count></lk-count>
  <cc-count></cc-count>
</div>

<script src="../js/vue.js"></script>
<script>
  // 注冊一個局部組件
  const Counter = {
    data() {
      return {
        count: 0
      }
    },
    template: `
        <button @click="count++">你點擊了{{count}}次</button>`
  }
  // 注冊第二個局部組件
  const Box = {
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子組件
        </div> `
  }
  // 創(chuàng)建Vue的實例對象
  const app = Vue.createApp({
    data(){
      return {
        msg: '你好,Vue3!'
      }
    },
    // 組件選項
    components: {
      'lk-count': Counter,
      'cc-count': Box
    }
  });
  // 掛載vue實例
  app.mount('#app');
</script>
</body>

3. 注意事項

1. data必須是一個函數(shù)

2. 組件模板內(nèi)容必須是單個跟元素

3. 組件模板內(nèi)容可以是模板字符串(需要瀏覽器提供ES6語法支持)

4. 組件命名方式

  • 短橫線方式:
Vue.component('my-component', { /* ... */ })
  • 駝峰方式:
Vue.component('MyComponent', { /* ... */ })

4.總結(jié)

  • 全局組件:在整個Vue實例中都可以被調(diào)用,若想要全局組件之間相互使用,只需將想使用全局組件的名稱寫入 template

  • 局部組件:只能在當前組件中被使用,若想在其他組件中使用,必須使用 components 將其掛載在想使用的組件中,然后再如全局組件那樣向模板template寫入名稱標簽

  • 我們之后其實對局部組件用的更多一些。

三、組件數(shù)據(jù)存放

Data屬性的值是一個函數(shù)??

  • 為什么data在組件中必須是一個函數(shù)呢?
    • 當然,如果不是一個函數(shù),Vue直接就會報錯。
    • 組件是可復用的vue實例,一個組件被創(chuàng)建好之后,就可能被用在各個地方
    • 而組件不管被復用了多少次,組件中的data數(shù)據(jù)都應(yīng)該是相互隔離,互不影響的
    • 基于這一理念,組件每復用一次,data數(shù)據(jù)就應(yīng)該被復制一次,之后,當某一處復用的地方組件內(nèi)data數(shù)據(jù)被改變時,其他復用地方組件的data數(shù)據(jù)不受影響
    • 組件中的data寫成一個函數(shù),數(shù)據(jù)以函數(shù)返回值形式定義,這樣每復用一次組件,就會返回一份新的data,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間,讓各個組件實例維護各自的數(shù)據(jù)
    • 而單純的寫成對象形式,就使得所有組件實例共用了一份data,就會造成一個變了全都會變的結(jié)果

四、組件之間數(shù)據(jù)的交互共享

4.1 父組件向子組件傳值??

1. 組件內(nèi)部通過props接收傳遞過來的值

Vue.component(‘menu-item', {
    props: ['title'],
    template: '<div>{{ title }}</div>'
})

2. 父組件通過屬性將值傳遞給子組件

<menu-item title="來自父組件的數(shù)據(jù)"></menu-item>
<menu-item :title="title"></menu-item>

3. props屬性名規(guī)則

  • 在props中使用駝峰形式,模板中需要使用短橫線的形式
  • 字符串形式的模板中沒有這個限制
Vue.component(‘menu-item', {
    // 在 JavaScript 中是駝峰式的
    props: [‘menuTitle'],
    template: '<div>{{ menuTitle }}</div>'
})
<!– 在html中是短橫線方式的 -->
<menu-item menu-title=“nihao"></menu-item>

4. props屬性值類型

  • 字符串 String
  • 數(shù)值 Number
  • 布爾值 Boolean
  • 數(shù)組 Array
  • 對象 Object

4.2 子組件向父組件傳值??

1. 子組件通過自定義事件向父組件傳遞信息

<button v-on:click='$emit("enlarge-text") '>擴大字體</button>

2. 父組件監(jiān)聽子組件的事件

<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>

3. 子組件通過自定義事件向父組件傳遞信息

<button v-on:click='$emit("enlarge-text", 0.1) '>擴大字體</button>

4. 父組件監(jiān)聽子組件的事件

<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>

4.3 非父子組件間傳值??

1. 單獨的事件中心管理組件間的通信

var eventHub = new Vue()

2. 監(jiān)聽事件與銷毀事件

eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')

3. 觸發(fā)事件

eventHub.$emit(‘a(chǎn)dd-todo', id)

五、組件插槽

5.1 組件插槽的作用

  • 插槽就是子組件中的提供給父組件使用的一個占位符,用<slot></slot> 表示,父組件可以在這個占位符中填充任何模板代碼,如 HTML、組件等,填充的內(nèi)容會替換子組件的<slot></slot>標簽。

  • 父組件向子組件傳遞內(nèi)容

5.2 組件插槽基本用法

//插槽的使用
<div id="app">
    <alert-box>有bug發(fā)生</alert-box>
    <alert-box>有一個警告</alert-box>
    <alert-box></alert-box>
</div>
//插槽的定義
Vue.component('alert-box', {
      template: `
        <div>
          <strong>ERROR:</strong>
          <slot>默認內(nèi)容</slot>
        </div>`
});

5.3 具名插槽用法

//具名插槽的使用
<div id="app">
    //第一種:當具名插槽內(nèi)只有1個標簽
    <base-layout>
      <p slot='header'>標題信息</p>
      <p>主要內(nèi)容1</p>
      <p>主要內(nèi)容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>
    
    //第二種:當具名插槽內(nèi)需要填充多個標簽
    <base-layout>
      <template slot='header'>
        <p>標題信息1</p>
        <p>標題信息2</p>
      </template>
      <p>主要內(nèi)容1</p>
      <p>主要內(nèi)容2</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>
    </base-layout>
</div>

//具名插槽的定義
Vue.component('base-layout', {
      template: `
        <div>
          <header>
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name='footer'></slot>
          </footer>
        </div>`
});

5.4 作用域插槽

//作用域插槽的使用
<fruit-list v-bind:list= "list">
    <template slot-scope="slotProps">
        <strong v-if="slotProps.item.current">
            {{ slotProps.item.text }}
        </strong>
    </template>
</fruit-list>

//作用域插槽的定義
<ul>
    <li v-for= "item in list" v-bind:key= "item.id" >
        <slot v-bind:item="item">
            {{item.name}}
        </slot>
    </li>
</ul>
?著作權(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)容

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