Vue-組件

定義Vue組件

什么是組件: 組件的出現(xiàn),就是為了拆分Vue實(shí)例的代碼量的钱反,能夠讓我們以不同的組件,來(lái)劃分不同的功能模塊,將來(lái)我們需要什么樣的功能面哥,就可以去調(diào)用對(duì)應(yīng)的組件即可乙各; 組件化和模塊化的不同:

  • 模塊化: 是從代碼邏輯的角度進(jìn)行劃分的;方便代碼分層開(kāi)發(fā)幢竹,保證每個(gè)功能模塊的職能單一耳峦;

  • 組件化: 是從UI界面的角度進(jìn)行劃分的;前端的組件化焕毫,方便UI組件的重用蹲坷;

    全局組件定義的三種方式

    1. 使用 Vue.extend 配合 Vue.component 方法:

      var login = Vue.extend({
        template: '<h1>登錄</h1>'
      });
      Vue.component('login', login);
      
    2. 直接使用 Vue.component 方法:

      Vue.component('register', {
           template: '<h1>注冊(cè)</h1>'
      });
      
    3. 將模板字符串,定義到script標(biāo)簽種:

      <script id="tmpl" type="x-template">
        <div>
          <a href="#">登錄</a> |
           <a href="#">注冊(cè)</a>
        </div>
      </script>
      

      同時(shí)邑飒,需要使用 Vue.component 來(lái)定義組件:

      Vue.component('account', {
      template: '#tmpl'
      });
      

注意: 組件中的DOM結(jié)構(gòu)循签,有且只能有唯一的根元素(Root Element)來(lái)進(jìn)行包裹!

組件中展示數(shù)據(jù)和響應(yīng)事件

  1. 在組件中疙咸,data需要被定義為一個(gè)方法县匠,例如:

    Vue.component('account', {
       template: '#tmpl',
       data() {
         return {
           msg: '大家好!'
         }
       },
       methods:{
         login(){
           alert('點(diǎn)擊了登錄按鈕');
         }
       }
     });
    

【重點(diǎn)】為什么組件中的data屬性必須定義為一個(gè)方法并返回一個(gè)對(duì)象

  • 組件可以有自己的data數(shù)據(jù)
  • 組件的data和實(shí)例的data有點(diǎn)不一樣撒轮, 實(shí)例中的data 可以為一個(gè)對(duì)象,但是組件中的data必須是一個(gè)方法
  • 組件中的data除了必須為一個(gè)方法之外乞旦, 這個(gè)方法內(nèi)部,還必須返回一個(gè)對(duì)象才行;
  • 組件中的data數(shù)據(jù),使用方式题山,和實(shí)例中的data使用方式完全樣!! !
  • 不同組件之間的數(shù)據(jù)不相互影響兰粉,所以data定義為方法
  1. 在子組件中,如果將模板字符串顶瞳,定義到了script標(biāo)簽中玖姑,那么,要訪問(wèn)子組件身上的data屬性中的值慨菱,需要使用this來(lái)訪問(wèn)焰络;

使用components屬性定義局部子組件

  1. 組件實(shí)例定義方式:

    <script>
     // 創(chuàng)建 Vue 實(shí)例,得到 ViewModel
     var vm = new Vue({
       el: '#app',
       data: {},
       methods: {},
       components: { // 定義子組件
         account: { // account 組件
           template: '<div><h1>這是Account組件{{name}}</h1><login></login></div>', // 在這里使用定義的子組件
           components: { // 定義子組件的子組件
             login: { // login 組件
               template: "<h3>這是登錄組件</h3>"
             }
           }
         }
       }
     });
    </script>
    
  2. 引用組件:

    <div id="app">
         <account></account>
    </div>
    

使用flag標(biāo)識(shí)符結(jié)合v-ifv-else切換組件

  1. 頁(yè)面結(jié)構(gòu):

    <div id="app">
     <input type="button" value="toggle" @click="flag=!flag">
     <my-com1 v-if="flag"></my-com1>
     <my-com2 v-else="flag"></my-com2>
    </div>
    
  2. Vue實(shí)例定義:

    <script>
     Vue.component('myCom1', {
       template: '<h3>奔波霸</h3>'
     })
    
     Vue.component('myCom2', {
       template: '<h3>霸波奔</h3>'
     })
    
     // 創(chuàng)建 Vue 實(shí)例符喝,得到 ViewModel
     var vm = new Vue({
       el: '#app',
       data: {
         flag: true
       },
       methods: {}
     });
    </script>
    

使用:is屬性來(lái)切換不同的子組件

  1. 組件實(shí)例定義方式:

    // 登錄組件
     const login = Vue.extend({
       template:
       `<div>
           <h3>登錄組件</h3>
       </div>`
     });
     Vue.component('login', login);
    
     // 注冊(cè)組件
     const register = Vue.extend({
       template: `<div>
         <h3>注冊(cè)組件</h3>
       </div>`
     });
     Vue.component('register', register);
    
     // 創(chuàng)建 Vue 實(shí)例闪彼,得到 ViewModel
     var vm = new Vue({
       el: '#app',
       data: { comName: 'login' },
       methods: {}
     });
    
  2. 使用component標(biāo)簽,來(lái)引用組件洲劣,并通過(guò):is屬性來(lái)指定要加載的組件:

    <div id="app">
     <a href="#" @click.prevent="comName='login'">登錄</a>
     <a href="#" @click.prevent="comName='register'">注冊(cè)</a>
     <hr>
     <transition mode="out-in">
       <component :is="comName"></component>
     </transition>
    </div>
    
  3. 添加切換樣式:

    <style>
     .v-enter,
     .v-leave-to {
       opacity: 0;
       transform: translateX(30px);
     }
    
     .v-enter-active,
     .v-leave-active {
       position: absolute;
       transition: all 0.3s ease;
     }
    
     h3{
       margin: 0;
     }
    </style>
    

