Vue中的组件

Vue组件化

组件的使用步骤

调用Vue.extend()创建一个组件构造器,在创建构造器时传入需要使用的template模板即HTML复用的代码。然后调用Vue.component()将组件构造器注册为一个组件,并给组件取一个标签名称。使用组件的标签名在挂载的Vue实例元素下使用即可。

  1. 创建组件构造器对象

    //1.创建组件构造器对象
    const cpnC = Vue.extend({
      template: `<div>
                    <h2>组件标题</h2>
                    <p>组件内容</p>
                 </div>`
    })
    
  2. 注册组件

    //2.注册组件
    Vue.component('my-component', cpnC)
    
  3. 使用组件

    <div id="app">
      <my-component></my-component>
    </div>
    

效果截图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8d9QgklX-1608995452504)(C:%5CUsers%5C13536%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20201226182053795.png)]


全局组件

全局组件可以在多个Vue实例中使用,通过Vue.component()注册的组件为全局组件


局部组件

在Vue实例中注册的组件为局部组件,只能在注册的实例中进行使用,使用components来注册组件

const cpnC = Vue.extend({
    template: `<div>
                  <h2>组件标题</h2>
                  <p>组件内容</p>
               </div>`
  })

const app = new Vue({
  el: '#app',
  components: {
    //组件名: 组件构造器名
    cpn: cpnC
  }
})

父子组件

如果想在组件中使用其它的组件,这两个组件就为父子关系。先创建子组件,然后再创建父组件,在父组件中使用compoents注册子组件就可以在template中使用子组件

<div id="app">
  <cpn-father></cpn-father>
</div>

<script src="../js/vue.js"></script>
<script>
  //子组件
  const cpnChild = Vue.extend({
    template: `<div><h1>子组件标题</h1><p>子组件内容</p></div>`
  })

  //父组件
  const cpnFather = Vue.extend({
    //在父模板中使用子组件
    template: `<div>
                <h1>父组件标题</h1>
                <p>父组件内容</p>
                <cpn-child></cpn-child>
               </div>`,
    //在父组件中注册子组件
    components: {
      cpnChild
    }
  })

  const app = new Vue({
    el: '#app',
    components: {
      //注册父组件
      cpnFather
    }
  })
</script>

效果


注册组件的语法糖

// 全局组件注册语法糖
Vue.component('cpn', {
  template: `<div><h1>组件标题</h1></div>`
})

//局部组件注册语法糖
const app = new Vue({
    el: '#app',
    components: {
      cpn: {
        template: `<div><h1>组件标题</h1></div>`
      }
    }
  })

组件模板的抽离

使用<template>标签并指定id进行对模板的抽离,注册组件时通过id指定模板

<template id="myCpn">
  <div>
    <h1>组件标题</h1>
    <p>组件内容</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    components: {
      myCpn: {
        //通过id指定模板
        template: '#myCpn'
      }
    }
  })

组件中的数据

如果想要在组件中存放数据,应该使用data()函数精选存储,而不是data属性,让组件创建时保证数据的封闭。

<template id="myTemplate">
  <div>
    <h1>{{title}}</h1>
    <p>{{content}}</p>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    components: {
      myCpn: {
        template: '#myTemplate',
        //在组件中使用data()函数存放数据
        data() {
          return {
            title: "组件标题",
            content: "组件内容"
          }
        }
      }
    }
  })
</script>

组件的通信

父子组件通信需要使用两种方法,一个是使用props向子组件传递数据,另一个是通过事件向父组件发送消息。

父子组件的通信

父传子props

在子组件中使用props声明需要的变量,在使用组件时使用v-bind对参数进行绑定

<div id="app">
  <!-- 通过v-bind将父组件与子组件中的变量进行绑定 -->
  <cpn v-bind:c-message="message" :c-movies="movies"></cpn>
</div>

<!-- 子组件模板 -->
<template id="myTemplate">
  <div>
    <h1>{{cMessage}}</h1>
    <ul>
      <li v-for="item in cMovies">{{item}}</li>
    </ul>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  //子组件
  const cpn = {
    template: '#myTemplate',
    //父传子声明变量
    props: ['cMovies', 'cMessage']
  }

  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js',
      movies: ["《信条》", "《你的名字》", "《让子弹飞》", "《阿甘正传》", "《盗梦空间》"]
    },
    //注册子组件
    components: {
      cpn
    }
  })
