Vue组件化

本文详细介绍了Vue.js中组件的创建过程,包括全局组件和局部组件的注册,以及父子组件间的通信方法。内容涵盖组件构造器、模板定义、属性限制与默认值、事件传递等核心概念,同时探讨了组件数据的独立性和模板分离写法,旨在深入理解Vue.js组件系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建-----------》注册一般都是局部组件
在这里插入图片描述
在这里插入图片描述


流程


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

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

在这里插入图片描述
在这里插入图片描述


全局组件、局部组件

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

全局组件

Vue.component('my-cpn', cpnC)//调用

局部组件

const app=new Vue({
 el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      // cpn使用组件时的标签名
      cpn: cpnC
    }
})

父子组件

  // 1.创建第一个组件构造器(子组件)
  const cpnC1 = Vue.extend({
    template: `
      <div>
        <h2>我是标题1</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })


  // 2.创建第二个组件构造器(父组件)
  const cpnC2 = Vue.extend({
    template: `
      <div>
        <h2>我是标题2</h2>
        <p>我是内容, 呵呵呵呵</p>
        <cpn1></cpn1>
      </div>
    `,
    components: {
      cpn1: cpnC1
    }
  })

Vue实例它会在自己局部里先找,找不到再去全局组件,它本身并不知道cpn1组件内容,未被挂载到app实例中,直接在app 根dom下使用不被认为是一个组件/

root根组件

  // root组件
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn2: cpnC2
    }
  })

语法糖注册组件,其内部会执行Vue.extend:

//全局
  Vue.component('cpn1', {  
    template: `
      <div>
        <h2>我是标题1</h2>
        <p>我是内容, 哈哈哈哈</p>
      </div>
    `
  })
  //局部
    const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      'cpn2': {
        template: `
          <div>
            <h2>我是标题2</h2>
            <p>我是内容, 呵呵呵</p>
          </div>
    `
      }
    }
  })

组件模板的分离写法
在这里插入图片描述

1.script标签, 注意:类型必须是text/x-template

<script type="text/x-template" id="cpn">
<div>
  <h2>我是标题</h2>
  <p>我是内容,哈哈哈</p>
</div>
</script>
//两个不同script里面
<script>
  Vue.component('cpn', {
    template: '#cpn',
    data() {
      return {
        title: 'abc'
      }
    }
  })
</script>

注意:组件中的内部不可以直接访问Vue的实例数据,即使能访问也不能这样做,随着体量的增多,不适合直接放到root根组件

组件内部的data属性,其内部必须是函数类型,对象会报错

data(){
return {}
}

这是因为要保证每次返回都是一个新对象,每个组件的data对象都彼此相互不影响


组件通信


在这里插入图片描述

在这里插入图片描述

  const cpn = {
    template: '#cpn',
    // props: ['cmovies', 'cmessage'],
    props: {
      // 1.类型限制
      // cmovies: Array,
      // cmessage: String,

      // 2.提供一些默认值, 以及必传值
      cmessage: {
        type: String,
        default: 'aaaaaaaa',
        required: true
      },
      // 类型是对象或者数组时, 默认值必须是一个函数
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
    },
    data() {
      return {}
    },
    methods: {

    }
  }

vue2…17以后默认值需用函数返回
在这里插入图片描述
type可以是自定义数据类型,自定义的一个对象

驼峰使用,一般子组件使用直接c+父属性名,cinfo====>info
或者使用驼峰时,在传的过程应-相连,c-info、child-my-message

<div id="app">
  <cpn :c-info="info" :child-my-message="message" v-bind:class></cpn>
</div>

<template id="cpn">
  <div>
    <h2>{{cInfo}}</h2>
    <h2>{{childMyMessage}}</h2>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  const cpn = {
    template: '#cpn',
    props: {
      cInfo: {
        type: Object,
        default() {
          return {}
        }
      },
      childMyMessage: {
        type: String,
        default: ''
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      info: {
        name: 'why',
        age: 18,
        height: 1.88
      },
      message: 'aaaaaa'
    },
    components: {
      cpn
    }
  })

子传父

<!--父组件模板-->
<div id="app">
  <cpn @item-click="cpnClick"></cpn>
</div>

<!--子组件模板-->
<template id="cpn">
  <div>
    <button v-for="item in categories"
            @click="btnClick(item)">
      {{item.name}}
    </button>
  </div>
</template>

// 1.子组件

  const cpn = {
    template: '#cpn',
    data() {
      return {
        categories: [
          {id: 'aaa', name: '热门推荐'},
          {id: 'bbb', name: '手机数码'},
          {id: 'ccc', name: '家用家电'},
          {id: 'ddd', name: '电脑办公'},
        ]
      }
    },
    methods: {
      btnClick(item) {
        // 发射事件: 自定义事件
        this.$emit('item-click', item)
      }
    }
  }

// 2.父组件

  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn
    },
    methods: {
      cpnClick(item) {
        console.log('cpnClick', item);
      }
    }
  })

注意:子传父时:需要调用事件this.emit(“itemClick”,item)
//itemClick为父组件自定义事件,非脚手架情况下用驼峰命名父组件事件可能会出现问题,建议一个单词或者‘-’连接

在这里插入图片描述
$children:[]
$refs最常用:{}

<div id='app'>
<cpn ref='aaa'></cpn>
<button @click='btnclick'>111</button>
</div>

<template id='cpn'><template>

<script>
const app= new Vue({
el:"#app",
data:{},
methods:{
btnclick(){
console.log(this.$ref.aaa)
}
}
compontents:{
cpn:{
template:"#cpn",
data(){

},
methods:{
showMessage(){
console.log('asas')
}
}
}
})
</script>	

在这里插入图片描述
子访问父组件

 // 1.访问父组件$parent
                // console.log(this.$parent);
  const app = new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name: '我是cpn组件的name'
          }
        },
        components: {
          ccpn: {
            template: '#ccpn',
            methods: {
              btnClick() {
                // 1.访问父组件$parent
                // console.log(this.$parent);
                // console.log(this.$parent.name);

                // 2.访问根组件$root
                console.log(this.$root);
                console.log(this.$root.message);
              }
            }
          }
        }
      }
    }
  })

在这里插入图片描述

  // 2.访问根组件$root
                console.log(this.$root);
                console.log(this.$root.message);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值