父組件向子組件傳值

  1. 組件實(shí)例定義方式备蚓,注意:一定要使用props屬性來(lái)定義父組件傳遞過(guò)來(lái)的數(shù)據(jù)

    <script>
     // 創(chuàng)建 Vue 實(shí)例课蔬,得到 ViewModel
     var vm = new Vue({
       el: '#app',
       data: {
         msg: '這是父組件中的消息'
       },
       components: {
         son: {
           template: '<h1>這是子組件 --- {{finfo}}</h1>',
           props: ['finfo']
         }
       }
     });
    </script>
    
  2. 使用v-bind或簡(jiǎn)化指令囱稽,將數(shù)據(jù)傳遞到子組件中:

    <div id="app">
     <son :finfo="msg"></son>
    </div>
    

子組件向父組件傳值

  1. 原理:父組件將方法的引用,傳遞到子組件內(nèi)部二跋,子組件在內(nèi)部調(diào)用父組件傳遞過(guò)來(lái)的方法战惊,同時(shí)把要發(fā)送給父組件的數(shù)據(jù),在調(diào)用方法的時(shí)候當(dāng)作參數(shù)傳遞進(jìn)去扎即;

  2. 父組件將方法的引用傳遞給子組件吞获,其中况凉,getMsg是父組件中methods中定義的方法名稱,func是子組件調(diào)用傳遞過(guò)來(lái)方法時(shí)候的方法名稱

    <son @func="getMsg"></son>
    
  3. 子組件內(nèi)部通過(guò)this.$emit('方法名', 要傳遞的數(shù)據(jù))方式各拷,來(lái)調(diào)用父組件中的方法刁绒,同時(shí)把數(shù)據(jù)傳遞給父組件使用

    <div id="app">
     <!-- 引用父組件 -->
     <son @func="getMsg"></son>
    
     <!-- 組件模板定義 -->
     <script type="x-template" id="son">
       <div>
         <input type="button" value="向父組件傳值" @click="sendMsg" />
       </div>
     </script>
    </div>
    
    <script>
     // 子組件的定義方式
     Vue.component('son', {
       template: '#son', // 組件模板Id
       methods: {
         sendMsg() { // 按鈕的點(diǎn)擊事件
           this.$emit('func', 'OK'); // 調(diào)用父組件傳遞過(guò)來(lái)的方法,同時(shí)把數(shù)據(jù)傳遞出去
         }
       }
     });
    
     // 創(chuàng)建 Vue 實(shí)例烤黍,得到 ViewModel
     var vm = new Vue({
       el: '#app',
       data: {},
       methods: {
         getMsg(val){ // 子組件中知市,通過(guò) this.$emit() 實(shí)際調(diào)用的方法,在此進(jìn)行定義
           alert(val);
         }
       }
     });
    </script>
    

評(píng)論列表案例

目標(biāo):主要練習(xí)父子組件之間傳值

使用 this.$refs 來(lái)獲取DOM元素和組件引用

  <div id="app">
    <div>
      <input type="button" value="獲取元素內(nèi)容" @click="getElement" />
      <!-- 使用 ref 獲取元素 -->
      <h1 ref="myh1">這是一個(gè)大大的H1</h1>

      <hr>
      <!-- 使用 ref 獲取子組件 -->
      <my-com ref="mycom"></my-com>
    </div>
  </div>

  <script>
    Vue.component('my-com', {
      template: '<h5>這是一個(gè)子組件</h5>',
      data() {
        return {
          name: '子組件'
        }
      }
    });

    // 創(chuàng)建 Vue 實(shí)例速蕊,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getElement() {
          // 通過(guò) this.$refs 來(lái)獲取元素
          console.log(this.$refs.myh1.innerText);
          // 通過(guò) this.$refs 來(lái)獲取組件的數(shù)據(jù)和方法
          console.log(this.$refs.mycom.name);
        }
      }
    });
  </script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嫂丙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子规哲,更是在濱河造成了極大的恐慌跟啤,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唉锌,死亡現(xiàn)場(chǎng)離奇詭異隅肥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)袄简,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門武福,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人痘番,你說(shuō)我怎么就攤上這事捉片。” “怎么了汞舱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵伍纫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我昂芜,道長(zhǎng)莹规,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任泌神,我火速辦了婚禮良漱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘欢际。我一直安慰自己母市,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布损趋。 她就那樣靜靜地躺著患久,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒋失,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天返帕,我揣著相機(jī)與錄音,去河邊找鬼篙挽。 笑死荆萤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铣卡。 我是一名探鬼主播观腊,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼算行!你這毒婦竟也來(lái)了梧油?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤州邢,失蹤者是張志新(化名)和其女友劉穎儡陨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體量淌,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骗村,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了呀枢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胚股。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖裙秋,靈堂內(nèi)的尸體忽然破棺而出琅拌,到底是詐尸還是另有隱情,我是刑警寧澤摘刑,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布进宝,位于F島的核電站,受9級(jí)特大地震影響枷恕,放射性物質(zhì)發(fā)生泄漏党晋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一徐块、第九天 我趴在偏房一處隱蔽的房頂上張望未玻。 院中可真熱鬧,春花似錦胡控、人聲如沸扳剿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舞终。三九已至轻庆,卻和暖如春癣猾,著一層夾襖步出監(jiān)牢的瞬間敛劝,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工纷宇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夸盟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓像捶,卻偏偏與公主長(zhǎng)得像上陕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拓春,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348