前言:常规问题
什么是组件:
- 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
为什么组件中data必须是函数:
//伪代码var Component = functionComponent() {};Component.prototype.data = {demo: 123}var component1 = new Component();var component2 = new Component();component1.data.demo = 456;console.log(component2.data.demo); // 456
- 从上面可以看出,两个实例都引用同一个对象,其中一个改变的时候,另一个也发生改变。
- 每一个vue组件都是一个vue实例,通过new Vue()实例化,引用同一个对象,如果data直接是一个对象的话,那么一旦修改其中一个组件的数据,其他组件相同数据就会被改变。
- 而data是函数,并且在函数中return一个独立对象的时候,每个vue组件的data都因为函数有了自己的作用域,互不干扰。
一、组件使用
1.1 局部组件
- 创建页面组件

- 引用
1.2 全局组件
在src根目录下创建全局组件
然后在main.js下引入就行
import Item from '../components/Item.vue'Vue.component("Item",Item)
二、组件传值
2.1 父组件传子组件
一、定义一个子组件
1.组件的名字是以大写字母开头的2.驼峰命名//1.components/HomeTable.vue<template><div><div><span>name:张三</span><span>age:18</span></div></div></template><script>export default {name: "HomeTable"};</script><style></style>
二、在app.vue中导入子组件
<script>//2.导入子组件import HomeTable from './components/HomeTable'export default {name: 'app',....//3.需要在components属性中注册components:{HomeTable}}</script>//4.在模板中使用<template><div id="app">...//可以使用下划线命名使用<home-table ></home-table></div></template>
三、父组件向子组件传值
父组件://1.子组件通过属性接收父组件传递的参数<home-table :data="arr"></home-table>子组件://2.子组件接收的参数需要在props属性中注册<script>export default {name: "HomeTable",props: {data: {type: Array}}};</script>
- 传多个值的情况
```javascript
父组件:
子组件接收 props:{ data:{ type:Object, }, index:{ type:Number } }
父组件传子组件:<br />父组件:<br />子组件:<br /><a name="FNylQ"></a>#### 四、子组件自定义事件向父组件传参原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;```javascript子组件://1.使用$emit方式自定义事件,向父组件传参<button @click="handleDelete(index)">删除</button><script>export default {...methods:{handleDelete(index){this.$emit("deleteItem",index)}}};</script>父组件://2.父组件接收子组件传递过来的事件参数<home-table :data="arr" @deleteItem="handleDelete"></home-table><script>import HomeTable from './components/HomeTable'export default {name: 'app',...methods:{handleDelete(index){console.log(index)}}}</script>
2.2 跳转页面传id
第一种:页面直接跳转


第二种:子组件获取id 通过子组件自定义事件传参回父组件跳转
子组件
三、组件通讯
3.1 单向数据流
props/$emit
父组件A通过props的方式向子组件B传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。
1.父组件向子组件传值
2.子组件向父组件传值(通过事件形式)
子组件通过this.$emit(“methodName”,data),父组件定义同名方法即可。
子组件定义
父组件接收
3.2 双向数据流
子组件
父组件
四、中央事件总线
中央事件总线 :
就是一个名字可以叫做Bus的vue空实例,里边没有任何内容。
它就像一个公交车一样,来回输送人,将组件A输送到组件B,再将组件B输送到组件A;
这里A,B组件可以是父、子组件,也可以是兄、弟组件,或者两个没有任何关系的组件;
我们可以使用中央事件总线这种技术来实现vue组件之间的数据通信。
//1.创建中央事件总线var bus = new Vue();//A组件发送//2.使用Bus中央事件总线在A组件中发送信息Bus.$emit('自定义事件名','$on发送过来的数据');//B组件接收//3.使用Bus中央事件总线在B组件中接收信息Bus.$on('自定义事件名',function(){//然后执行什么你自己懂的。。。});
五、动态组件切换
//1.定义组件//2.引入组件和data关联<template><div><button @click="handleToggle">toggle</button><component :is="isToggle?one:two"></component></div></template><script>import One from "../components/One.vue";import Two from '../components/Two.vue'export default {data() {return {isToggle:false,one: "One",two:"Two"};},components: {One,Two},methods:{handleToggle(){this.isToggle = !this.isToggle}}};</script>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script><style>.v-enter,.v-leave-to {opacity: 0;transform: translateX(150px);}.v-enter-active,.v-leave-active {transition: all 0.5s ease;}</style></head><body><div id="app"><a href="" @click.prevent="comName='login'">登录</a><a href="" @click.prevent="comName='register'">注册</a><!-- Vue提供了 component ,来展示对应名称的组件 --><!-- component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称 --><!-- 通过 mode 属性,设置组件切换时候的模式,out-in 表示原先的组件先出去,后来的组件再进来 --><transition mode="out-in"><component :is="comName"></component></transition></div><script>// 组件名称是 字符串Vue.component('login', {template: '<h3>登录组件</h3>'})Vue.component('register', {template: '<h3>注册组件</h3>'})// 创建 Vue 实例,得到 ViewModelvar vm = new Vue({el: '#app',data: {comName: 'login' // 当前 component 中的 :is 绑定的组件的名称},methods: {}});</script></body></html>
