vue(生命周期,鈎子方法,組件)


VUE實例的生命周期和VUE提供的鈎子方法

鈎子方法就是事先給你准備好的方法,但是需要你自己實現

盜官方的圖,真香!

 

 紅色框子里的英文就代表我們可以使用鈎子方法的方法名

注意事項:

不要在選項屬性或回調上使用箭頭函數,比如 created: () => console.log(this.a) 或 vm.$watch('a', newValue => this.myMethod())。因為箭頭函數並沒有 thisthis會作為變量一直向上級詞法作用域查找,直至找到為止,經常導致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之類的錯誤。

    new Vue({
        el:"#app",
        data:{},
        methods:{},
        created:function(){
            console.log("執行created方法")
        },
        mounted:function(){
            console.log("執行mounted方法")
        }
    })

 

 組件

組件是可以復用的VUE實例

組件的命名規范,單詞首字母大寫(例如ButtonCounter)或者全小寫使用連接線(例如button-counter)

最簡單的使用方法,注釋解決了一個坑

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>
<script>

    //定義一個組件 此方式代表全局注冊  
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">你點一下我就加一,現在是:{{ count }}</button>'
    });
    new Vue({el:"#app"});<!--實例要寫在組件定義之后-->
</script>
</body>
</html>

 

 

 每用一次組件都會創建一個新的實例,互不干擾

這是因為data的選項是一個必須是一個函數,因此每個實例可以維護一份被返回對象的獨立拷貝

data: function () {
  return {
    count: 0
  }
}

如下寫法導致多個實例共用一個對象值

data: {
  count: 0
}

 通過 Prop 向子組件傳遞數據

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <blog-post title="這就是傳過來的值"></blog-post>
    <blog-post v-for="item in posts" v-bind:title="item.title"></blog-post>
</div>
<script>

    //定義一個組件
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">你點一下我就加一,現在是:{{ count }}</button>'
    });

    //定義一個可以傳值的組件
    Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3>'
    })
    new Vue({el:"#app",
                data:{
                posts: [
                    { id: 1, title: 'My journey with Vue' },
                    { id: 2, title: 'Blogging with Vue' },
                    { id: 3, title: 'Why Vue is so fun' }
                ]
                }
                }

    );<!--實例要寫在組件定義之后-->
</script>
</body>
</html>

注意事項:每個組件必須只有一個根元素,假如上面的模板(template)這樣定義就會報錯

 Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3><h2>{{ title }}</h2>'
    })

 

 解決的方法就是把所有的標簽都放在同一個父標簽中

 Vue.component('blog-post', {
        props: ['title'],
        template: '<div><h3>{{ title }}</h3><h2>{{ title }}</h2></div>'
    })

重構一下組件了,讓它變成接受一個單獨的 post prop

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
<div id="app">
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
  <!--  <blog-post title="這就是傳過來的值"></blog-post>
    <blog-post v-for="item in posts" v-bind:title="item.title"></blog-post>-->
    <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            v-bind:post="post"
            ></blog-post>
</div>
<script>

    //定義一個組件
    Vue.component('button-counter', {
        data: function () {
            return {
                count: 0
            }
        },
        template: '<button v-on:click="count++">你點一下我就加一,現在是:{{ count }}</button>'
    });

    //定義一個可以傳值的組件
    /*Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3><h2>{{ title }}</h2>'
    })*/
   /* Vue.component('blog-post', {
        props: ['title'],
        template: '<div><h3>{{ title }}</h3><h2>{{ title }}</h2></div>'
    })*/

    Vue.component('blog-post', {
        props: ['post'],
        template: "<div class='blog-post'><h3>{{ post.title }}</h3><div v-html='post.content'></div></div> "
    })
    new Vue({el:"#app",
                data:{
                posts: [
                    { id: 1, title: 'My journey with Vue',content:"第一個文章內容" },
                    { id: 2, title: 'Blogging with Vue',content:"第二個文章內容" },
                    { id: 3, title: 'Why Vue is so fun' ,content:"第三個文章內容"}
                ]
                }
                }

    );<!--實例要寫在組件定義之后-->
