组件

组件实现

组件可用以下方式实现,其实组件都是以extend方法生产的,代码如下:

组件可分为全局组件和局部组件

全局组件使用Vue.component注册

局部组件在Vue实例中使用component属性进行注册

<body>
    <div id="app">
        <cpn></cpn>
    </div>

    <div id="appTwo">
        <cpn></cpn>
    </div>

    <script src="../vue.js"></script>
    <script>
        const cpns = Vue.extend({
            template: ` <ul>
        <li>hello world</li>
        <li>hello world</li>
        <li>hello world</li>
        <li>hello world</li>
        </ul>`
        });

        Vue.component('cpn', cpns);

        const app = new Vue({
            el: '#app',
            // components: {
            //     cpn: cpns
            // }
        });

        const appTwo = new Vue({
            el: '#appTwo',
        });
    </script>
</body>

组件语法糖

组件同样也有语法糖写法

第一种写法为template,它将extend方法省去,简化了代码

<body>
    <div id="app">
        <cpn></cpn>
    </div>
    <script src="../vue.js"></script>
    <script>
        // Vue.component('cpn', {
        //     template: `<div>
        // <h1>hello papa</h1>
        // <p>how you doing</p>
        // </div>`
        // });

        const app = new Vue({
            el: '#app',
            components: {
                cpn: {
                template: `<div>
            <h1>hello papa</h1>
            <p>how you doing</p>
            </div>`
            }
            }
        });
    </script>
</body>

Vue还提供了另外一种语法糖,这种语法糖可以很好的模板代码与js代码进行分离

<body>
    <div id="app">
      <cpn></cpn>
    </div>

    <script src="../vue.js"></script>
<!--    <script type="text/x-template" id="cpn">-->
<!--        <div>-->
<!--            <h1>hello daddy</h1>-->
<!--            <p>how you doing</p>-->
<!--        </div>-->
<!--    </script>-->

    <template id="cpn">
        <div>
            <h1>hello daddy</h1>
            <p>how you doing</p>
        </div>
    </template>

    <script>
        Vue.component('cpn', {
            template: `#cpn`
        });

        const app = new Vue({
            el: '#app',

        });
    </script>
</body>

组件数据处理

其实组件的结构和vue实例很相似,甚至可以将vue实例当作一个根组件,因此vue实例中的属性在template中也能使用

<body>
<div id="app">
    <cpn></cpn>
    <cpn></cpn>
    <cpn></cpn>
</div>

<script src="../vue.js"></script>
<template id="cpn">
    <div>
        <div>
            <h1>当前计数:{{count}}</h1>
            <button @click="subCount"> -</button>
            <button @click="addCount"> +</button>
        </div>
    </div>
</template>

<script>
    Vue.component('cpn', {
        template: `#cpn`,
        data() {
            return {
                count: 0
            }
        },
        methods: {
            addCount() {
                this.count++;
            },
            subCount() {
                this.count--
            }
        }
    });

    const app = new Vue({
        el: '#app'
    });
</script>
</body>

但是得记住,template中的data是一个函数,返回值是一个对象,这样做是为了让各个组件实例的数据不相互影响

props属性

props属性常常用于父组件向子组件传递数据,刚刚说到vue实例其实也可看做一个组件,因此常用于vue实例向组件传递数据

但实际上官方文档是这样说的:

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。

也就是说prop是我们在组件上自定义的属性,我们可以直接给这个属性赋值,它是可以显示在模板语法中的,也可以通过绑定的方式,将属性与vue实例的data属性中的值进行绑定,这样模板语法中渲染出来的值就是来自其他节点的

<body>
    <div id="app">
      <cpn :name="name" :movies="movies"></cpn>
    </div>

    <template id="cpn">
      <div>
        <h1>hello: {{name}}</h1>
        <p>see movies: {{movies}}</p>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
        Vue.component('cpn',{
          template: `#cpn`,
          props: ['name', 'movies']
        });

        const app = new Vue({
          el: '#app',
          data() {
            return {
              name: 'justin timberlake',
              movies: ['千与千寻', '星际穿越', '龙猫']
            };
          }
        });
    </script>
</body>

$emit方法

官方文档给出的解释是:

触发当前实例上的事件。附加参数都会传给监听器回调。

可以这样理解,emit相当于将事件监听与模板实例里面的方法绑定起来,在触发模板实例时,便会回调emit所在的方法,并将方法的参数传递给模板实例的方法,随后进行数据的处理

<body>
    <div id="app">
      <cpn @get-item="btnClick" :movies="movies"></cpn>
    </div>

    <template id="cpn">
      <div>
        <button v-for="item in movies" @click="$emit('get-item', item)">{{item}}</button>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
      const cpn = {
        template: `#cpn`,
        data() {
          return {

          }
        },
        props: ['movies']
        // methods: {
        //   btnClick(item) {
        //     this.$emit('get-item', item);
        //   }
        // }
      }

      const app = new Vue({
        el: '#app',
        data:{
            movies: ['taylor', 'justin', 'rihanna', 'pink']
        },
        components: {
          cpn
        },
        methods: {
          btnClick(item) {
            console.log(item);
          }
        }
      });
    </script>
</body>

获取父子组件

获取子组件

获取子组件有两种方法,分别是$children和$refs

不同的是,$children获取的是所有子节点,以数组形式存储

$refs获取含有ref属性的节点,以对象的形式存储,也是较为常用的一种方式

<body>
    <div id="app">
      <cpn ref="first"></cpn>
      <cpn></cpn>
      <cpn></cpn>
      <button @click="getChild()">获取子节点数据</button>
    </div>

    <template id="cpn">
      <h1>i am son node</h1>
    </template>

    <script src="../vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        methods: {
          getChild() {
            // console.log(this.$children[0].message);
            console.log(this.$refs.first);
          }
        },
        components: {
          cpn: {
            template: `#cpn`,
            data() {
              return {
                message: 'you got me!'
              }
            }
          }
        }
      });
    </script>
</body>

获取父组件

获取父组件也有两种方法,分别是$parents和$root

$parent是获取所有的父节点

$root是获取根节点

这两种方法都较为少用

<body>
    <div id="app">
      <cpn></cpn>
    </div>

    <template id="cpn">
      <div>
        <h1>hello world</h1>
        <ccpn></ccpn>
      </div>
    </template>

    <template id="ccpn">
      <div>
        <h1>i am child</h1>
        <button @click="getFather()">访问父节点</button>
        <button @click="getRoot()">访问根节点</button>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        date: {
          message: 'hello!!!'
        },
        components: {
          cpn: {
            template: `#cpn`,
            components: {
              ccpn: {
                template: `#ccpn`,
                methods: {
                  getFather() {
                    console.log(this.$parent);
                  },
                  getRoot() {
                    console.log(this.$root)
                  }
                }
              }
            }
          }
        }
      });
    </script>
</body>
posted @ 2021-09-09 09:53  JSW79  阅读(7)  评论(0)    收藏  举报
隐藏目录