Vue 组件

组件

一、组件

<div id="app">
    <p>{{ msg }}</p>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    /*
    * 1. 组件:有html,css,js,三部分组成的独立单位,可以类似于变量,重复使用
    * 2. 组件其实就是vue实例(对象), 一个组件就是一个vue实例(对象)
    * 3. new Vue({}) 产生的是一个实例对象,所以也是一个组件,我们称之为根组件
    *       一个页面建议只出现一个根组件(项目开发模式下,一个项目建议只出现一个根组件)
    * 4. 组件的html页面结构由 template实例成员提供
    *       template提供的html结构用来构建虚拟DOM
    *       真实DOM最终被虚拟DOM替换
    *       根组件一般不提供template,就由挂载点el来提供构建虚拟Dom的页面结构
    *       根组件如果提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签
    *
    * */
    let c1 = '';
    new Vue({
        el: '#app',
        data: {
            msg: 'vue组件',
            c1: 'red'

        },
        template:
            `
        <div id="app1">
            <p :style="{color: c1}">{{ msg }}</p>
            <p @click="clickAction">{{ msg }}</p>
        </div>
        `,
        methods: {
            clickAction() {
                console.log(this.msg)
            }
        }
    })
</script>

总结:

  1. 组件:组件由html,css,js三部分组成的独立单位,类似于变量,可以重复使用
  2. 使用: 组件就是vue实例对象, 一个组件就是一个vue实例对象,通过new Vue({ })创建的对象,就是一个组件,也称之为根组件
  3. 一个页面建议只出现一个根组件,在项目开发模式下,一个项目建议只出现一个根组件
  4. 组件的html页面结构由template实例成员提供
  5. template提供html结构用来构建虚拟的DOM,真实的DOM最终会被虚拟的DOM替换,所以说不能将html和body作为根组件
  6. 根组件一般不提供template,都是由挂载点el来提供构建虚拟DOM页面结构,如果根组件提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签

二、子组件

<body>
<div id="app">
    <!--在根组件template中加载的组件,称之为根组件的子组件-->
    <my-Tag></my-Tag>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    /*
    * 1. 定义组件
    * 2. 注册组件
    * 3. 使用组件
    * */
    // 1.定义组件 如何定义子组件:组件就是一个普通对象,内部采用vue语法结构,被vue注册解释后,就会成为vue组件
    let myTag = {
        template: `
            <div>
            <h3>子组件</h3>
            <p>我是自定义的子组件</p>
            </div>`,
    };
    // 了解:全局组件,不要注册就可以直接使用
    Vue.component('tag', {
        template: `
        <div>
            <h3>全局组件</h3>
            <p>我是自定义的全局组件</p>
        </div>
        `,
    });

    new Vue({
        el: '#app',
        components: {
            // 注册组件
            myTag
        }

    })
</script>

