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>

 

posted @ 2020-04-04 12:11  天戈  阅读(1029)  评论(0编辑  收藏  举报