vue学习回顾第三天

2018-12-03  本文已影响0人  xinhongwu

Vue组件

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。

组件的创建

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vue2.js"></script>
</head>
<body>
<!--模板要在不受vue控制的地方创建-->
<template id="three">
    <div>方式3通过模板</div>
</template>
<!--模板的第二种使用方式-->
<script type="x-template" id="three2">
<div>模板的另一种使用方式</div>
</script>
<div id="app">
    <!--组件的使用与HTML标签一样-->
    <index-a></index-a>
    <index-b></index-b>
    <index-c></index-c>
    <index-d></index-d>
</div>
</body>
<script>

    // 注意:1. 模板template中只能有一个根节点;2. 组件的名字,如果采用驼峰命令的话,在使用的时候,就要加上 “-”,比如组件名字叫indexA,那么在使用的时候就叫index-a
    // 第一种:使用Vue.extend()和Vue.component()两个方法创建
    // Vue.extend()函数会返回一个组件的构造器,它里面包含一个参数,它是一个对象,里面是一些配置项
    // Vue.component()函数会利用Vue.extend()返回的构造器创建一个组件的实例,它有两个参数,一个是组件的名字,另一个组件的构造器
    let Index=Vue.extend({
        template:"<div>我是首页</div>"
    });
    //第一个参数为组件名字,第二个为组件构造器
    Vue.component("indexA",Index);

    //方式二创建组件:使用Vue.component()创建,本质上还是调用vue.extend()方法
    Vue.component("indexB",{
        template:"<div>第二种方式创建</div>"
    });


    //第三种方式创建
    //通过指定模板创建,适用于模板内容特别多的时候
    Vue.component("indexC",{
        template:"#three"
    });
    Vue.component("indexD",{
        template:"#three2"
    });
    let vm=new Vue({
        el:"#app",
        data:{

        }
    })
</script>
</html>

组件中使用事件和指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件中使用事件和指令</title>
    <script src="vue2.js"></script>
</head>
<body>
<div id="app">
    <click></click>
</div>

</body>
<script>
    //注册组件
    // 构造 Vue 实例时传入的各种选项大多数都可以在组件里使用,但注意data必须是一个函数
    Vue.component("click",{
        template:"<div>{{msg}}<button @click='change'>改变</button></div>",
       //data必须是一个函数
        data(){
            return{msg:"hello"
            }

        },
        methods:{
            change(){
                this.msg="world"
            }
        }
    })
    let vm=new Vue({
        el:'#app',
        data:{

        }
    })
</script>
</html>

父子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件的创建</title>
    <script src="vue2.js"></script>
</head>
<body>
<div id="app">
    <father>

    </father>
   <!-- <son></son>错误用法,子组件在父组件中使用-->
</div>
</body>
<script>
    //创建父组件
    Vue.component("father",{
        //子组件要在父组件中使用
        template:'<div>我是父组件<son></son></div>',
        //通过components创建子组件
        components:{
            //son就是子组件的名字
            son:{
                template:"<div>我是子组件</div>"
            }
        }
    })
    let vm=new Vue({
        el:"#app",
        data:{

        }
    })
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>子组件获取父组件中的值</title>
    <script src="vue2.js"></script>
</head>
<body>
<div id="app">
    <father></father>
</div>
</body>
<script>
    Vue.component("father",{
        // 2. 在使用子组件的地方,通过v-bind指令给子组件中的props赋值
        template:'<div>我是一个父亲,我儿子的名字叫{{mySonName}}<p><son :myName="mySonName"></son></p></div>',
        data(){
            return{
                mySonName:"小明"
            }
        },
        components:{

            son:{
                // 1. 声明props,它的作用是:用来接收从父组件传递过来的值
                // props可以跟一个数组,数组里面的值是一个一个的字符串,这个字符串可以当成属性来使用
                props:['myName'],
                template:'<div>我是儿子,我爸爸给我起名叫{{myName}}</div>'
            }
        }
    });

    let vm=new Vue({
        el:"#app",
        data:{

        }
    })
</script>
</html>

2 子组件传值给父组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父组件获取子组件中的值</title>
    <script src="vue2.js"></script>
</head>
<body>
<div id="app">
    <father></father>
</div>
</body>
<script>

    Vue.component("father",{
        //通过监听事件获取数据
        template:'<div>我是爸爸,我儿子告诉我他的名字是{{mySonName}}<p><son @tellMyName="getMySonName"></son></p></div>',
        data(){
            return{
                mySonName:""
            }
        },
        methods:{
            //获取子组件上传的数据,默认参数代表子组件上传的数据
            getMySonName(data){
                this.mySonName=data;
            }
        },
        components:{
            son:{
                template:'<button @click="emitMyName">告诉我父亲我的名字</button>',
                data(){
                    return{
                        myName:"小花"
                    }
                },
                methods:{
                    //传递数据给父组件使用$emit方法,有两个参数,一个是事件名,另一个是要传递的数据
                    emitMyName(){
                        this.$emit("tellMyName",this.myName)
                    }
                }
            }
        }
    })
    let vm=new Vue({
        el:"#app",
        data:{

        }
    })
</script>
</html>

3 兄弟组件之间传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>兄弟组件之间传值</title>
    <script src="vue2.js"></script>
</head>
<body>
<div id="app">
    <father>

    </father>