总结

  1. 子组件: 在根组件template中加载的组件,称之为根组件的子组件

  2. 使用:定义组件,注册组件,使用组件

  3. 创建局部组件(创建对象):let myTage =

  4. 注册组件:new Vue({el:'#app', components:{ myTag //注册主键}})

  5. 使用组件:

    <div id="app">
        <!--在根组件template中加载的组件,称之为根组件的子组件-->
        <my-Tag></my-Tag>
    </div>
    
    • 使用组件注意,如果创建组件对象时使用了驼峰命名,是使用组件时候使用杠- 进行分开,子组件才可以生效
  6. 全局组件:不需要注册直接使用

    // 了解:全局组件,不要注册就可以直接使用
        Vue.component('tag', {
            template: `
            <div>
                <h3>全局组件</h3>
                <p>我是自定义的全局组件</p>
            </div>
            `,
        });
    
    <div id="app">
        <!--在根组件template中加载的组件,称之为根组件的子组件-->
        <tag></tag>
    </div>
    

三、子组件其他使用

 <style>
        .wrap {
            width: calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
            width: 200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
            width: 100%;
            /*height: 200px;*/
            border-radius: 50%;
        }
        .box p {
            text-align: center;
        }
    </style>
</head>
<body>
<div id="app">
    <!--在根组件template中加载的组件,称之为根组件的子组件-->
    <div class="wrap">
        <tag></tag>
        <tag></tag>
        <tag></tag>
        <tag></tag>
    </div>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    /*
    * 1. 定义组件
    * 2. 注册组件
    * 3. 使用组件
    * */
    let titleTag = {
        template: `
      <p>
            <b>
                这是一种纯二哈
            </b>
        </p>
      `
    };
    let tag = {
        template: `
        <div class="box">
        <img src="img/001.jpg" alt="">
           <title-tag></title-tag>
        <p @click="fn">
            锤他: <b>{{ num }}</b>下
        </p>
    </div>

        `,
        data() {
            /*
            * 1. 能被复用的组件(除了根组件),数据也要做局部化处理,
            *   因为复用组件后组件的数据是相互独立的
            * 2. data的值为绑定的方法的返回值,返回值是存放在数据字典中的*/
            return {
                num: 0,
                a:1
            }
        },
        methods: {
            fn() {
                this.num++
            }
        },
        components: {
            titleTag
        }
    };
    new Vue({
        el: '#app',
        components: {
            // 注册组件
            tag
        }

    })
</script>

总结:

  1. 子组件除了组件能够被复用以外,数据也需要做局部化的处理,因为每一个组件复用后,组件的数据是相互独立的

  2. 在复用数据data中的是绑定方法的返回值,返回值要存放在字典中,返回的数据是键值对,每复用一次组件,就相当于产生一份自己的数据,与其他组件互不干扰,data:的数据是通过return返回的键值对

    eg: data() { return { num: 0 } },

  3. 每次复用一次组件,数据data需要做局部化处理,相当于每次复用一次组件就产生一个对象,产生不相干的各个名称空间

四、组件传参父传子

 <style>
        .wrap {
            width: calc(200px * 4 + 80px);
            margin: 0 auto;
            user-select: none;
        }
        .box {
            width: 200px;
            height: 260px;
            /*border: 1px solid black;*/
            background-color: rgba(10, 200, 30, 0.5);
            border-radius: 10px;
            float: left;
            margin: 10px;
        }
        .box img {
            width: 160px;
            height: 160px;
            border-radius: 50%;
            margin: 0 auto;
            display: block;
        }
        .box p {
            text-align: center;
        }
    </style>
</head>
<body>
<div id="app">
    <!--在根组件template中加载的组件,称之为根组件的子组件-->
    <div class="wrap">
        <tag v-for="(dog, i) in dogs" :dog="dog" v-bind:a="2"></tag>
    </div>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    let dogs = [
        {title: '二哈1号', img: 'img/1.jpg',},
        {title: '二哈2号', img: 'img/2.jpg',},
        {title: '二哈3号', img: 'img/3.jpg',},
        {title: '二哈4号', img: 'img/4.jpg',},
        {title: '二哈1号', img: 'img/1.jpg',},
        {title: '二哈2号', img: 'img/2.jpg',},
        {title: '二哈3号', img: 'img/3.jpg',},
        {title: '二哈4号', img: 'img/4.jpg',},
    ];
    let tag = {
        // 在组件内部就可以通过设置自定义属性,拿到外部选择子组件提供给属性的值
        props:['dog','a'],
        template: `
        <div class="box">
        <img :src="dog.img" :alt="a">
           <p>{{ dog.title }}</p>
        <p @click="fn">
            锤他: <b>{{ num }}</b>下
        </p>
    </div>
        `,
        data() {
            return {
                num: 0,
                a: 1
            }
        },
        methods: {
            fn() {
                this.num++;
                // console.log(this.a);
            }
        },
    };
    new Vue({
        el: '#app',
        data: {
            dogs,
        },
        components: {
            // 注册组件
            tag
        }
    })
</script>

总结:

  1. 组件传参-父传子:将根组件的数据传给子组件 eg: props:['dog','a'],
  2. 子组件所使用的数据在父组件中产生,在子组件中使用
  3. 通过在父组件中渲染子组件的时候,子组件绑定自定义属性v-bind对应的值为父组件中的数据
  4. 子组件中绑定的自定义属性,子组件通过props反射机制获取绑定的属性值(采用字符串反射机制)
  5. 使用,通过props声明获取的属性,可以直接作为变量来使用父组件中的数据

五、组件传参子传父

 <style>
        ul {
            list-style: none;
        }
        .d-btn {
            font-size: 12px;
            width: 15px;
            display: inline-block;
        }
        .d-btn:hover {
            color: red;
            cursor: pointer;
        }
    </style>
</head>
<body>
<div id="app">
    <input type="text" v-model="msg">
    <button @click="send_msg">留言</button>
    <ul>
        <tag v-for="(msg, i) in comment" :comment="msg" :index="i" @fn="deleteMsg"></tag>
    </ul>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    let tag = {
        props: ['comment', 'index'],
        template: `
         <li >
         <i class="d-btn" @click="fun">x</i>
         <b>{{ comment }}</b>
         </li>
      `,
        methods: {
            fun() {
                // 点击要删除的信息,告诉父级要删除的是第几条数据记录,疑问comments在父级中
                // 需要告诉父级删除的是那一个记录
                this.$emit('fn', this.index)
            },
        },
    };
    new Vue({
        el: '#app',
        data: {
            msg: '',
            comment: localStorage.comment ? JSON.parse(localStorage.comment) : []
        },
        methods: {
            send_msg() {
                if (this.msg) {
                    this.comment.push(this.msg);
                    this.msg = ""
                    localStorage.comment = JSON.stringify(this.comment)
                }
            },
            deleteMsg(i) {
                // splice参数:开始索引操作长度,操作的结果
                this.comment.splice(i, 1)
                localStorage.comment = JSON.stringify(this.comment)
            }
        },
        components: {
            tag,
        }
    });
    // localStorage,sessionStorage不能直接存储数组和对象,需要序列化为json
    localStorage.arr = JSON.stringify([1, 2, 3]);
    let res = JSON.parse(localStorage.arr);
    console.log(res, res[2]);
</script>

eg2:
<body>
<div id="app">
    <h1>{{ title }}</h1>
    <tag @fn="msg"></tag>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
    let tag = {
        data() {
            return {
                modify_title: '',
            }
        },
        template: `
         <p >
         <input v-model="modify_title">   {{modify_title}}
         </p>
      `,
        watch: {
            modify_title() {
                //将修改的数据传父类级组件,可以传递多个值给父级组件
                console.log(1);
                this.$emit('fn', this.modify_title, 'adf')
            },
        },
    };
    new Vue({
        el: '#app',
        data: {
            title: '父级初始内容',
        },
        methods: {
            // 可以传递多个
            msg(s, a) {
                console.log(s, a);
                this.title = s ? s : '父级初始内容'
            }
        },
        components: {
            tag,
        }
    });
</script>

img

总结:

  1. 组件数据传参-子传父:通过方式事件请求的方式进行数据传递 eg: this.$emit('fn', this.index)
  2. 通过在子组件中创建的函数通过 this.$emit('函数名', 参数),传递给父组件,第一个参数为自己定义的函数不能是事件函数(@fn='fun')在标签中绑定函数不需要括号传参,他会自动将数据传递,第二参数为要传递的真实数据,可以传送多个值
  3. ,localStorage,sessionStorage在前台浏览器中,不能直接存储数组和对象,需要将数据序列化为json数据

六、总结

  1. 组件:

    1. 组件:组件由html,css,js三部分组成的独立单位,类似于变量,可以重复使用
    2. 使用: 组件就是vue实例对象, 一个组件就是一个vue实例对象,通过new Vue({ })创建的对象,就是一个组件,也称之为根组件
    3. 一个页面建议只出现一个根组件,在项目开发模式下,一个项目建议只出现一个根组件
    4. 组件的html页面结构由template实例成员提供
    5. template提供html结构用来构建虚拟的DOM,真实的DOM最终会被虚拟的DOM替换,所以说不能将html和body作为根组件
    6. 根组件一般不提供template,都是由挂载点el来提供构建虚拟DOM页面结构,如果根组件提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签
  2. 子组件

    1. 子组件: 在根组件template中加载的组件,称之为根组件的子组件

    2. 使用:定义组件,注册组件,使用组件

    3. 创建局部组件(创建对象):let myTage =

    4. 注册组件:new Vue({el:'#app', components:{ myTag //注册主键}})

    5. 使用组件:

      <div id="app">
          <!--在根组件template中加载的组件,称之为根组件的子组件-->
          <my-Tag></my-Tag>
      </div>
      
      • 使用组件注意,如果创建组件对象时使用了驼峰命名,是使用组件时候使用杠- 进行分开,子组件才可以生效
    6. 全局组件

      // 了解:全局组件,不要注册就可以直接使用
          Vue.component('tag', {
              template: `
              <div>
                  <h3>全局组件</h3>
                  <p>我是自定义的全局组件</p>
              </div>
              `,
          });
      
      <div id="app">
          <!--在根组件template中加载的组件,称之为根组件的子组件-->
          <tag></tag>
      </div>
      
  3. 子组件数据复用

    1. 子组件除了组件能够被复用以外,数据也需要做局部化的处理,因为每一个组件复用后,组件的数据是相互独立的

    2. 在复用数据data中的是绑定方法的返回值,返回值要存放在字典中,返回的数据是键值对,每复用一次组件,就相当于产生一份自己的数据,与其他组件互不干扰

      eg: data() { return { num: 0 } },

    3. 每次复用一次组件,数据data需要做局部化处理,相当于每次复用一次组件就产生一个对象,产生不相干的各个名称空间

  4. 组件数据传参-父传子

    1. 组件传参-父传子:将根组件的数据传给子组件 eg: props:['dog','a'],:'dog'是绑定的属性,通过绑定属性的方式进行数据传递
    2. 子组件所使用的数据在父组件中产生,在子组件中使用
    3. 通过在父组件中渲染子组件的时候,子组件绑定自定义属性v-bind对应的值为父组件中的数据
    4. 子组件中绑定的自定义属性,子组件通过props反射机制获取绑定的属性值(采用字符串反射机制)
    5. 使用:通过props声明获取的属性,可以直接作为变量来使用父组件中的数据
  5. 组件数据传参-子传父

    1. 组件数据传参-子传父:通过方式事件请求的方式进行数据传递 eg: this.$emit('fn', this.index)
    2. 通过在子组件中创建的函数通过 this.$emit('函数名', 参数),传递给父组件,第一个参数为自己定义的函数不能是事件函数(@fn='fun')在标签中绑定函数不需要括号传参,他会自动将数据传递,第二参数为要传递的真实数据
    3. ,localStorage,sessionStorage在前台浏览器中,不能直接存储数组和对象,需要将数据序列化为json数据
posted @ 2019-11-17 14:51  RandySun  阅读(272)  评论(0编辑  收藏  举报