目 录
4、组件化开发
什么是组件??? 组件就是零件,组成⼀个功能局部零件!
4.1、组件的注册
全局注册
// <script></script>中
Vue.component('组件名',{
template:"#id值" // 指定组件的模板
})
// HTML 中
<template id="id值">
<!--模板只能有⼀个根标签!-->
<div>
模板内容
</div>
</template>
局部注册(只能在当前整个Vue实例的范围内才可以使用)
new Vue({
el:"",
data:{},
...,
components:{ // 带s
组件名:{
template:"#id值"
}
}
})
使用组件
<组件名></组件名>
注意点
组件命名,如果使用驼峰命名法,那么,使⽤组件的时候 需要 变成中划线的模式。
组件介绍-案例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>06、组件介绍</title>
<style>
* {
margin: 0;
padding: 0;
}
.item {
display: inline-block;
width: 340px;
border: 2px solid blue;
margin: 10px
}
.tit {
height: 46px;
padding: 0 10px;
line-height: 46px;
background-color: #eee;
}
.cot {
min-height: 200px;
padding: 10px;
}
.kaixin {
width: 100px;
height: 100px;
background-color: orange;
}
</style>
<script src="./vue.js"></script>
</head>
<body>
<!-- <div class="item">
<h3 class="tit">学员故事</h3>
<div class="cot">
内容
</div>
</div>
<div class="item">
<h3 class="tit">公司新闻</h3>
<div class="cot">
内容
</div>
</div>
<div class="item">
<h3 class="tit">公司荣誉</h3>
<div class="cot">
内容
</div>
</div> -->
<div id="app">
<item-box></item-box>
<item-box></item-box>
<item-box></item-box>
<kaixin></kaixin>
</div>
<hr>
<div id="app2">
<item-box></item-box>
</div>
<!-- 模板内容 -->
<template id="mb">
<!-- 【注意点:】 组件的模板只能有一个根标签! -->
<div class="item"> <!-- 这是根标签!-->
<h3 class="tit">学员故事</h3>
<div class="cot">
内容
</div>
</div>
</template>
</body>
<script>
// 全局 注册一个组件!
/*
Vue.component('组件名',{ 组件的配置对象信息 })
*/
Vue.component('itemBox', {
// template: "<h1>111</h1>"
template: "#mb" // template指定这个组件的模板内容!
})
// 组件化开发:
// 每个小功能模块都是独立的!维护起来简单! 复用性高!
// 模块化、组件化、工程化、自动化
new Vue({
el: "#app",
components: { // 局部组件!
kaixin: {
template: "<div class='kaixin'>开心组件</div>"
}
}
})
new Vue({
el: "#app2"
})
</script>
</html>
4.2、组件的配置选项
- 组件的data是⼀个函数,且这个函数返回⼀个对象! 这个对象就是组件的数据源!
- template是组件的模板。
- 其它配置选项和Vue实例⼀致。(computed、watch、components)
- 注意点:组件里面不能直接⽤外⾯的数据或事件函数,外部也不可以直接⽤⾥⾯的数据和事件函数。
案例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>07、组件的配置选项</title>
<style>
.box {
display: inline-block;
background-color: #eee;
padding: 4px;
}
.box input {
width: 40px;
text-align: center;
}
</style>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<num-box></num-box>
<num-box></num-box>
<num-box></num-box>
</div>
<!-- 放在app外面 -->
<template id="nums">
<div class="box">
<button @click="reudce">-</button>
<input type="text" v-model="num">
<button @click="add">+</button>
</div>
</template>
</body>
<script>
Vue.component('numBox', {
template: "#nums",
data: function () { // 组件的data是一个函数,且这个函数返回一个对象,返回的这个对象就是组件的数据源
return {
num: 1
}
},
methods: {
add() {
this.num++
},
reudce() {
this.num--;
}
},
computed: {},
watch: {},
components: {}
})
// 为什么组件的data是一个函数呢! 因为组件的数据都是独立的! 相同的组件,数据之间是不会有干扰的!
new Vue({
el: "#app",
data: { // Vue实例的data是一个对象!
msg: "11111"
}
})
</script>
</html>
轮播图实例
功能分析
- ⾃动播放;
- 左右按钮切换图⽚; [1]
- 分⻚下标点击切换到对应图⽚; [2]
- 图⽚切换和下标⼀致关联; [3]
- 输⼊移⼊轮播区域⾃动播放暂停;离开区域,⾃动播放开始。
运行效果1(点击两边按钮-切换图片)
运行效果图
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>08、轮播图组件</title>
<script src="./vue.js"></script>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
.banner {
width: 540px;
height: 280px;
border: 2px solid blue;
margin: 20px auto;
position: relative;
overflow: hidden;
}
.banner .bd li,
.banner .bd li img {
width: 540px;
height: 280px;
}
.banner .bd {
width: 10000px;
position: relative;
/* 相当于自己原来的位置定位!*/
left: 0;
overflow: hidden;
background-color: #eee;
transition: all .3s linear;
}
.banner .bd li {
float: left;
}
.banner .btn {
width: 35px;
height: 70px;
background-color: rgba(0, 0, 0, .3);
text-align: center;
line-height: 70px;
font-size: 30px;
position: absolute;
top: 50%;
color: #fff;
margin-top: -35px;
cursor: pointer;
}
.banner .btn:hover {
background-color: rgba(0, 0, 0, .8);
}
.banner .prev {
left: 0;
}
.banner .next {
right: 0;
}
.banner .hd {
position: absolute;
display: inline-block;
left: 50%;
transform: translateX(-50%);
/*平移自身的百分之50%*/
bottom: 0;
background-color: orange;
padding: 3px 8px;
}
.banner .hd li {
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #fff;
font-size: 10px;
text-align: center;
margin: 0 10px;
cursor: pointer;
}
.banner .hd li.active {
background-color: red;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<banner></banner>
</div>
<template id="lunbo">
<!-- 主容器 -->
<div class="banner">
<!-- 滑块部分 -->
<ul class="bd" :style="'left:-'+curIndex*540+'px'">
<li v-for="item in list">
<a :href="item.link">
<img :src="item.src" :alt="item.title">
</a>
</li>
</ul>
<!-- 分页器 -->
<ul class="hd">
<li v-for="(item,index) in list" :class="curIndex==index ? 'active':''">{{index}}</li>
</ul>
<!-- 左右按钮 -->
<span class="btn prev" @click="leftClick"><</span>
<span class="btn next" @click="rightClick">></span>
</div>
</template>
</body>
<script>
Vue.component('banner', {
template: "#lunbo",
data() { // JS 里面方法的简写 方法名:function{} 简写 方法名(){}
return {
curIndex: 0, // 当前下标! 【核心!】
list: [
{
link: "http://www.taobao.com",
src: "https://img.alicdn.com/simba/img/TB1wrEbX5cKOu4jSZKbSuw19XXa.jpg",
title: "别克"
},
{
link: "http://www.jd.com",
src: "https://img.alicdn.com/tfs/TB1G9x1Hbr1gK0jSZFDXXb9yVXa-520-280.png_q90_.webp",
title: "胶原蛋白"
},
{
link: "http://www.sina.com",
src: "https://img.alicdn.com/tfs/TB1KXpUHG61gK0jSZFlXXXDKFXa-520-280.jpg_q90_.webp",
title: "图书影像"
}
]
}
},
methods: {
// 右点击
rightClick() {
if (this.curIndex == this.list.length - 1) {
this.curIndex = 0;
} else {
this.curIndex++;
}
},
// 左点击
leftClick() {
if (this.curIndex == 0) {
this.curIndex = this.list.length - 1
} else {
this.curIndex--;
}
}
}
})
new Vue({
el: "#app"
})
</script>
</html>
运行效果2(定时器、鼠标移入-图片静止)
运行效果图
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>08、轮播图组件</title>
<script src="./vue.js"></script>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
}
.banner {
width: 540px;
height: 280px;
border: 2px solid blue;
margin: 20px auto;
position: relative;
overflow: hidden;
}
.banner .bd li,
.banner .bd li img {
width: 540px;
height: 280px;
}
.banner .bd {
width: 10000px;
position: relative;
/* 相当于自己原来的位置定位!*/
left: 0;
overflow: hidden;
background-color: #eee;
transition: all .3s linear;
}
.banner .bd li {
float: left;
}
.banner .btn {
width: 35px;
height: 70px;
background-color: rgba(0, 0, 0, .3);
text-align: center;
line-height: 70px;
font-size: 30px;
position: absolute;
top: 50%;
color: #fff;
margin-top: -35px;
cursor: pointer;
}
.banner .btn:hover {
background-color: rgba(0, 0, 0, .8);
}
.banner .prev {
left: 0;
}
.banner .next {
right: 0;
}
.banner .hd {
position: absolute;
display: inline-block;
left: 50%;
transform: translateX(-50%);
/*平移自身的百分之50%*/
bottom: 0;
background-color: orange;
padding: 3px 8px;
}
.banner .hd li {
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #fff;
font-size: 10px;
text-align: center;
margin: 0 10px;
cursor: pointer;
}
.banner .hd li.active {
background-color: red;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<banner></banner>
<hr>
<banner></banner>
</div>
<template id="lunbo">
<!-- 主容器 -->
<div class="banner" @mouseenter="stop" @mouseleave="start">
<!-- 滑块部分 -->
<ul class="bd" :style="'left:-'+curIndex*540+'px'">
<li v-for="item in list">
<a :href="item.link">
<img :src="item.src" :alt="item.title">
</a>
</li>
</ul>
<!-- 分页器 -->
<ul class="hd">
<li v-for="(item,index) in list" @click="change(index)" :class="curIndex==index ? 'active':''">
{{index}}</li>
</ul>
<!-- 左右按钮 -->
<span class="btn prev" @click="leftClick"><</span>
<span class="btn next" @click="rightClick">></span>
</div>
</template>
</body>
<script>
Vue.component('banner', {
template: "#lunbo",
data() { // JS 里面方法的简写 方法名:function{} 简写 方法名(){}
return {
curIndex: 0, // 当前下标! 【核心!】
timer: "", // 定时器
list: [
{
link: "http://www.taobao.com",
src: "https://img.alicdn.com/simba/img/TB1wrEbX5cKOu4jSZKbSuw19XXa.jpg",
title: "别克"
},
{
link: "http://www.jd.com",
src: "https://img.alicdn.com/tfs/TB1G9x1Hbr1gK0jSZFDXXb9yVXa-520-280.png_q90_.webp",
title: "胶原蛋白"
},
{
link: "http://www.sina.com",
src: "https://img.alicdn.com/tfs/TB1KXpUHG61gK0jSZFlXXXDKFXa-520-280.jpg_q90_.webp",
title: "图书影像"
}
]
}
},
mounted: function () { // 生命周期函数:【挂载完成之后,自动执行!】
this.autplay();// 调用自动播放
},
methods: {
// 右点击
rightClick() {
if (this.curIndex == this.list.length - 1) {
this.curIndex = 0;
} else {
this.curIndex++;
}
},
// 左点击
leftClick() {
if (this.curIndex == 0) {
this.curIndex = this.list.length - 1
} else {
this.curIndex--;
}
},
// 鼠标移入轮播区域
start() {
this.autplay();// 调用自动播放方法
},
// 数量离开轮播区域
stop() {
clearInterval(this.timer);
},
// 自动播放
autplay() {
var _this = this;
this.timer = setInterval(function () {
// console.log(_this)
// 点击一下右按钮!
_this.rightClick();
}, 3000);
},
// 分页器被点击了
change(idx) {
this.curIndex = idx;
}
}
})
new Vue({
el: "#app"
})
</script>
</html>
多谢观看~