VUE图片轮播
以下是一个基于Vue.js的图片轮播组件的简单案例:
代码示例
-
创建轮播组件
ImageCarousel.vue
vue<template> <div class="carousel"> <div class="carousel-inner" :style="{ transform: `translateX(-${currentIndex * 100}%)` }"> <div v-for="(image, index) in images" :key="index" class="carousel-item"> < img :src="image" alt="" /> </div> </div> <div class="carousel-indicators"> <span v-for="(image, index) in images" :key="index" :class="{ active: index === currentIndex }" @click="goToSlide(index)"></span> </div> </div> </template> <script> export default { name: 'ImageCarousel', props: { images: { type: Array, required: true } }, data() { return { currentIndex: 0, interval: null }; }, methods: { goToSlide(index) { this.currentIndex = index; }, nextSlide() { this.currentIndex = (this.currentIndex + 1) % this.images.length; } }, mounted() { this.interval = setInterval(this.nextSlide, 3000); // 自动播放 }, beforeUnmount() { clearInterval(this.interval); // 清除定时器 } }; </script> <style scoped> .carousel { position: relative; width: 100%; max-width: 800px; margin: 0 auto; overflow: hidden; } .carousel-inner { display: flex; transition: transform 0.5s ease; } .carousel-item { flex-shrink: 0; width: 100%; } .carousel-item img { width: 100%; display: block; } .carousel-indicators { position: absolute; bottom: 10px; width: 100%; text-align: center; } .carousel-indicators span { display: inline-block; width: 10px; height: 10px; margin: 0 5px; background-color: #ccc; border-radius: 50%; cursor: pointer; } .carousel-indicators span.active { background-color: #333; } </style>
-
在父组件中使用轮播组件
vue<template> <div> <h1>图片轮播示例</h1> <ImageCarousel :images="imageList" /> </div> </template> <script> import ImageCarousel from './ImageCarousel.vue'; export default { components: { ImageCarousel }, data() { return { imageList: [ 'path/to/image1.jpg', 'path/to/image2.jpg', 'path/to/image3.jpg' ] }; } }; </script>
功能说明
- 自动播放:轮播图每隔3秒自动切换到下一张图片。
- 手动切换:用户可以通过点击底部的指示器切换到指定的图片。
- 指示器:底部的圆点指示器显示当前显示的图片序号,点击可切换图片。
- 响应式:轮播图根据容器的宽度自动调整图片大小。
注意事项
- 请将
path/to/image.jpg
替换为实际的图片路径。 - 可根据需求调整样式和组件逻辑,例如添加过渡效果、修改切换时间等。
记事本案例
以下是一个基于Vue.js的简易记事本案例,包含基本的增删改查功能:
2. 代码实现
2.1 创建记事本组件 NoteApp.vue
vue
<template>
<div class="note-app">
<div class="header">
<h1>记事本</h1>
<input
v-model="newNote"
placeholder="输入内容并按回车添加"
@keyup.enter="addNote"
/>
</div>
<ul class="notes-list">
<li v-for="note in notes" :key="note.id">
<div class="content">
<input
type="text"
:value="note.content"
@input="editNote(note.id, $event.target.value)"
/>
</div>
<div class="actions">
<button @click="deleteNote(note.id)">删除</button>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
notes: [
{ id: 1, content: '默认笔记1' },
{ id: 2, content: '默认笔记2' }
],
newNote: ''
};
},
methods: {
// 添加新笔记
addNote() {
if (this.newNote.trim()) {
const newId = this.notes.length ? this.notes[this.notes.length - 1].id + 1 : 1;
this.notes.push({ id: newId, content: this.newNote });
this.newNote = '';
}
},
// 编辑笔记
editNote(id, content) {
const note = this.notes.find(note => note.id === id);
if (note) {
note.content = content;
}
},
// 删除笔记
deleteNote(id) {
this.notes = this.notes.filter(note => note.id !== id);
}
}
};
</script>
<style scoped>
.note-app {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}
.header input {
width: 100%;
padding: 10px;
margin-top: 10px;
font-size: 16px;
}
.notes-list {
list-style: none;
padding: 0;
}
.notes-list li {
margin-bottom: 15px;
padding: 15px;
background: #f4f4f4;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
.content input {
width: 80%;
padding: 8px;
border: 1px solid #ccc;
font-size: 14px;
}
.actions {
display: flex;
gap: 10px;
}
.actions button {
padding: 6px 12px;
background: #e74c3c;
color: white;
border: none;
cursor: pointer;
border-radius: 3px;
}
</style>
2.2 在父组件中使用
vue
<template>
<div>
<NoteApp />
</div>
</template>
<script>
import NoteApp from './NoteApp.vue';
export default {
components: {
NoteApp
}
};
</script>
3. 功能说明
-
添加笔记
- 在输入框输入内容并按回车键,新笔记将被添加到列表。
- 自动生成唯一ID(模拟数据持久化)。
-
编辑笔记
- 直接修改列表中的输入框内容,内容会实时保存。
-
删除笔记
- 点击笔记右侧的"删除"按钮,对应笔记会被移除。
4. 注意事项
- 数据持久化 :当前数据存储在内存中,刷新页面后数据会丢失。如需持久化,可结合
localStorage
或后端API。 - 样式调整:可根据需求修改样式,例如增加主题色、动画效果等。
- 扩展功能:可添加排序、搜索、分类等功能。
购物车案例
以下是一个基于Vue.js的购物车案例,包含商品展示、添加到购物车、数量修改和总价计算等功能:
2. 代码实现
2.1 创建购物车组件 ShoppingCart.vue
vue
<template>
<div class="shopping-cart">
<h2>商品列表</h2>
<div class="products">
<div v-for="product in products" :key="product.id" class="product-item">
< img :src="product.image" alt="商品图片" />
<div class="product-info">
<h3>{{ product.name }}</h3>
<p>价格:¥{{ product.price }}</p >
<button @click="addToCart(product.id)" :disabled="isInCart(product.id)">
{{ isInCart(product.id) ? '已添加' : '加入购物车' }}
</button>
</div>
</div>
</div>
<div class="cart" v-if="cartItems.length">
<h2>购物车</h2>
<ul>
<li v-for="item in cartItems" :key="item.id">
<div class="item-info">
<span>{{ item.name }}</span>
<span>¥{{ item.price }}</span>
</div>
<div class="quantity">
<button @click="decrementQuantity(item.id)" :disabled="item.quantity === 1">-</button>
<span>{{ item.quantity }}</span>
<button @click="incrementQuantity(item.id)">+</button>
</div>
<button @click="removeFromCart(item.id)">移除</button>
</li>
</ul>
<div class="total">
<span>总价:¥{{ total.toFixed(2) }}</span>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
products: [
{
id: 1,
name: '商品1',
price: 19.99,
image: 'https://via.placeholder.com/150/00ff00'
},
{
id: 2,
name: '商品2',
price: 29.99,
image: 'https://via.placeholder.com/150/0000ff'
},
{
id: 3,
name: '商品3',
price: 14.99,
image: 'https://via.placeholder.com/150/ff0000'
}
],
cartItems: []
};
},
computed: {
total() {
return this.cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
},
methods: {
addToCart(id) {
const product = this.products.find(p => p.id === id);
if (product) {
const existingItem = this.cartItems.find(item => item.id === id);
if (existingItem) {
existingItem.quantity++;
} else {
this.cartItems.push({ ...product, quantity: 1 });
}
}
},
removeFromCart(id) {
this.cartItems = this.cartItems.filter(item => item.id !== id);
},
incrementQuantity(id) {
const item = this.cartItems.find(item => item.id === id);
if (item) {
item.quantity++;
}
},
decrementQuantity(id) {
const item = this.cartItems.find(item => item.id === id);
if (item && item.quantity > 1) {
item.quantity--;
}
},
isInCart(id) {
return this.cartItems.some(item => item.id === id);
}
}
};
</script>
<style scoped>
.shopping-cart {
max-width: 800px;
margin: 20px auto;
padding: 20px;
background: #f4f4f4;
border-radius: 8px;
}
.products {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.product-item {
display: flex;
align-items: center;
padding: 15px;
background: white;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.product-item img {
width: 80px;
height: 80px;
margin-right: 15px;
}
.product-info button {
padding: 5px 10px;
background: #2ecc71;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
}
.cart ul {
list-style: none;
padding: 0;
}
.cart li {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-bottom: 1px solid #ddd;
}
.quantity button {
padding: 5px;
background: #3498db;
color: white;
border: none;
border-radius: 3px;
margin: 0 5px;
cursor: pointer;
}
.total {
margin-top: 20px;
font-size: 18px;
font-weight: bold;
}
</style>
2.2 在父组件中使用
vue
<template>
<div>
<ShoppingCart />
</div>
</template>
<script>
import ShoppingCart from './ShoppingCart.vue';
export default {
components: {
ShoppingCart
}
};
</script>
3. 功能说明
-
商品展示
- 列表展示商品名称、价格和图片,点击"加入购物车"按钮可添加到购物车。
- 已添加的商品按钮会显示"已添加"并禁用。
-
购物车管理
- 购物车显示已添加的商品、数量和单价。
- 支持修改数量(+/-按钮)、移除商品。
- 实时计算总价并显示。
4. 注意事项
- 数据持久化 :当前数据存储在内存中,刷新页面后数据会丢失。如需持久化,可结合
localStorage
或后端API。 - 样式调整:可根据需求修改样式,例如增加动画效果、主题颜色等。
- 扩展功能:可添加商品分类、优惠券、支付流程等。
组件通信案例
以下是Vue组件通信的案例,涵盖父子组件、兄弟组件和跨层级组件之间的通信方式。
案例一:父子组件通信
场景:父组件传递数据给子组件,子组件通过事件通知父组件。
代码:
父组件(Parent.vue)
vue
<template>
<div>
<h2>父组件</h2>
<p>消息:{{ message }}</p >
<ChildComponent :initialMessage="message" @updateMessage="message = $event" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
message: '来自父组件的消息'
};
}
};
</script>
子组件(ChildComponent.vue)
vue
<template>
<div>
<h3>子组件</h3>
<input type="text" v-model="currentMessage" @input="updateMessage">
</div>
</template>
<script>
export default {
props: {
initialMessage: String
},
data() {
return {
currentMessage: this.initialMessage
};
},
methods: {
updateMessage() {
this.$emit('updateMessage', this.currentMessage);
}
}
};
</script>
说明:
- 父组件通过
props
将message
传递给子组件。 - 子组件使用
v-model
双向绑定输入框和currentMessage
。 - 子组件通过
$emit
触发updateMessage
事件,将修改后的消息传递给父组件。
案例二:兄弟组件通信(通过事件总线)
场景:两个兄弟组件通过事件总线传递数据。
代码:
创建事件总线(eventBus.js)
javascript
import mitt from 'mitt';
export const bus = mitt();
组件A(ComponentA.vue)
vue
<template>
<div>
<h3>组件A</h3>
<button @click="sendMessage">发送消息给组件B</button>
</div>
</template>
<script>
import { bus } from './eventBus.js';
export default {
methods: {
sendMessage() {
bus.emit('message-to-b', '来自组件A的消息');
}
}
};
</script>
组件B(ComponentB.vue)
vue
<template>
<div>
<h3>组件B</h3>
<p>收到的消息:{{ receivedMessage }}</p >
</div>
</template>
<script>
import { bus } from './eventBus.js';
export default {
data() {
return {
receivedMessage: ''
};
},
mounted() {
bus.on('message-to-b', (message) => {
this.receivedMessage = message;
});
}
};
</script>
父组件(Parent.vue)
vue
<template>
<div>
<ComponentA />
<ComponentB />
</div>
</template>
<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
export default {
components: {
ComponentA,
ComponentB
}
};
</script>
说明:
- 创建事件总线
bus
用于组件间通信。 - 组件A通过
bus.emit
发送消息。 - 组件B通过
bus.on
监听并接收消息。
案例三:跨层级组件通信(使用provide
和inject
)
场景:祖组件向后代组件传递数据。
代码:
祖组件(GrandParent.vue)
vue
<template>
<div>
<h2>祖组件</h2>
<ParentComponent />
</div>
</template>
<script>
import ParentComponent from './ParentComponent.vue';
export default {
components: {
ParentComponent
},
provide() {
return {
sharedData: '来自祖组件的数据'
};
}
};
</script>
父组件(ParentComponent.vue)
vue
<template>
<div>
<h3>父组件</h3>
<ChildComponent />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
子组件(ChildComponent.vue)
vue
<template>
<div>
<h4>子组件</h4>
<p>接收到的数据:{{ sharedData }}</p >
</div>
</template>
<script>
export default {
inject: ['sharedData']
};
</script>
说明:
- 祖组件通过
provide
提供数据sharedData
。 - 后代组件通过
inject
接收并使用sharedData
。