Vue全家桶(二)之组件化开发

本文详细介绍了Vue的组件化开发,包括组件的基础概念、全局与局部组件的注册、组件数据存放的注意事项以及组件间数据交互的方法。通过实例展示了如何创建、注册和使用组件,以及如何通过props和自定义事件实现父子组件和非父子组件之间的通信。此外,还探讨了组件插槽的使用,包括默认插槽、具名插槽和作用域插槽,帮助理解如何在组件中插入和定制内容。
摘要由CSDN通过智能技术生成

🔥Vue全家桶🔥

Vue全家桶地址
Vue全家桶(一)之基础指令🔥https://blog.csdn.net/m0_55990909/article/details/123917809
Vue全家桶(一)之常用特性🔥https://blog.csdn.net/m0_55990909/article/details/123917352
Vue全家桶(二)之组件化开发🔥https://blog.csdn.net/m0_55990909/article/details/123957131
Vue全家桶(三)之cli3脚手架🔥https://blog.csdn.net/m0_55990909/article/details/123956982
Vue全家桶(四)之ES6模块化与webpack打包🔥https://blog.csdn.net/m0_55990909/article/details/124019983
Vue全家桶(五)之Vue-Router路由🔥https://blog.csdn.net/m0_55990909/article/details/123994048
Vue全家桶(六)之VueX状态管理🔥https://blog.csdn.net/m0_55990909/article/details/124017667
Vue接口调用(一)fetch用法https://blog.csdn.net/m0_55990909/article/details/123957200
Vue接口调用(二)axios用法🔥https://blog.csdn.net/m0_55990909/article/details/123981283
Vue接口调用(三)async/await用法🔥https://blog.csdn.net/m0_55990909/article/details/123981292

🔥Vue组件化开发🔥

组件化开发地址
🔥Vue组件化开发https://blog.csdn.net/m0_55990909/article/details/123957131
🔥Vue组件化开发-单文件组件https://blog.csdn.net/m0_55990909/article/details/123957171

目录总览:(组件化概念、组件注册、数据存放、组件数据共享、组件插槽、使用步骤)

一、组件化概念

1. 组件化开发思想

组件化思想的特点:标准、分治、复用、组合

2. 组件定义

 **组件化**开发:根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。

3. Vue中的组件化开发

 **vue** 是一个**支持组件化开发的前端框架**。

 **vue** 中规定:**组件的后缀名是 .vue**。之前接触到的 App.vue 文件本质上就是一个 vue 的组件,即**单组件**(单文件组件)。

4. Vue组件的三个组成部分

每个 .vue 组件都由 3 部分构成,分别是:

  • template -> 组件的模板结构
  • script -> 组件的 JavaScript 行为
  • style -> 组件的样式

其中,每个组件中必须包含 template 模板结构,而 script 行为style 样式可选的组成部分。

二、组件注册

1. 全局组件🔥
//全局组件使用
<div id="app">
	<组件名称></组件名称>
</div>

//全局组件注册
Vue.component(组件名称, {
	data: 组件数据,
	template: 组件模板内容
})
  • 1.1 全局组件组件可以在app实例内部任意地方使用:我们可以在 app 实例下使用,也可以在 home 实例下使用,也可以在 message 实例下使用。
<body>
  <div id="app">
    <div id="home">
      <span>首页</span>
      <button-counter></button-counter>
    </div>
    <div id="message">
      <span>消息</span>
      <button-counter></button-counter>
    </div>
    <!--调用全局注册组件-->
    <button-counter></button-counter>
  </div>

  <script src="../js/vue.js"></script>
  <script>
     // 2.定义一个组件(全局组件)
     app.component('button-counter',{
       data() {
         return {
           count: 0
         }
       },
       template: `
        <button @click="count++">你点击了{{count}}次</button>`
     })
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          msg: '你好,Vue3!'
        }
      }
     });
     // 3. 挂载vue实例
     app.mount('#app'); 
  </script>
</body>

  • 1.2 可以设置多个全局组件,代码如下:
<body>
<div id="app">
  <div id="home">
    <span>首页</span>
    <button-counter></button-counter>
  </div>
  <div id="message">
    <span>消息</span>
    <button-counter></button-counter>
    <!--调用第二个注册组件-->
    <lk-box></lk-box>
  </div>
  <!--调用全局注册组件-->
  <button-counter></button-counter>
</div>

<script src="../js/vue.js"></script>
<script>
  // 1.创建Vue的实例对象
  const app = Vue.createApp({
    data(){
      return {
        msg: '你好,Vue3!'
      }
    }
  });

  // 2.定义一个组件(全局组件)
  app.component('button-counter',{
    data() {
      return {
        count: 0
      }
    },
    template: `
        <button @click="count++">你点击了{{count}}次</button>
       `
  })
  // 定义第二个全局组件
  app.component('lk-box',{
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子组件
        </div>
       `
  })

  // 3. 挂载vue实例
  app.mount('#app');
</script>
</body>

  • 1.3 全局组件之间可以相互使用,使用方式如下:我们在定义第二个全局组件,若向使用第一个全局组件,只需要将第一个全局组件的名称标签写入模板template中即可。
// 定义第二个全局组件
app.component('lk-box',{
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子组件
        <button-counter></button-counter>
        </div>
       `
})

2. 局部组件🔥
  • 局部组件只能在注册他的父组件中使用
//局部组件使用
<div id="app">
    <ComponentA></ComponentA>
    <ComponentB></ComponentB>
    <ComponentC></ComponentC>
</div>

