《VUE-REVIEW》 day3

day03_04 组件的创建

    <body>
        <div id="app">
            <my-component1></my-component1>
            <hr>
            <my-component2></my-component2>
        </div>
        <!-- 在被控制的 #app 外面,使用template元素定义组建的html模板结构 -->
        <template id="temp1">  
            <div>
                <h1>通过template元素定义的组建</h1>
                <h3>我也是</h3>
            </div>
        </template>
        <script>
            // 全局注册组建
            //定义方式1:
            Vue.component('my-component1',{
                template:'<h3>这是VUE定义的全局组建</h3>'
            })
            //定义方式2:
            Vue.component('myComponent2',{
                template:'#temp1'
            })
            new Vue({
                el: '#app',
                data: {
                },
                methods:{
                }
            })
        </script>
    </body>

 day03_05 组件中data

    <body>
        <div id="app">
            <mycom1></mycom1>
        </div>
        <script>
            Vue.component('mycom1',{
                template:'<h1>这里是全局组件-----{{message}}</h1>',
                // 组件中的data和实例中的data不一样,实例中的data可以为一个对象,但是组建中的data必须为一个方法
                // 并且组建中的data方法 中必须返回一个对象
                data : function(){
                    return {
                        message: '组件中的data'
                    }
                }
            })
            new Vue({
                el: '#app',
                data: {

                },
                methods:{

                }
            })
        </script>
    </body>

day03_06 组件中的methods

<body>
        <div id="app">
            <mycom1></mycom1>
            <hr>
            <mycom1></mycom1>
            <hr>
            <mycom1></mycom1>
            <hr>
        </div>

        <template id="temp1">
            <div>
                <input type="button" value="点我+1" @click="add">
                {{count}}
            </div>
        </template>
        <script>
            //实现一个计数器的组建,每次点击按钮时+1
            Vue.component('mycom1',{
                template:'#temp1',
                //data必须为方法再返回一个对象的好处在于:每次返回一个对象的时候,可以创建一个新的对象,数据值不会跟其他元素调用该组件时串用
                data:function(){
                    return {count:0}
                },
                methods:{
                    add(){
                        this.count++
                    }
                }
                   
            })
            new Vue({
                el: '#app',
                data: {

                },
                methods:{

                }
            })
        </script>
    </body>

 day03_07 组件切换-使用v-if和v-else

    <body>
        <div id="app">
            <a href="" @click.prevent="flag = true">登录</a>
            <a href=""  @click.prevent="flag = flase">注册</a>
            <mycom1 v-if="flag"></mycom1>
            <mycom2 v-else="flag"></mycom2>
        </div>
        <!-- 登陆模板 -->
        <template id="temp1">
            <div>
                <span>------欢迎来到登陆页面------</span><br>
                账号:<input type="text"><br>
                密码:<input type="text"><br>
                <input type="button" value="登陆">
                <input type="button" value="注册">
            </div>
        </template>
        <script>
            Vue.component('mycom1',{
                template:'#temp1'
            })

            Vue.component('mycom2',{
                template:'<h1>注册组件</h1>'
            })
            new Vue({
                el: '#app',
                data: {
                    flag:true
                },
                methods:{

                }
            })
        </script>
    </body>

day03_08 组件切换-使用vue提供的component

    <body>
        <div id="app">
            <a href="" @click.prevent="compName = 'login'">登录</a>
            <a href=""  @click.prevent="compName = 'register'">注册</a>
            <!-- vue提供了component 元素,来展示对应的组件模板 -->
            <!-- component元素的值如果写 组件名,需要用单引号''引起来,不然会默认为是一个对象-->
            <component :is="compName"></component>

            <!-- 目前为止,已学习VUE提供的标签有: -->
            <!-- 组件标签:component  组件模板标签template  动画标签transition transitionGroup-->
        </div>

        <!-- 登陆模板 -->
        <template id="temp1">
            <div>
                <span>------欢迎来到登陆页面------</span><br>
                账号:<input type="text"><br>
                密码:<input type="text"><br>
                <input type="button" value="登陆">
            </div>
        </template>
        <!-- 注册模板 -->
        <template id="temp2">
            <div>
                <span>------欢迎来到注册页面------</span><br>
                账号:<input type="text"><br>
                密码:<input type="text"><br>
                <input type="button" value="注册">
            </div>
        </template>
        <script>
            Vue.component('login',{
                template:'#temp1'
            })

            Vue.component('register',{
                template:'#temp2'
            })
            new Vue({
                el: '#app',
                data: {
                    compName:'login'
                },
                methods:{

                }
            })
        </script>
    </body>

