1. 程式人生 > 其它 >Vue中的元件

Vue中的元件

技術標籤:vuevue

Vue元件化

元件的使用步驟

呼叫Vue.extend()建立一個元件構造器,在建立構造器時傳入需要使用的template模板即HTML複用的程式碼。然後呼叫Vue.component()將元件構造器註冊為一個元件,並給元件取一個標籤名稱。使用元件的標籤名在掛載的Vue例項元素下使用即可。

  1. 建立元件構造器物件

    //1.建立元件構造器物件
    const cpnC = Vue.extend({
      template: `<div>
                    <h2>元件標題</h2>
                    <p>元件內容</p>
                 </div>`
    })
  2. 註冊元件

    //2.註冊元件
    Vue.component('my-component', cpnC)
    
  3. 使用元件

    <div id="app">
      <my-component></my-component>
    </div>
    

效果截圖:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-8d9QgklX-1608995452504)(C:%5CUsers%5C13536%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20201226182053795.png)]


全域性元件

全域性元件可以在多個Vue例項中使用,通過Vue.component()註冊的元件為全域性元件


區域性元件

在Vue例項中註冊的元件為區域性元件,只能在註冊的例項中進行使用,使用components來註冊元件

const cpnC = Vue.extend({
    template: `<div>
                  <h2>元件標題</h2>
                  <p>元件內容</p>
               </div>`
  })

const app =
new Vue({ el: '#app', components: { //元件名: 元件構造器名 cpn: cpnC } })

父子元件

如果想在元件中使用其它的元件,這兩個元件就為父子關係。先建立子元件,然後再建立父元件,在父元件中使用compoents註冊子元件就可以在template中使用子元件

<div id="app">
  <cpn-father></cpn-father>
</div>

<script src="../js/vue.js"></script>
<script>
  //子元件
  const cpnChild = Vue.extend({
    template: `<div><h1>子元件標題</h1><p>子元件內容</p></div>`
  })

  //父元件
  const cpnFather = Vue.extend({
    //在父模板中使用子元件
    template: `<div>
                <h1>父元件標題</h1>
                <p>父元件內容</p>
                <cpn-child></cpn-child>
               </div>`,
    //在父元件中註冊子元件
    components: {
      cpnChild
    }
  })

  const app = new Vue({
    el: '#app',
    components: {
      //註冊父元件
      cpnFather
    }
  })
</script>

效果


註冊元件的語法糖

// 全域性元件註冊語法糖
Vue.component('cpn', {
  template: `<div><h1>元件標題</h1></div>`
})

//區域性元件註冊語法糖
const app = new Vue({
    el: '#app',
    components: {
      cpn: {
        template: `<div><h1>元件標題</h1></div>`
      }
    }
  })

元件模板的抽離

使用<template>標籤並指定id進行對模板的抽離,註冊元件時通過id指定模板

<template id="myCpn">
  <div>
    <h1>元件標題</h1>
    <p>元件內容</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    components: {
      myCpn: {
        //通過id指定模板
        template: '#myCpn'
      }
    }
  })

元件中的資料

如果想要在元件中存放資料,應該使用data()函式精選儲存,而不是data屬性,讓元件建立時保證資料的封閉。

<template id="myTemplate">
  <div>
    <h1>{{title}}</h1>
    <p>{{content}}</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    components: {
      myCpn: {
        template: '#myTemplate',
        //在元件中使用data()函式存放資料
        data() {
          return {
            title: "元件標題",
            content: "元件內容"
          }
        }
      }
    }
  })
</script>

元件的通訊

父子元件通訊需要使用兩種方法,一個是使用props向子元件傳遞資料,另一個是通過事件向父元件傳送訊息。

父子元件的通訊

父傳子props

在子元件中使用props宣告需要的變數,在使用元件時使用v-bind對引數進行繫結

<div id="app">
  <!-- 通過v-bind將父元件與子元件中的變數進行繫結 -->
  <cpn v-bind:c-message="message" :c-movies="movies"></cpn>
</div>

<!-- 子元件模板 -->
<template id="myTemplate">
  <div>
    <h1>{{cMessage}}</h1>
    <ul>
      <li v-for="item in cMovies">{{item}}</li>
    </ul>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  //子元件
  const cpn = {
    template: '#myTemplate',
    //父傳子宣告變數
    props: ['cMovies', 'cMessage']
  }

  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js',
      movies: ["《信條》", "《你的名字》", "《讓子彈飛》", "《阿甘正傳》", "《盜夢空間》"]
    },
    //註冊子元件
    components: {
      cpn
    }
  })