</script>

props中可以使用数组进行对变量的声明,也可以使用对象的形式对数据进行限制或默认值。

注意:数组类型或对象类型的默认值必须是一个default()函数

props: {
      cMessage: {
        //类型
        type: String,
        //默认值
        default: "暂无数据",
        //必须传递,否则报错
        required: true
      },
      cMovies: {
        type: Array,
        //default函数指定默认值
        default() {
          return ['暂无数据']
        },
        required: true
      }
    }

子传父$emit Events

子组件通过this.$emit('name', parms)发送自定义事件,父组件通过v-on监听子组件发送的自定义事件来实现子组件向父组件通信的过程。

<div id="app">
  <!-- 监听子组件发送的事件 -->
  <cpn @item-click="cpnClick"></cpn>
</div>

<template id="myTemplate">
  <div>
    <button v-for="item in categories"
            @click="btnClick(item)">{{item.name}}</button>
  </div>
</template>

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

  //子组件
  const cpn = {
    template: '#myTemplate',
    methods: {
      btnClick(item) {
        //发送自定义事件
        this.$emit('item-click', item);
      }
    },
    data() {
      return {
        categories: [
          {id: '001', name: "热门推荐"},
          {id: '002', name: "手机数码"},
          {id: '003', name: "家用家电"},
          {id: '004', name: "电脑办公"},
        ]
      }
    }
  }

  const app = new Vue({
    el: '#app',
    methods: {
      cpnClick(item) {
        alert("你选择了:" + item.name);
      }
    },
    //注册子组件
    components: {
      cpn
    }
  })
</script>

父子组件双向绑定

实际上是通过子组件向父组件发送事件进而修改父组件中data中的数据

<div id="app">
  <h1>父组件</h1>
  <p>num:{{num}}</p>
  <p>msg:{{msg}}</p>
  <hr>
  <!-- 绑定数据 并且 监听事件 -->
  <cpn :message="msg"
       @message-change="msgChange"></cpn>
</div>

<template id="myTemplate">
  <div>
    <h1>子组件</h1>
    <p>message:{{dataMessage}}</p>
    <input type="text" :value="dataMessage" @input="messageInput">
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      msg: "Hello world"
    },
    methods: {
      msgChange(value) {
        this.count = value;
      }
    },
    //子组件
    components: {
      cpn: {
        template: '#myTemplate',
        //父组件传输数据
        props: {
          message: String
        },
        //存储数据
        data() {
          return {
            dataMessage: this.message
          }
        },
        //事件
        methods: {
          messageInput(event) {
            //子组件的双向绑定
            this.dataMessage = event.target.value;
            //向父组件发送数据
            this.$emit('message-change', this.dataMessage);
          }
        }
      }
    }
  })
</script>

父子组件的直接获取

直接获取即在父组件或子组件中直接获取到子组件或父组件的对象,进而访问起属性和方法。

父组件获取子组件

父组件可使用$children$refs获取子组件。

this.$children是一个数组,它包含了当前组件下所有的子组件,可通过遍历的形式获取需要的子组件。

this.$refs是一个子组件对象,需要指定组件的ref,通过$refs.xxx获取对应的组件,从而不需要遍历

<div id="app">
  <cpn></cpn>
  <button @click="btnClick">访问子组件</button>
</div>

<template id="myTemplate">
  <div>
    <h1>子组件</h1>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    methods: {
      btnClick() {
        //访问子组件的showMessage的方法
        this.$children[0].showMessage();
      }
    },
    //注册子组件
    components: {
      cpn: {
        template: '#myTemplate',
        data() {
          return{
            message: "Hello Vue.js"
          }
        },
        methods: {
          showMessage() {
            alert(this.message);
          }
        }
      }
    }
  })
</script>

使用refs

<cpn ref="cpn"></cpn>

调用形式

this.$refs.cpn.showMessage();

子组件获取父组件

子组件可以使用$parent获取父组件。

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

<template id="myTemplate">
  <div>
    <h1>子组件</h1>
    <button @click="btnClick">访问父组件</button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js'
    },
    //注册子组件
    components: {
      cpn: {
        template: '#myTemplate',
        methods: {
          btnClick() {
            //访问父组件
            alert(this.$parent.message);
          }
        }
      }
    }
  })
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值