</script>
</body>
</html>

監聽子組件事件

組件定義時綁定v-on:click='$emit(`enlarge-text`)'

組件使用時綁定v-on:enlarge-text="postFontSize += 0.1"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
    <div id="blog-posts-events-demo" >
        <div :style="{ fontSize: postFontSize + 'em' }">
            <blog-post
                    v-on:enlarge-text="postFontSize += 0.1"
                    v-for="post in posts"
                    v-bind:key="post.id"
                    v-bind:post="post"
                    ></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',content:"第一個文章內容" },
                { id: 2, title: 'Blogging with Vue',content:"第二個文章內容" },
                { id: 3, title: 'Why Vue is so fun' ,content:"第三個文章內容"}],
            postFontSize: 1
        }
    })
    <!--實例要寫在組件定義之后-->
</script>
</body>
</html>

插槽

插槽的定義

 Vue.component('alert-box', {
        template:"<div class='demo-alert-box'> <strong>Error!</strong> <slot></slot> </div>"
    })
<slot></slot>就的代表組件插入的位置
    <alert-box>
            Something bad happened.
        </alert-box>

局部注冊

上面所有使用Vue.component()方式注冊的組件都是全局的,全局注冊所有的組件意味着即便你已經不再使用一個組件了,它仍然會被包含在你最終的構建結果中。這造成了用戶下載的 JavaScript 的無謂的增加。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
<div id="app">
    <component-a></component-a>
    <component-b></component-b>
</div>
<div id="app1">
    <component-a></component-a>
    <component-b></component-b>
</div>
<script>
    var ComponentA ={
        template:"<strong>ComponentA!</strong>"
    };
    var ComponentB ={
        template:"<strong>ComponentB!</strong>"
    };

    new Vue({
        el: '#app',
        components: {
            'component-a': ComponentA,
            'component-b': ComponentB
        }
    })


</script>
</body>
</html>

上面的代碼對中id為app1的div是無法使用那兩個組件的,但也不會報錯

注意局部注冊的組件在其子組件中不可用

    var ComponentB ={
        template:"<strong>ComponentB! <component-a></component-a></strong>"
    };

如果你想向上面一樣在B組件里使用A組件,你需要這樣寫

    var ComponentB ={
      components:{
            'component-a': ComponentA
        },
        template:"<strong>ComponentB! <component-a></component-a></strong>"
    };

prop

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="../js/vue.js"></script>
    <title>Assembly--->組件</title>
</head>
<body>
<div id="app">
    <blog-post title="靜態傳入" ></blog-post>
    <!-- 數值的傳入需要使用v-bind進行綁定-->
    <blog-post v-bind:likes="123"></blog-post>
    <!--傳遞一個boolean isPublished要變為is-published-->
    <blog-post v-bind:is-published="true"></blog-post>
    <!--傳遞一個對象-->
    <blog-post
            v-bind:author="{
    name: 'Veronica',
    company: 'Veridian Dynamics'
         }"
            ></blog-post>
    <!--傳遞一個數組-->
    <blog-post v-bind:comment-ids="[123, 456, 789]"></blog-post>


    <!-- 動態賦予一個變量的值 -->
    <div v-for="post in items">
    <blog-post v-bind:title="post"></blog-post>
    </div>

   <!-- <blog-post v-bind:title="post.title + ' by ' + post.author.name"></blog-post>-->
</div>
<script>
    Vue.component('blog-post', {
        // 在 JavaScript 中是 camelCase 的
        props: {
            title: String,
            likes: Number,
            isPublished: Boolean,
            commentIds: Array,
            author: Object,
            callback: Function,
            contactsPromise: Promise // or any other constructor
        },
        template: '<h3>{{title}}--{{likes}}-->{{isPublished}}-->{{author}}-->{{commentIds}}</h3>'
    })

    new Vue({
        el: '#app',
        data:{
            items:["天雁","孤歐","風鶴","血雕","斗鷹"]
        }

    })


</script>
</body>
</html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM