VUE进阶案例
VUE图片轮播
以下是一个基于Vue.js的图片轮播组件的简单案例:
代码示例
-
创建轮播组件
ImageCarousel.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>
-
在父组件中使用轮播组件
<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
<template><div class="note-app"><div class="header"><h1>记事本</h1><inputv-model="newNote"placeholder="输入内容并按回车添加"@keyup.enter="addNote"/></div><ul class="notes-list"><li v-for="note in notes" :key="note.id"><div class="content"><inputtype="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 在父组件中使用
<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
<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 在父组件中使用
<template><div><ShoppingCart /></div>
</template><script>
import ShoppingCart from './ShoppingCart.vue';export default {components: {ShoppingCart}
};
</script>
3. 功能说明
-
商品展示
- 列表展示商品名称、价格和图片,点击“加入购物车”按钮可添加到购物车。
- 已添加的商品按钮会显示“已添加”并禁用。
-
购物车管理
- 购物车显示已添加的商品、数量和单价。
- 支持修改数量(+/-按钮)、移除商品。
- 实时计算总价并显示。
4. 注意事项
- 数据持久化:当前数据存储在内存中,刷新页面后数据会丢失。如需持久化,可结合
localStorage
或后端API。 - 样式调整:可根据需求修改样式,例如增加动画效果、主题颜色等。
- 扩展功能:可添加商品分类、优惠券、支付流程等。
组件通信案例
以下是Vue组件通信的案例,涵盖父子组件、兄弟组件和跨层级组件之间的通信方式。
案例一:父子组件通信
场景:父组件传递数据给子组件,子组件通过事件通知父组件。
代码:
父组件(Parent.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)
<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)
import mitt from 'mitt';export const bus = mitt();
组件A(ComponentA.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)
<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)
<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)
<template><div><h2>祖组件</h2><ParentComponent /></div>
</template><script>
import ParentComponent from './ParentComponent.vue';export default {components: {ParentComponent},provide() {return {sharedData: '来自祖组件的数据'};}
};
</script>
父组件(ParentComponent.vue)
<template><div><h3>父组件</h3><ChildComponent /></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent}
};
</script>
子组件(ChildComponent.vue)
<template><div><h4>子组件</h4><p>接收到的数据:{{ sharedData }}</p ></div>
</template><script>
export default {inject: ['sharedData']
};
</script>
说明:
- 祖组件通过
provide
提供数据sharedData
。 - 后代组件通过
inject
接收并使用sharedData
。