day03_09 组件切换-切换动画效果

   1、给day03_08中的component 元素加上动画效果

<!-- 1、通过设置mode属性,元素先出去后再进来 -->
<transition mode="out-in">
      <component :is="compName"></component>
</transition>

  2、设置动画样式

    <style>
        .v-enter,
        .v-leave-to{
            opacity: 0;
            transform: translateX(150px);
        }
        .v-enter-active,
        .v-leave-active{
            transition: all 0.5s ease;
        }
    </style>

效果如下:

day03_09【复习】组建定义的方式

   <body>
        <div id="app">
            <mycomp></mycomp>
        </div>
        <script>
            // 通过Vue.component注册一个全局的vue组件,同时为这个组件起了一个名称,可以让我们通过标签的方式
            // 在页面中进行引用
            // Vue.component('mycomp',{'template':{},date:{},methods:{}})

            var login = {
                'template':'<h1>helloworld</h1>'
            }
            //可以直接调用定义的对象
            Vue.component('mycomp',login)

            new Vue({
                el: '#app',
                data: {

                },
                methods:{

                }
            })
        </script>
    </body>

day03_10 父组件向子组件传值

 1、定义局部组件comp1 ,作为VM组件的子组件

 2、尝试从父组件VM中直接用插值表达式的方式获取父组件中的值{{parentMsg}}

   <script>
        var vm = new Vue({
            el: '#app',
            data: {
                parentMsg:'父组件中的数据aaaaaaaa'
            },
            methods: {},
            components:{
                comp1:{
                    template:'<h1>子组件的模板:---{{parentMsg}}</h1>'
                } 
            }
        });
    </script>

3、报错如下,提示找不到 parentMsg 这个属性或者方法。

 

 

 

 

 4、父组件可以在引用子组件的时候,通过 属性绑定(v-bind :)的形式,自定义属性将数据传递给子组件,供子组件内部使用 

<div id="app">
        <!-- 自定义属性 pMsg,将父组件中的数据parentMsg传过来-->
        <comp1 :pMsg="parentMsg"></comp1>
 </div>

5、需要在子组件中的props属性中定义从父组件传递给子组件的数据,定义为‘pMsg’ ,子组件中props所用的数据都是通过父组件传递给子组件的

6、通过插值表达式{{pMsg}}获取在props中定义的数据

<body>
    <div id="app">
        <!-- 自定义属性 pMsg,将父组件中的数据parentMsg传过来-->
        <comp1 :pMsg="parentMsg"></comp1>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                parentMsg:'父组件中的数据aaaaaaaa'
            },
            methods: {},
            components:{
                comp1:{
                    template:'<h1>子组件的模板:---{{pMsg}}</h1>'
                },
                props:['pMsg']
            }
        });
    </script>
</body>

7、执行后发现报错如下:

 

 

 

 百度后才知道踩了VUE的坑:子组件属性传值绑定时名称不能 有 大写,必须小写

于是将pMsg 改为 pmsg 后就可以了。

并且,从父组件传递过来的props中的值都是只读的,修改会报错。子组件本身的data数据都是可读可写的。

 
 

day03_11 父组件向组件传递方法(子组件向父组件中传值)

 1、定义子组件模板,并在vm中引入子组件

   <body>
        <div id="app">
            <comp ></comp>
        </div>
        <!-- 组件模板 -->
        <template id="temp">
            <div>
                <h1>这是子组件-----</h1>
            </div>
        </template>
        <script>
            //定义组件模板对象
            var comp = {
                template:'#temp'
            }
            new Vue({
                el: '#app',
                data: {
                },
                methods:{
                },
                components:{
                    comp
                }
            })
        </script>
    </body>

 

 2、父组件可以在引用子组件的时候,通过事件绑定机制向子组件传递方法 

  ①父组件中添加show方法

  ②在引用子组件comp 时,通过绑定事件的机制向子组件传递父组件中show 方法 

 
methods:{
      show(data){
          console.log('这是父组件中的show方法')
      }
},

 

<comp @func="show"></comp>

 

 3、在子组件模板 中添加按钮触发事件’sonfunc‘用来接收 父组件传过来的方法

<!-- 组件模板 -->
<template id="temp">
     <div>
          <h1>这是子组件</h1>
          <input type="button" value="这是子组件的按钮,点击它触发父组件传递过来的func方法" @click="sonfunc">
     </div>
</template>

 4、在子组件点击事件 sonfunc 中使用vue提供的$emit指令可以拿到父组件在引用子组件的时候,通过事件绑定机制传递过来的方法

      //emit为触发,调用的含义

 methods:{
       sonfunc(){
           this.$emit('func')
       }
}

 

 

 

 5、在调用父组件方法时,可以在方法中以添加参数的形式向父组件方法传递数据。

    ①、现在子组件中定义需要传递的数据对象

