1. 程式人生 > >vue學習十(prop傳參、v-bind傳參、$emit向父級傳送訊息、input元件上使用 v-model、事件拋值)

vue學習十(prop傳參、v-bind傳參、$emit向父級傳送訊息、input元件上使用 v-model、事件拋值)

基本示例

元件是可複用的 Vue 例項,且帶有一個名字:在這個例子中是 。我們可以在一個通過 new Vue 建立的 Vue 根例項中,把這個元件作為自定義元素來使用

 <div id="components-demo">
        <button-counter></button-counter>
    </div>

    <script>

        Vue.component('button-counter', {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
        })

        new Vue({
            el: "#components-demo"
        })
    </script>

效果如下,點選按鈕,會顯示點選的總次數

You clicked me 5 times.

元件的複用

你可以將元件進行任意次數的複用:

<div id="components-demo">
        <button-counter></button-counter>
        <button-counter></button-counter>
        <button-counter></button-counter>
    </div>

注意當點選按鈕時,每個元件都會各自獨立維護它的 count。因為你每用一次元件,就會有一個它的新例項被建立。 一個元件的 data 選項必須是一個函式,因此每個例項可以維護一份被返回物件的獨立的拷貝:

如果 Vue 沒有這條規則,點選一個按鈕就可能會影響到其它所有例項:

通過 Prop 向子元件傳遞資料

Prop 是你可以在元件上註冊的一些自定義特性。當一個值傳遞給一個 prop 特性的時候,它就變成了那個元件例項的一個屬性。為了給博文元件傳遞一個標題,我們可以用一個 props 選項將其包含在該元件可接受的 prop 列表中:

    <div id="div11">
        <blog-post title="My journey with Vue"></blog-post>
        <blog-post title="Blogging with Vue"></blog-post>
        <blog-post title="Why Vue is so fun"></blog-post>
    </div>
    <script>
        Vue.component('blog-post', {
            props: ['title'],
            template: '<h3>{{ title }}</h3>'
        })
        new Vue({
            el: "#div11"
        })
    </script>

輸出如下:

My journey with Vue
Blogging with Vue
Why Vue is so fun

v-bind 來動態傳遞 prop

你會發現我們可以使用 v-bind 來動態傳遞 prop


    <div id="div12">
        <blog-post v-for="post in posts" v-bind:key="post.id" v-bind:title="post.title"></blog-post>
    </div>
    <script>
        Vue.component('blog-post', {
            props: ['title'],
            template: '<h3>{{ title }}</h3>'
        })
        new Vue({
            el: "#div12",
            data: {
                posts: [
                    { id: 1, title: 'My journey with Vue' },
                    { id: 2, title: 'Blogging with Vue' },
                    { id: 3, title: 'Why Vue is so fun' }
                ]
            }
        })
    </script>

渲染效果如下:

My journey with Vue
Blogging with Vue
Why Vue is so fun

通過 $emit 事件向父級元件傳送訊息

我們可以呼叫內建的 $emit 方法並傳入事件的名字,來向父級元件觸發一個事件:

  <div id="blog-posts-events-demo">
        <div :style="{ fontSize: postFontSize + 'em' }">
            <blog-post v-for="post in posts" v-bind:key="post.id" 
            v-bind:post="post" v-on:enlarge-text="postFontSize += 0.1"></blog-post>
        </div>
    </div>


    <script>
        Vue.component('blog-post', {
            props: ['post'],
            template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <button v-on:click="$emit('enlarge-text')">
  Enlarge text
</button>
      <div v-html="post.content"></div>
    </div>`
        })
        
        new Vue({
            el: '#blog-posts-events-demo',
            data: {
                posts: [
                    { id: 1, title: 'My journey with Vue' },
                    { id: 2, title: 'Blogging with Vue' },
                    { id: 3, title: 'Why Vue is so fun' }
                ],
                postFontSize: 1
            }
        })

    </script>

效果圖如下: 在這裡插入圖片描述

使用事件丟擲一個值

有的時候用一個事件來丟擲一個特定的值是非常有用的。例如我們可能想讓 元件決定它的文字要放大多少。這時可以使用 $emit 的第二個引數來提供這個值:

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

然後當在父級元件監聽這個事件的時候,我們可以通過 $event 訪問到被丟擲的這個值

<blog-post
  ...
  v-on:enlarge-text="postFontSize += $event"
></blog-post>

如果這個事件處理函式是一個方法

<blog-post
  ...
  v-on:enlarge-text="onEnlargeText"
></blog-post>

那麼這個值將會作為第一個引數傳入這個方法:

new Vue({
            el: '#blog-posts-events-demo',
            data: {
                posts: [
                    { id: 1, title: 'My journey with Vue' },
                    { id: 2, title: 'Blogging with Vue' },
                    { id: 3, title: 'Why Vue is so fun' }
                ],
                postFontSize: 1
            },
            methods: {
                onEnlargeText: function (enlargeAmount) {
                    this.postFontSize += enlargeAmount
                }
            }
        })

在元件上使用 v-model

<input v-model="searchText">

等價於

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

當用在元件上時,v-model 則會這樣:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

為了讓它正常工作,這個元件內的 必須:

將其 value 特性繫結到一個名叫 value 的 prop 上 在其 input 事件被觸發時,將新的值通過自定義的 input 事件丟擲

<div id="lll">
        <custom-input v-model="searchText"></custom-input>
        <span>{{searchText}}</span>
    </div>



    <script>


        Vue.component('custom-input', {
            props: ['value'],
            template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
        })
        new Vue({
            el: "#lll",
            data: { searchText: "" }
        })

    </script>

效果如下: 在這裡插入圖片描述