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ù)都應該是相互隔離逾礁,互不影響的
    • 基于這一理念,組件每復用一次访惜,data數(shù)據(jù)就應該被復制一次嘹履,之后,當某一處復用的地方組件內(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)系作者
  • 序言:七十年代末纱意,一起剝皮案震驚了整個濱河市婶溯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偷霉,老刑警劉巖迄委,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異类少,居然都是意外死亡叙身,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門硫狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來信轿,“玉大人,你說我怎么就攤上這事残吩〔坪觯” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵泣侮,是天一觀的道長即彪。 經(jīng)常有香客問我,道長旁瘫,這世上最難降的妖魔是什么祖凫? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮酬凳,結(jié)果婚禮上惠况,老公的妹妹穿的比我還像新娘。我一直安慰自己宁仔,他們只是感情好稠屠,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翎苫,像睡著了一般权埠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上煎谍,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天攘蔽,我揣著相機與錄音,去河邊找鬼呐粘。 笑死满俗,一個胖子當著我的面吹牛转捕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唆垃,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼五芝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辕万?” 一聲冷哼從身側(cè)響起枢步,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渐尿,沒想到半個月后醉途,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡涡戳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年结蟋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渔彰。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡嵌屎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恍涂,到底是詐尸還是另有隱情宝惰,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布再沧,位于F島的核電站尼夺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炒瘸。R本人自食惡果不足惜淤堵,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顷扩。 院中可真熱鬧拐邪,春花似錦、人聲如沸隘截。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婶芭。三九已至东臀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犀农,已是汗流浹背惰赋。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呵哨,地道東北人赁濒。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓贵扰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親流部。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容