data(){
   return {
        person:{name:'zhangsan',age:10}
   }
},

② 在 emit 指令中添加需要传递的对象数据

this.$emit('func',this.person)

③ 、在父组件方法中添加接收参数data ,用于子组件调用父组件show方法时所传过来的数据。

                methods:{
                    show(data){
                        // console.log('这是父组件中的show方法:----'+data)
                        console.log(data)

                    }
                },

打印结果如下:

总结:从而实现了父组件通过事件绑定机制向子组件传递方法,子组件通过调用父组件传过来的方法,以参数形式向父组件传递参数数据。

 

day03_12 组件案例:发表评论

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../../lib/vue.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div id="app">
        <!-- 将父组件中的加载评论数据方法传递给子组件 -->
        <comp @parentfunc="loadComments"></comp>
        <ul class="list-group">
            <li class="list-group-item" v-for="item in list" :key="item.id"> 
                <span class="badge">{{item.user}}</span>
                {{item.content}}
            </li>
        </ul>
    </div>

    <template id ="temp1">
        <div>
            <div class="form-group">
                <label >评论人</label>
                <input type="text" class="form-control" v-model="user">
            </div>
            <div class="form-group">
                <label >评论内容</label>
                <input type="text" class="form-control" v-model="content">
            </div>
            <div class="form-group">
                <input type="button" value="发表评论" class="btn btn-primary" @click="fabiao">
            </div>
        </div>
    </template>

    <script>
        var comp = {
            template :"#temp1",
            data(){
                return {
                    user:'',
                    content:''
                }
            },
            methods:{
                fabiao(){
                     //发表评论的逻辑
                        //1、评论数据存到localStorage中,模拟数据库
                        //2、组织出一个发表的评论对象
                        //3、将评论对象保存到localStorage中
                        //  3.1、localstrorage中只支持存放字符串,需要先调用JSON.stringfy将评论对象转成字符串
                        //  3.2、保存最新的数据之前,需要先从localstorage中获取之前的评论数据(String),转换为一个
                        //       数组对象(JSON.parse),然后把最新的评论push到这个数组
                        //  3.3、如果获取到的localstorage为空,则可以返回一个空数组[],防止JSON.parse报错
                        //  3.4  再次将最新的评论数组调用JSON.stringfy转换成字符串,然后调用localstorage.setItem()
                    var content = {id:Date.now(),user:this.name,content:this.msg}
                        
                    var listConts = JSON.parse(localStorage.getItem('conts') || '[]')
                    //unshift方法插入到最前面
                    listConts.unshift(content);
                    localStorage.setItem('conts',JSON.stringify(listConts))
                    this.name = this.msg = ''
                    this.$emit('parentfunc')

                }
            }
        }
        var vm = new Vue({
            el: '#app',
            data: {
                list:[
                        {id:'1',user:'李白',content:'天生我才必有用'},
                        {id:'2',user:'江小北',content:'把酒问青天,天下谁人不识君'},
                        {id:'3',user:'张小黑',content:'草拟个dj'}
                    ]
            },
            created(){
                    this.loadComments();
            },
            methods:{
                loadComments(){
                    this.list = JSON.parse(localStorage.getItem('conts') || '[]')
                }
            },
            components:{
                comp
            }
        });
    </script>
</body>

 day03_13 ref获取dom元素

<body>
        <div id="app">
            <input type="button" value="获取dom元素" @click="btn">
            <!-- 通过ref来直接获取DOM元素 -->
            <h3 id="myh3" ref="myh3">hellow Vue</h3>
            <comp ref="mycomp"></comp>
        </div>
        <script>
            var comp = {
                template:'<h1>这是子组件</h1>',
                data(){
                    return {
                        msg:'这是子组件中的date数据'
                    }
                },
                methods:{
                    func(){
                        console.log('这是子组件中的methods')
                    }
                }
            }
            var vm = new Vue({
                el: '#app',
                data: {

                },
                methods:{
                    btn(){
                        //原始方法获取
                        //console.log(document.getElementById('myh3').innerText)
                        //使用Vue提供给我们的ref,ref是英文单词 [reference:引用] 的缩写
                        // console.log(this.$refs.myh3.innerText)
                        console.log(this.$refs.mycomp.func)
                    }
                },
                components:{
                    comp
                }
            })
        </script>
    </body>

 

posted @ 2021-03-18 17:02  LZ1024  阅读(39)  评论(0编辑  收藏  举报