组件

全局组件

1<template>
2  <div>
3    <!-- 3.调用组件 -->
4    <globalComponent />
5    <global-component />
6  </div>
7</template>
8<!-- 1.定义模版 -->
9<template id="global">
10  <div>我是全局组件</div>
11</template>
12<script>
13import Vue from "vue";
14// 2.注册组件
15Vue.component("globalComponent", {
16  template: "#global",
17});
18export default {
19  data() {
20    return {};
21  }
22};
23</script>

局部组件

1<template>
2  <div>
3    <!-- 3.调用组件 -->
4    <localComponent title="标题" />
5    <local-component />
6  </div>
7</template>
8<!-- 1.定义模版 -->
9<template id="local">
10  <div>{{ title }}</div>
11</template>
12<script>
13export default {
14  data() {
15    return {};
16  },
17  // 2.注册组件
18  components: {
19    localComponent: {
20      template: "#local",
21      // props:["title"]
22      
23      props:{
24      	title:{
25      default:"默认值",
26      type:String
27    		}
28    	}
29    },
30  },
31};
32</script>

动态组件

动态组件其实可以认为是组件的占位,在使用组件的时候,不直接使用组件名的形式而是使用一个内置的标签

:is 的值是一个变量,这个变量是哪个组件名,该元素所占的位置就加载并渲染哪个组件

1<div id="app">
2  <component :is="变量"></component>
3</div>

组件传值

组件之间是不能通讯的(默认数据是不能互相使用的)

父传子

1<template>
2  <div>
3    <h1>我是父组件</h1>
4    <son-comp :father="father"></son-comp>
5  </div>
6</template>
7
8<script>
9import sonComp from "./sonComp.vue";
10export default {
11  data() {
12    return {
13      father: "父组件data",
14    };
15  },
16  components: {
17    sonComp,
18  },
19};
20</script>
1<template>
2  <div>
3    <h1>我是子组件</h1>
4    <h2>我是子组件,我在使用{{ father }}</h2>
5  </div>
6</template>
7
8<script>
9export default {
10  data() {
11    return {};
12  },
13  props: {
14    father: {
15      default: "",
16      type: String,
17    },
18  },
19};
20</script>

子传父

在子组件中通过this.$emit('自定义事件名',参数) 来触发自定义事件,从而执行父组件的函数

什么时候会用到子传父??

修改父组件数据的时候

1<template>
2  <div>
3    <h1>我是父组件</h1>
4    <h2>我接收了{{ sonData }}</h2>
5    <son-comp @father="fn"></son-comp>
6  </div>
7</template>
8
9<script>
10import sonComp from "./sonComp.vue";
11export default {
12  data() {
13    return {
14      sonData: "",
15    };
16  },
17  components: {
18    sonComp,
19  },
20  methods: {
21    fn(value) {
22      console.log("子组件data", value);
23      this.sonData = value;
24    },
25  },
26};
27</script>
1<template>
2  <div>
3    <h1>我是子组件</h1>
4    <button @click="send">发送</button>
5  </div>
6</template>
7
8<script>
9export default {
10  data() {
11    return {
12      son: "子组件的data",
13    };
14  },
15  methods: {
16    send() {
17      this.$emit("father", this.son);
18    },
19  },
20};
21</script>

插槽

插槽的作用:就是可以让我们封装的组件更灵活,可以让使用组件的人去决定组件中出现的内容,通常把组件的灵活不确定的内容使用slot标签进行占位,在使用组件的时候 在组件标签中间给插槽设置内容。

匿名插槽

<slot></slot>

默认情况下,浏览器不会渲染在子组件标签内插入的内容,这个时候就需要在子组件中定义 solt 插槽来接收插入的内容,slot 插槽的位置就是后续插入内容渲染的位置。

1<template>
2  <div>
3    <h1>我是父组件</h1>
4    <son-comp>
5      <h2>我是子组件匿名插槽要渲染的内容</h2>
6    </son-comp>
7  </div>
8</template>
9
10<script>
11import sonComp from "./sonComp.vue";
12export default {
13  data() {
14    return {};
15  },
16  components: {
17    sonComp,
18  },
19};
20</script>
1<template>
2  <div>
3    <h1>我是子组件</h1>
4    <slot></slot>
5  </div>
6</template>
7
8<script>
9export default {
10  data() {
11    return {};
12  },
13};
14</script>

具名插槽

<slot name=""></slot>

slot 标签添加上name属性,相当于给插槽起名字,称为具名插槽。

为子组件标签内插入的内容添加slot属性,其值为name的值,这样就可以将该内容与name属性对应的插槽绑定。

1<template>
2  <div>
3    <h1>我是父组件</h1>
4    <son-comp>
5      <h2 slot="son">我是子组件具名插槽的title</h2>
6      <h2>我是匿名插槽要渲染的内容</h2>
7    </son-comp>
8  </div>
9</template>
10
11<script>
12import sonComp from "./sonComp.vue";
13export default {
14  data() {
15    return {};
16  },
17  components: {
18    sonComp,
19  },
20};
21</script>
1<template>
2  <div>
3    <h1>我是子组件</h1>
4    <slot name="son"></slot>
5    <slot></slot>
6  </div>
7</template>
8
9<script>
10export default {
11  data() {
12    return {};
13  },
14};
15</script>

作用域插槽

slot-scope 属性专门收集所在标签对应slot插槽身上的属性为自己用

1<template>
2  <div>
3    <h1>我是父组件</h1>
4    <son-comp>
5      <h2 slot="son" slot-scope="obj">
6        我是 {{ obj.title }} 的title {{ obj.sonNum }}
7      </h2>
8    </son-comp>
9  </div>
10</template>
11
12<script>
13import sonComp from "./sonComp.vue";
14export default {
15  data() {
16    return {};
17  },
18  components: {
19    sonComp,
20  },
21};
22</script>
1<template>
2  <div>
3    <h1>我是子组件</h1>
4    <slot name="son" :sonNum="num" title="子组件具名插槽"></slot>
5  </div>
6</template>
7
8<script>
9export default {
10  data() {
11    return {
12      num: 100,
13    };
14  },
15};
16</script>

作用域插槽的多种写法

1// 1.基本写法
2<son-comp>
3	<h2 slot="title" slot-scope="obj">
4		我是 {{ obj.title }} 的title {{ obj.sonNum }}
5	</h2>
6</son-comp>
7
8// 2.模版写法
9<son-comp>
10	<template slot="title" slot-scope="obj">
11  	<h2>我是 {{ obj.title }} 的title {{ obj.sonNum }}</h2>
12  </template>
13</son-comp>
14
15// 3.指令写法
16<son-comp v-slot:son="obj">
17  <h2 >我是 {{ obj.title }} 的title {{ obj.sonNum }}</h2>
18</son-comp>
19
20// 4.指令的模版写法
21<son-comp>
22	<template v-slot:son="obj">
23		<h2 >我是 {{ obj.title }} 的title {{ obj.sonNum }}</h2>
24	</template>
25</son-comp>