</div>
</body>
<script>
    //1 创建一个空的vue实例,作为事件总线
    let eventBus=new Vue();
    Vue.component("father",{
        template:`<div>父组件
            <son></son>
            <daughter></daughter>
</div>`,
        components:{
            son:{
                data(){
                    return{
                        mySisterName:""
                    }
                },
                template:`<div>我妹妹的名字叫{{mySisterName}}</div>`,
               mounted(){
                    // 3 通过eventbus的$on()方法去监听兄弟节点发射过来的事件
                   //两个参数,事件名称和回调函数,参数就是传过来的数据
                    eventBus.$on('tellBroMyName',data=>{
                        this.mySisterName=data;
                    })
               }
            },
            daughter:{
                data(){
                    return{
                        myName:"小红"
                    }
                },
                template:`<button @click="emitMyName">点击就告诉哥哥我的名字叫{{myName}}</button>`,
                methods:{
                    emitMyName(){
                        //2 通过事件总线的$emit方法发送一个事件和传递的数据
                        eventBus.$emit("tellBroMyName",this.myName)
                    }
                }
            }
        }
    })
    let vm=new Vue({
        el:"#app",
        data:{

        }
    })
</script>
</html>

动态组件

<body>
    <div id="app">
      <ul>
        <li @click="currentCom='index'"><a href="#">首页</a></li>
        <li @click="currentCom='productType'"><a href="#">蔬菜</a></li>
        <li @click="currentCom='productType'"><a href="#">水果</a></li>
        <li @click="currentCom='productType'"><a href="#">肉类</a></li>
      </ul>
      <!-- 利用component标签创建动态组件,它的is属性指向谁,就显示哪个组件 -->
      <component :is="currentCom"></component>
    </div>
    <script>
      // 首页组件
      Vue.component('index', {
        template: '<div>首页</div>'
      })
      Vue.component('productType', {
        template: '<div>这里显示商品编号</div>'
      })
      var vm = new Vue({
        el: '#app',
        data: {
          currentCom: ''
        }
      })
    </script>
  </body>

局部过滤器和局部指令

<body>
    <div id="app">
      <one></one>
      <two></two>
    </div>
    <script>
      // 全局自定义指令可以在任何组件中使用
        Vue.directive('mycolor', {
          inserted(el, binding) {
            console.log(binding);
            // binding.value可以获取传入自定义指令中的属性的值
            el.style.color = binding.value
          }
        })
      // 不管是局部自定义指令还是局部过滤器都只能在当前组件内使用,脱离当前组件无效
      // 局部过滤器通过在组件内部使用filters属性创建
      Vue.component('one', {
        data () {
          return {
            time: new Date(),
            color: 'red'
          }
        },
        template: `
                      <div>
                        <p>{{time | fmtTime}}</p>
                        <input type="text" v-mycolor="color">
                      </div>
        `,
          //filters创建局部过滤器
        filters: {
          fmtTime(time) {
            console.log(time);
            var y = time.getFullYear();
            var m = time.getMonth() + 1;
            var d = time.getDate();
            return y + '/' + m + '/' + d
          }
        }
      })
      // 局部自定义指令通过在组件内部使用directives属性创建
      Vue.component('two', {
        data () {
          return {
            time: new Date(),
            color: 'red'
          }
        },
        template: `
                      <div>
                        <p>{{time}}</p>
                        <input type="text" v-myfocus v-mycolor="color">
                      </div>
        `,
        directives: {
          myfocus: {
            inserted(el, binding) {
              console.log(el);
              console.log(binding);
              el.focus()
            }
          }
        }
      })
      var vm = new Vue({
        el: '#app',
        data: {

        }
      })
    </script>
  </body>

生命周期钩子

<body>
    <div id="app">
        <p>{{info}}</p>
        <button @click="info='hello1'">更新info</button>
        <button @click="destroy">销毁实例</button>
    </div>
    <script>
        var myVm = new Vue({
            el: "#app",
            data: {
                info: "hello"
            },
            // 在实例初始化之后,数据观测 (data observer) 和 event/watcher 配置之前被调用。
            beforeCreate: function () {
                console.log("===============beforeCreate============================================")
                // $el表示Vue 实例使用的根 DOM 元素。
                console.log('$el', this.$el);
                // $data Vue 实例观察的数据对象
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            // 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,dom还未生成,$el 属性目前不可见。
            created: function () {
                console.log("===============created=======================================")
                console.log('$el', this.$el);
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            // 模板编译挂载之前调用,首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)。接着判断是否有template属性,有的话就以template属性中的值作为模板,如果没有的话,就以el属性指向的作为模板。这里会生成vm.$el,但指令尚未被解析
            beforeMount: function () {
                console.log("===============beforeMount=========================================")
                console.log('$el', this.$el);
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            // 模板编译挂载之后调用,vm.$el替换掉el指向的dom
            mounted: function () {
                console.log("===============mounted===========================================")
                console.log('$el', this.$el);
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            // 数据变更导致虚拟DOM重新渲染之前调用
            beforeUpdate: function () {
                console.log("===============beforeUpdate============================================");

            },
            // 数据变更导致虚拟DOM重新渲染之后调用
            updated: function () {
                console.log("===============updated======================================================");
            },
            // 实例销毁之前调用,在这一步,实例完全可用
            beforeDestroy: function () {
                console.log("===============beforeDestroy===============================================")
                console.log('$el', this.$el);
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            // vue实例指向的所有东西解除绑定,包括watcher、事件、所以的子组件,后续就不再受vue实例控制了
            destroyed: function () {
                console.log("===============destroyed================================================")
                console.log('$el', this.$el);
                console.log('$data', this.$data);
                console.log("info:", this.info)
            },
            methods: {
                destroy() {
                    // 表示销毁组件
                    this.$destroy()
                },
                udpateinfo() {
                    this.info = 'hello2'
                }
            }
        })
    </script>
</body>
上一篇下一篇

猜你喜欢

热点阅读