//局部组件注册
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
new Vue({
	el: '#app'
	components: {
		'component-a': ComponentA,
		'component-b': ComponentB,
		'component-c': ComponentC,
	}
})

实例:

//局部组件使用
<body>
<div id="app">
  <lk-count></lk-count>
  <cc-count></cc-count>
</div>

<script src="../js/vue.js"></script>
<script>
  // 注册一个局部组件
  const Counter = {
    data() {
      return {
        count: 0
      }
    },
    template: `
        <button @click="count++">你点击了{{count}}次</button>`
  }
  // 注册第二个局部组件
  const Box = {
    template: `
        <div style="width: 200px;height: 200px;background-color:pink;">
        盒子组件
        </div> `
  }
  // 创建Vue的实例对象
  const app = Vue.createApp({
    data(){
      return {
        msg: '你好,Vue3!'
      }
    },
    // 组件选项
    components: {
      'lk-count': Counter,
      'cc-count': Box
    }
  });
  // 挂载vue实例
  app.mount('#app');
</script>
</body>

3. 注意事项

1. data必须是一个函数

2. 组件模板内容必须是单个跟元素

3. 组件模板内容可以是模板字符串(需要浏览器提供ES6语法支持)

4. 组件命名方式

  • 短横线方式:
Vue.component('my-component', { /* ... */ })
  • 驼峰方式:
Vue.component('MyComponent', { /* ... */ })
4.总结
  • 全局组件:在整个Vue实例中都可以被调用,若想要全局组件之间相互使用,只需将想使用全局组件的名称写入 template

  • 局部组件:只能在当前组件中被使用,若想在其他组件中使用,必须使用 components 将其挂载在想使用的组件中,然后再如全局组件那样向模板template写入名称标签

  • 我们之后其实对局部组件用的更多一些。

三、组件数据存放

Data属性的值是一个函数🔥
  • 为什么data在组件中必须是一个函数呢?
    • 当然,如果不是一个函数,Vue直接就会报错。
    • 组件是可复用的vue实例,一个组件被创建好之后,就可能被用在各个地方
    • 而组件不管被复用了多少次,组件中的data数据都应该是相互隔离,互不影响的
    • 基于这一理念,组件每复用一次,data数据就应该被复制一次,之后,当某一处复用的地方组件内data数据被改变时,其他复用地方组件的data数据不受影响
    • 组件中的data写成一个函数数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据
    • 而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果

四、组件之间数据的交互共享

4.1 父组件向子组件传值🔥

1. 组件内部通过props接收传递过来的值

Vue.component(‘menu-item', {
	props: ['title'],
	template: '<div>{{ title }}</div>'
})

2. 父组件通过属性将值传递给子组件

<menu-item title="来自父组件的数据"></menu-item>
<menu-item :title="title"></menu-item>

3. props属性名规则

  • 在props中使用驼峰形式,模板中需要使用短横线的形式
  • 字符串形式的模板中没有这个限制
Vue.component(‘menu-item', {
	// 在 JavaScript 中是驼峰式的
	props: [‘menuTitle'],
	template: '<div>{{ menuTitle }}</div>'
})
<!– 在html中是短横线方式的 -->
<menu-item menu-title=“nihao"></menu-item>

4. props属性值类型

  • 字符串 String
  • 数值 Number
  • 布尔值 Boolean
  • 数组 Array
  • 对象 Object
4.2 子组件向父组件传值🔥

1. 子组件通过自定义事件向父组件传递信息

<button v-on:click='$emit("enlarge-text") '>扩大字体</button>

2. 父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize += 0.1'></menu-item>

3. 子组件通过自定义事件向父组件传递信息

<button v-on:click='$emit("enlarge-text", 0.1) '>扩大字体</button>

4. 父组件监听子组件的事件

<menu-item v-on:enlarge-text='fontSize += $event'></menu-item>
4.3 非父子组件间传值🔥

1. 单独的事件中心管理组件间的通信

var eventHub = new Vue()

2. 监听事件与销毁事件

eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')

3. 触发事件

eventHub.$emit(‘add-todo', id)

五、组件插槽

5.1 组件插槽的作用
  • 插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。

  • 父组件向子组件传递内容

5.2 组件插槽基本用法
//插槽的使用
<div id="app">
    <alert-box>有bug发生</alert-box>
    <alert-box>有一个警告</alert-box>
    <alert-box></alert-box>
</div>
//插槽的定义
Vue.component('alert-box', {
      template: `
        <div>
          <strong>ERROR:</strong>
          <slot>默认内容</slot>
        </div>`
});

5.3 具名插槽用法
//具名插槽的使用
<div id="app">
	//第一种:当具名插槽内只有1个标签
    <base-layout>
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>
    
    //第二种:当具名插槽内需要填充多个标签
    <base-layout>
      <template slot='header'>
        <p>标题信息1</p>
        <p>标题信息2</p>
      </template>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>
    </base-layout>
</div>

//具名插槽的定义
Vue.component('base-layout', {
      template: `
        <div>
          <header>
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name='footer'></slot>
          </footer>
        </div>`
});

5.4 作用域插槽
//作用域插槽的使用
<fruit-list v-bind:list= "list">
	<template slot-scope="slotProps">
		<strong v-if="slotProps.item.current">
			{{ slotProps.item.text }}
		</strong>
	</template>
</fruit-list>

//作用域插槽的定义
<ul>
	<li v-for= "item in list" v-bind:key= "item.id" >
		<slot v-bind:item="item">
			{{item.name}}
		</slot>
	</li>
</ul>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值