1. 程式人生 > 其它 >Vue—04—元件化;

Vue—04—元件化;


一、元件化

1、介紹

2、註冊元件的三個步驟

3、全域性元件和區域性元件

全域性元件使用vue類的component方法建立;這個時候這個元件將可以在所有的vue例項下使用;

區域性元件在建立某個vue例項的時候新增component屬性建立,那麼這個元件就只能在這個vue例項下使用;

4、父元件和子元件

說白了就是搞兩個元件構造器,在某個元件構造器a裡註冊另外一個元件b,另外一個元件b就變成了a的子元件,然後就可以在a元件構造器中的template屬性中使用了;當然b既是子元件又是區域性元件;

new Vue也是一種元件,可以看作是元件樹的root元件;

區域性元件一定是子元件,反之不一定;

5、註冊元件的語法糖形式

註冊全域性元件:

註冊區域性元件:

6、模板抽離

主要是通過type為text/x-template的script標籤或者使用《template》標籤來定義內容;

二、元件的data屬性為什麼是函式而不是物件

每一個元件例項都要有自己的狀態;

所以元件裡的data屬性應該是函式,而不能是物件;

如果是函式,每一個元件在註冊的時候,都會有一個單獨的data初始狀態(單獨地址),不會受其他元件影響;

如果是物件,則可能大家的data的地址都是指向同一個,這個時候就會收到其他組建的影響;

三、父元件通訊到子元件

1、介紹

  • 你在div裡用我的cpn子元件的時候,可以通過v-bind來繫結並向子元件的props屬性的值傳遞資料;傳遞過去後,子元件的template屬性的內容就可以使用了本元件的props的資料了,也就使用了父元件的資料;
  • 子元件都有模板template屬性,其實root元件也有,只不過root元件的模板在例項外面(子元件模板和父元件模板);既然外部的div標籤也是root元件的一部分,那麼在div標籤中使用子元件是可以通過v-bind的方式向子元件傳值的;
  • 子元件props可以使用物件或者陣列兩種方式,如果使用物件,可以驗證傳過來的值的資料型別還可以要求是否這個屬性必穿等功能,建議使用這種方式而不是陣列;

2、實操

<body>
    <div id=app>
        <ccpn :c-msg='msg' :c-msg-array='msgArray'></ccpn>
    </div>

    <template id=ccpn>
        <div>
            <h2>自己的資料:{{myMessage}}</h2>
            <h5>父元件的資料:{{cMsg}}</h5>
            <ul  v-for
='item in cMsgArray'> <li>父元件陣列的資料:{{item}}</li> </ul> </div> </template> <script src=..\node_modules\vue\dist\vue.js></script> <script> const app = new Vue({ el:'#app', data:{ msg:'you are so niubai', msgArray:['haiwang','haierxiongdi'], }, components:{ 'ccpn':{ template:'#ccpn', props:{ cMsg:{ type:String, Requied:true, default(){ return ''; } }, cMsgArray:{ type:Array, requied:true, default: function(){ return []; }, } }, data(){ return { myMessage:'這個是子元件的值', } } } } }) </script>

3、駝峰標識

注意在父元件《div》標籤中使用子元件標籤《ccpn》時,,如果想 傳值到子元件,在使用

<ccpn :c-msg='msg' :c-msg-array='msgArray'></ccpn>

時我們可以看到,cMsg駝峰標識不起作用,要使用c-msg,目前的vue版本確實這樣,後期的vue版本不知道會不會支援;

四、子元件通訊到父元件

<body>
    <!-- 父元件模板 -->
    <div id=app>
        <ccpn v-on:clickevent="resolve($event)"></ccpn>
    </div>

    <!-- 子元件模板 -->
    <template id=ccpn>
        <div>
            <h2>自己的資料:{{myMessage}}</h2>
            <h5>父元件的資料:{{cMsg}}</h5>
            <ul  v-for='item in cMsgArray'>
                <button @click='sendToParent(item)'>{{item}}</button>
            </ul>
        </div>
    </template>


    <script src=..\node_modules\vue\dist\vue.js></script>
    <script>
        //父元件(root元件)例項
        const app = new Vue({
            el:'#app',
            methods:{
                resolve(event){
                    console.log(event);
                    console.log(`我收到了子元件的訊息,內容是${event}`);
                }
            },
            components:{
                ccpn,                    
            },
        })

         //子元件例項
        const ccpn = {
            template:'#ccpn',
            props:{
                cMsg:{
                    type:String,
                    Requied:true,
                    default(){
                        return '';
                    }
                },
                cMsgArray:{
                    type:Array,
                    requied:true,
                    default: function(){
                        return ['科技數碼','美食飲料'];
                    },
                }
            },
            data(){
                return {
                    myMessage:'這個是子元件的值',
                }
            },
            methods:{
                sendToParent(item){
                    console.log(item);
                    this.$emit('clickevent',item);
                },
            }
        }
        
    </script>
    

注意,父元件模板的resolve方法中會有一個預設監聽事件引數——$event物件,這個event物件在子父元件通訊時就是子元件例項sendToParent方法傳的item值;

五、父子元件的訪問

父子元件除了可以通訊即傳送資料外,還可以訪問他們的屬性;

1、父元件訪問子元件

有兩種方式,分別是this.$children或者this.$refs;

this.$children會放回一個數組,所以取某個子元件元素時需要用到下標比較麻煩,除非要取出所有的子元件元素,不然建議用第二個this.$refs,這個會在父元件模板中的每個<cpn>標籤中加一個ref屬性,比如

<cpn ref='aaa'></cpn>

這樣的話就可以在父元件例項中,使用this.$refs.關鍵名取呼叫這個專門的子元件;

2、子元件訪問父元件

開發時不建議使用$parent,為什麼呢?因為子元件最重要的是可高複用,如果你在這個子元件中使用$parent訪問某個父元件成功了,可是你這個子元件在下一個專案複用的時候,可能沒有父元件了,這個時候程式碼中還有$parent就會報錯;這樣的話子元件和父元件的耦合度就太高了;

3、子元件訪問root元件

使用$root訪問,但是用的都很少;