Vue局部组件、组件父子传值、添加属性

1.Vue的局部组件:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <div id="app">

        <div>

            <son/>

        </div>

        <div>

            <son/>

        </div>

        <div>

            <son/>

        </div>

        <div>

            <son/>

        </div>

        <div>

            <child2 />

        </div>

        <div>

            <child1 />

            <template id="child2">

                <div>

                    我爱学习js

                </div>

            </template>

       </div>

    </div>

    <template id="child2">

        <div>

            <h1>我是child2</h1>

            <child />

            <son />

        </div>

    </template>

    <script src="./vue.min.js"></script>

    <script>

        /* 全局组件 */

        Vue.component('child',{

            template:"<h1 @click = 'fn'>我是全局组件</h1>",

            created:function() {

                console.log('我是child');

            },

            methods: {

                fn(){

                    console.log('child');

                }

            },

        })

        Vue.component('child2',{

            template:"#child2"


        })

        new Vue({

            el:"#app",

            /* 局部组件 */

            components:{

            son:{

                template:`<h1>我是局部组件son</h1>`,

                created(){

                    console.log('son');

                }

            },

            child1:{

                template:`<h1>我爱学习</h1>`,


            }

            },

            data:{

            }

        })

        /* 全局组件 放哪都可用用

           局部组件只有在挂载的区域使用 如 el:"#app"这个div中 */

           /* #app模板写局部组件 child1 显示我爱学习 使用<template>标签的方式

             在child1 里面使用全局组件child2(child2显示我爱学JS) */

    </script>

</body>

</html>

效果图:


2.组件父子传值:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <!-- 父组件 -->

    <div id="app">

        <h1>这是父组件里面的msg:{{msg}}</h1>

        <!-- 把msg传入给子组件 -->

        <!-- 自定义事件不要写大写,会解析成小写 -->

        <child :cmsg="msg" :list="list" @childchange="ctrl" @xxxchild="xxxctrl"/>


    </div>

    <!-- 子组件 -->

       <template id="child">

           <div>

                <h1 @click="change">{{cmsg}}</h1>


           <ul>

               <!-- 点击li改变相应的li中的数据改成'xxx' -->

               <li v-for="(v,i) in list " :key="i" @click="xxx(i)" :style="{'text-decoration': v.flag? 'line-through':''}">{{v.content}}</li>

           </ul>

           <h2>{{msg}}</h2>

        </div>

       </template>



    <script src="./vue.min.js"></script>

    <script>

     new Vue({

         el:"#app",

         data:{

            msg:"任务列表",

            list:[]

         },

         methods:{

            ctrl(v){

                console.log(v.value1);

                console.log(v.value2);

                console.log(v.value3);

            this.msg = v.value1

            },

            xxxctrl(i){

                console.log(i);


                /* 第一种修改方法 */

                /* this.list[i].content = 'xxxxxx' */


                /* 第二种修改方法 */

                /* 数组的方法splice 三个参数的作用 第一个是索引 从哪里开始

                   第二个是从当前的索引删除几个  第三个参数是  添加的内容*/

                /* this.list.splice(i,1,{content:'xxxxx'})

                console.log(this.list); */


                /* 先把数组的所有对象加上flag属性 值为false */

               this.list.forEach(r=>{r.flag=false})

               /* 再把选中的flag变为true */

                /* this.list[i].flag = true */

                /* $set 三个参数 第一个是目标对象 this.list

                    第二个参数是目标参数的索引

                    第三个参数是具体要修改的内容 */

                this.$set(this.list,i,{content:this.list[i].content,flag:true})

                console.log(this.list);

                /* vue2的缺陷 不可以给对象里面添加属性

                   虽热可以添加 但是页面不会渲染相应的结果 */

            }


         },

         created() {

             setTimeout(()=>{

                this.list = [

                    {content:'今天天气好热'},

                    {content:'今天天气好冷'},

                    {content:'今天天气不冷不热'},

                ]

             },500)

         },

         components:{

             child:{

                 template:"#child",

                 /* 子组件使用props接收 */

                 /* 简写 */

                 /* props:['cmsg','list'] */

                 /* 全面写法 */

                 props:{

                     cmsg:{

                         type:String,

                         default:'默认值'

                     },

                     list:{

                         type:Array,

                         /* 默认值 */

                         default:[{content:'xxx'},{content:'xxx'},{content:'xxx'}]

                     }

                 },

                 /* 如果这样写的和父组件一样都是对象,会对父组件data的对象造成污染 */

                 /* data:{

                  msg:'我是child的人'

                 }, */

                 /* data 采用函数的方式会产生局部作用域 里面的数据是组件私有的不会对全局造成影响

                    怎么获取数据 , 采用return 一个对象的方式来获取组件里面的数据 */

                 data:function(){

                    return{

                        msg:'我是child的人'

                    }

                 },

                 created(){

                     /* 渲染页面后才能打印 */

                     console.log(this.list);

                 },

                 methods: {

                     change(){

                         /* this.cmsg = '子改父' */

                         /* 在子组件直接改父组件是不可以的

                           因为违反了Vue里面的 单向数据流的原理(类似于瀑布)

                           直接改在父组件里面的数据还是没有改变*/

                           /* 子改父步骤 */

                           /* 1.使用Vue里面的$emit方法发送一个自定义事件childchange */

                           /* 2.在组件上使用@childchange="ctrl" 绑定自定义事件触发父组件的ctrl方法 */

                           /* 3.在父组件中的ctrl方法内把父组件的msg值给改了 */

                          /*  this.$emit('childchange') */

                           /* this.$emit('childchange','子改父','baba','erzi') */

                           this.$emit('childchange',{value1:'子改父',value2:'baba',value3:'erzi'})


                     },

                     xxx(i){

                         this.$emit('xxxchild',i)

                         console.log(i);

                     }

                 },

             },


         }

     })

     /* 父组件有个数组[{content:'xxx'},{content:'xxx'},{content:'xxx'}]

        传给子组件来渲染*/


    </script>

</body>

</html>

效果图:


3.Vue添加属性:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <div id="app">

        <h1>{{list}}</h1>

        <button @click="fn">添加age</button>

        <hr>

        <h1>{{arr}}</h1>

        <button @click="fn2">添加car</button>

    </div>

    <script src="./vue.min.js"></script>

    <script>

        new Vue({

            el:"#app",

            data:{

                list:{

                    name:'tom'

                },

                arr:[{

                    name:'jack'

                },{

                    name:'youyuxi'

                }]

            },

            methods: {

                fn(){

                    /* VUE2的一个缺陷,不可以给对象添加属性 */

                    /* this.list[0].age = 30; */

                    /* this.$set(目标对象,具体的key要使用引号,具体要修改的值) */

                    this.$set(this.list,'age',30)

                    console.log(this.list);

                },

                fn2(){

                    /* 这是更新对象数据的方式 */

                    /* this.$set(this.arr[1],'car','bmw') */

                    /* 这是更新数组的到视图的方式 */

                    /* 三个参数分别对应 目标数组  数组所在的索引 和需要修改的内容 */

                    this.$set(this.arr,1,{name:'youyuxi',car:'benchi'})

                }

            },

        })

    </script>

</body>

</html>

效果图:


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容