美文网首页
vue学习回顾第三天

vue学习回顾第三天

作者: xinhongwu | 来源:发表于2018-12-03 20:26 被阅读0次

    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>
    
    • 组件之间的传值
      1父组件传值给子组件
    <!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>
    

    相关文章

      网友评论

          本文标题:vue学习回顾第三天

          本文链接:https://www.haomeiwen.com/subject/lbyucqtx.html