1.vue组件
1.1组件化和模块化的不同:
- 模块化:是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
- 组件化:是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
1.2 全局组件定义的四种方式
1.使用 Vue.extend 配合 Vue.component 方法
2.直接使用 Vue.component 方法
3.将模板字符串,定义到script标签中,同时,需要使用 Vue.component 来定义组件
4.将模板字符串,定义到template标签中,同时,需要使用 Vue.component 来定义组件
<div id='app'>
<son4></son4>
</div>
<template id="son4">
<h2>hahaha</h2>
</template>
<script>
Vue.component('son4', {
template: '#son4'
})
const vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
1.3 组件中展示数据和响应事件
可以全局定义 和私有定义
组件中的data属性必须定义为一个方法并返回一个对象 目的: 数据隔离, 互不影响
<div id='app'>
<son></son>
<son1></son1>
{{msg3}}
</div>
<template id="son">
<div>
{{msg}}
<!-- 事件 -->
<input type="text" v-model="msg">
<button @click="addList">点击添加</button>
<div v-for="(item,index) in list" :key="index">{{item}}</div>
</div>
</template>
<template id="son1">
<div>{{msg1}}</div>
</template>
<script>
// 全局定义
Vue.component("son", {
template: "#son",
data() {
return {
msg: "哈哈哈哈",
list: [1, 2, 3, 4]
}
},
addList() {
this.list.push(this.msg);
}
})
// 私有定义
let son1 = {
template: "#son1",
data() {
return {
msg1: "啦啦啦"
}
}
}
const vm = new Vue({
el: '#app',
data: {
msg3: "嘎嘎嘎"
},
methods: {},
components: {
son1,
}
})
</script>
1.4切换组件
让子在父中展示
<div id='app'>
<father></father>
<component is="father"></component>
</div>
<template id="father">
<div>
父
<son></son>
</div>
</template>
<template id="son">
<div>子</div>
</template>
<script>
let son = {
template: "#son"
}
let father = {
template: "#father",
components: {
son
}
}
const vm = new Vue({
el: '#app',
data: {},
methods: {},
components: {
father,
son
},
created() {
console.log(11111);
}
})
</script>
1.5 使用:is属性来切换不同的子组件,并添加切换动画
<div id='app'>
<button @click="changefather">切换父</button>
<button @click="changeson">切换子</button>
<transition mode="out-in">
<component :is="componentId"></component>
</transition>
</div>
<template id="father">
<div>父</div>
</template>
<template id="son">
<div>子</div>
</template>
<script>
let son = {
template: "#son",
data() {
return {}
},
methods: {},
//created() {
// console.log(111);
//},
//beforeDestroy() {
// console.log(222);
//},
//destroyed() {
// console.log(333);
//}
}
let father = {
template: "#father",
complates: {
son
}
}
const vm = new Vue({
el: '#app',
data: {
componentId: "father"
},
methods: {
changefather() {
this.componentId = "son"
},
changeson() {
this.componentId = "father"
}
},
components: {
father,
son
}
})
</script>
<style>
.v-enter,
.v-leave-to {
transform: translateX(200px);
}
.v-enter-active,
.v-leave-active {
transition: all 1s;
}
.v-enter-to,
.v-leave {
transform: translateX(0px);
}
</style>
2.slot插槽
2.1 什么是插槽?
插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签。
如果子组件没有使用插槽,父组件如果需要往子组件中填充模板或者html, 是没法做到的
2.2 插槽的使用
1) 在子组件中放一个占位符
2)在父组件中给这个占位符填充内容
3) 展示效果
2.3 具名插槽
具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。
<course page-size="10">免费课程</course>
<template id="course">
<div>
<h3>
<slot></slot>
</h3>
<ul class="course">
<li v-for="(item,index) in courseList" :key="index">
<div><img :src="item.coverFileUrl" alt=""></div>
<p>{{item.courseTitle}}</p>
<p class="sub">共{{item.subSectionNum}}节课|{{item.learningNum}}人报名</p>
<p v-if="item.isFree==1" class="free">免费</p>
<p v-else-if="item.isDiscount==1"><span class="count">
{{item.coursePrice}}</span><del>{{item.discountPrice}}</del><span class="desc">
{{item.discountDesc}}</span></p>
<p v-else class="price">{{item.discountPrice}}</p>
</li>
</ul>
</div>
</template>
2.4 默认插槽
默认插槽就是指没有名字的插槽,子组件未定义的名字的插槽,父级将会把 未指定插槽的填充的内容填充到默认插槽中
1. 父级的填充内容如果指定到子组件的没有对应名字插槽,那么该内容不会被填充到默认插槽中。
2. 如果子组件没有默认插槽,而父级的填充内容指定到默认插槽中,那么该内容就“不会”填充到子组件的任何一个插槽中。
3. 如果子组件有多个默认插槽,而父组件所有指定到默认插槽的填充内容,将“会” “全都”填充到子组件的每个默认插槽中。