前言
- 掌握组件的创建方式
- 掌握插槽的使用方法
1、什么是vue组件?
组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可。
组件化和模块化的不同:
- 模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
- 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
2、全局组件的定义的四种方式
最后按照标签的方式写在定义好的view层里面
<div id="app">
<temname1></temname1>
<methods></methods>
<register></register>
<footer1></footer1>
</div>
注意:
1不能使用驼峰命名
2不要使用内置或保留的HTML元素作为组件id: footer
3 只能有一个根元素
1.1 使用 Vue.extend 配合 Vue.component 方法:
let tep1 = Vue.extend({
template: "<div> 我是第一个<div>22</div><div>33</div></div>"
})
// 然后全局注册一个组件,参数1:名字,参数二: 模板 当做标签使用
Vue.component("temname1", tep1)
1.2 直接使用 Vue.component 方法:
// 方法2: 直接吧template单独拿出来当做一个对象
Vue.component("methods", {
template: "<h1>我是h1</h1>"
})
1.3 将模板字符串,定义到script标签种:
<!-- 方法3 单独声明一个script标签 -->
<script id="teme1" type="x-template">
<div>
<h2>我显示了</h2>
<h3>我又显示了</h3>
</div>
</script>
// 方法3: 定义一个模板
Vue.component("register", {
template: "#teme1",
});
1.4 最常用的一种方式 使用template标签
<!-- 方法4: 最常用的一个发发!!!!!!!!!!!!!!! -->
<template id="teme2">
<div>这是最常用的方式</div>
</template>
Vue.component("footer1", {
template: "#teme2",
})
3.组件的数据和事件
在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;
【重点】为什么组件中的data属性必须定义为一个方法并返回一个对象?
// 定义一个component 全局的组件 必须放在script前面
Vue.component("course", {
template: "#course",
data() {
return {
// 当data是一个函数并且返回一个对象时,每次使用一次组件就会返回一个新的对象
// 这样可以保证组件内部数据的独立性。不会随着一个组件数据的改变而改变
num: 7,
};
},
methods: {
add() {
this.num++;
},
},
})
// 定义一个私有组件 局部使用
const vm2 = new Vue({
el: "#app1",
data: {},
methods: {},
components: { //定义子组件
local: { //组件 也是再视图层 当做标签 展示在上面
template: "<h1>我再子组件里面 出现了 {{num2}} </h1>", //使用已定义的子组件
data() {
return {
num2: 6
}
}
}
}
})
4.利用flag标识符和v-if v-else切换组件
定义的组件 相比较与 new vue 是一个小的实例化组件,使用时,放在script标签的开头 进行声明。
Vue.component("login", {
template: "#login",
data() {
return {}
},
methods: {},
created() { },
beforeDestroy() {
console.log("我快要被销毁了");
},
destroyed() {
console.log("我被毁灭了");
}
});
5.使用:is属性来切换不同的子组件,并添加切换动画
使用component标签,来引用组件,并通过:is属性来指定要加载的组件:
<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='register'">注册</a>
<hr>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
6.插槽
什么是插槽?
插槽就是子组件中的提供给父组件使用的一个占位符,用 slot /slot 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
总结:如果子组件没有使用插槽,父组件如果需要往子组件中填充模板或者html, 是没法做到的
6.1 插槽的使用方法
- 在子组件中放一个占位符
- 在父组件中给这个占位符填充内容:
6.2 插槽的使用 - 具名插槽
描述:具名插槽其实就是给插槽娶个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。
<course>
免费课程
<!-- <template v-slot:header>
<div>这是头部</div>
</template>
<!-- 插槽,占位 -->
<!-- <slot name="header"></slot> -->
6.3 插槽的使用 - 默认插槽
描述: 默认插槽就是指没有名字的插槽,子组件未定义的名字的插槽,父级将会把 未指定插槽的填充的内容填充到默认插槽中。
注意:
1. 父级的填充内容如果指定到子组件的没有对应名字插槽,那么该内容不会被填充到默认插槽中。
2. 如果子组件没有默认插槽,而父级的填充内容指定到默认插槽中,那么该内容就“不会”填充到子组件
的任何一个插槽中。
3. 如果子组件有多个默认插槽,而父组件所有指定到默认插槽的填充内容,将“会” “全都”填充到子组件
的每个默认插槽中。
6.4 父组件传值子组件
接受父组件传值
设置props属性就可以接受父组件传值
<template id="father">
<div>
我是父组件
<!-- 父传子 pagesize props-->
<!-- 子传父 fromfather="fromson" 父亲方法中的fromson来接受子组件的zhi -->
<son @fromfather="fromson" pagesize="13"></son>
这是从子组件传过来的内容:{{msg}}
</div>
</template>
子组件中:props:{
sonAcceptValueName:{
type:[Number,String,Object]/String
default:10
}
}
props: {
// 规定了父组件只能传对象类型
prop1:Object
// 可以设置多个类型,可以传Number也可以传String
parentMsg: [Number, String],
list: {
// 设置类型
type: Array,// [Array,String]
// 设置默认值的时候必须使用函数,原理和data必须使用函数是一样的
default: function () {
return [{
name: '这个一个默认的名字'
}]
}
},
}
6.5 子组件传值父组件
子组件调用父组件的方法
- 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
- 子组件可以触发这个事件$emit(‘事件名字’)
子组件给父组件传递数据
- $emit方法第二个参数可以定义子组件给父组件传递的内容
- 在父组件中怎么拿到这内容
2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到
2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过sevent只能传递第一个参数。
// 定义子组件
Vue.component("son", {
template: "#son",
data() {
return {
num: 77
}
},
methods: {
sendfather() {
console.log(111111);
this.$emit("fromfather", this.num)
}
}
})
// 定义父组件
Vue.component("father", {
template: "#father",
data() {
return {
msg: ""
}
},
methods: {
fromson(data) {
console.log(data);
this.msg = data
}
}
})
第二种方法
<div id="app">
<son v-on:click-son='clickParent($event,"自定义参数")' v-on:click-son2='clickParent2'></son>
</div>
属性的继承和传递
属性继承的特征:
父组件的属性会覆盖子组件的属性
class 和 style 会进行合并,不会覆盖
设置禁用继承
加在子组件上的属性,使用了这个属性之后会阻止组件继承父组件的属性,但是class和style除外
inheritAttrs: false
在组件内可以使用$attrs获取父组件传过来的属性
** 注意事项**
data和props的区别
data是组件私有的,props是父组件传过来的
data是可以修改的,props是只读的