</script>

props中可以使用陣列進行對變數的宣告,也可以使用物件的形式對資料進行限制或預設值。

注意:陣列型別或物件型別的預設值必須是一個default()函式

props: {
      cMessage: {
        //型別
        type: String,
        //預設值
        default: "暫無資料",
        //必須傳遞,否則報錯
        required: true
      },
      cMovies: {
        type: Array,
        //default函式指定預設值
        default() {
          return ['暫無資料']
        },
        required: true
      }
    }

子傳父$emit Events

子元件通過this.$emit('name', parms)傳送自定義事件,父元件通過v-on監聽子元件傳送的自定義事件來實現子元件向父元件通訊的過程。

<div id="app">
  <!-- 監聽子元件傳送的事件 -->
  <cpn @item-click="cpnClick"></cpn>
</div>

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

<script src="../js/vue.js"></script>
<script>

  //子元件
  const cpn = {
    template: '#myTemplate',
    methods: {
      btnClick(item) {
        //傳送自定義事件
        this.$emit('item-click', item);
      }
    },
    data() {
      return {
        categories: [
          {id: '001', name: "熱門推薦"},
          {id: '002', name: "手機數碼"},
          {id: '003', name: "家用家電"},
          {id: '004', name: "電腦辦公"},
        ]
      }
    }
  }

  const app = new Vue({
    el: '#app',
    methods: {
      cpnClick(item) {
        alert("你選擇了:" + item.name);
      }
    },
    //註冊子元件
    components: {
      cpn
    }
  })
</script>

父子元件雙向繫結

實際上是通過子元件向父元件傳送事件進而修改父元件中data中的資料

<div id="app">
  <h1>父元件</h1>
  <p>num:{{num}}</p>
  <p>msg:{{msg}}</p>
  <hr>
  <!-- 繫結資料 並且 監聽事件 -->
  <cpn :message="msg"
       @message-change="msgChange"></cpn>
</div>

<template id="myTemplate">
  <div>
    <h1>子元件</h1>
    <p>message:{{dataMessage}}</p>
    <input type="text" :value="dataMessage" @input="messageInput">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      msg: "Hello world"
    },
    methods: {
      msgChange(value) {
        this.count = value;
      }
    },
    //子元件
    components: {
      cpn: {
        template: '#myTemplate',
        //父元件傳輸資料
        props: {
          message: String
        },
        //儲存資料
        data() {
          return {
            dataMessage: this.message
          }
        },
        //事件
        methods: {
          messageInput(event) {
            //子元件的雙向繫結
            this.dataMessage = event.target.value;
            //向父元件傳送資料
            this.$emit('message-change', this.dataMessage);
          }
        }
      }
    }
  })
</script>

父子元件的直接獲取

直接獲取即在父元件或子元件中直接獲取到子元件或父元件的物件,進而訪問起屬性和方法。

父元件獲取子元件

父元件可使用$children$refs獲取子元件。

this.$children是一個數組,它包含了當前元件下所有的子元件,可通過遍歷的形式獲取需要的子元件。

this.$refs是一個子元件物件,需要指定元件的ref,通過$refs.xxx獲取對應的元件,從而不需要遍歷

<div id="app">
  <cpn></cpn>
  <button @click="btnClick">訪問子元件</button>
</div>

<template id="myTemplate">
  <div>
    <h1>子元件</h1>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    methods: {
      btnClick() {
        //訪問子元件的showMessage的方法
        this.$children[0].showMessage();
      }
    },
    //註冊子元件
    components: {
      cpn: {
        template: '#myTemplate',
        data() {
          return{
            message: "Hello Vue.js"
          }
        },
        methods: {
          showMessage() {
            alert(this.message);
          }
        }
      }
    }
  })
</script>

使用refs

<cpn ref="cpn"></cpn>

呼叫形式

this.$refs.cpn.showMessage();

子元件獲取父元件

子元件可以使用$parent獲取父元件。

<body>
<div id="app">
  <cpn></cpn>
</div>

<template id="myTemplate">
  <div>
    <h1>子元件</h1>
    <button @click="btnClick">訪問父元件</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js'
    },
    //註冊子元件
    components: {
      cpn: {
        template: '#myTemplate',
        methods: {
          btnClick() {
            //訪問父元件
            alert(this.$parent.message);
          }
        }
      }
    }
  })
</script>