前言
什么是组件化开发?
Vue组件化开发是Vue.js框架的一个核心特性,它允许开发者将用户界面分解成一组可复用的、独立的组件,每个组件负责渲染视图的一部分,任何一个vue文件都是一个组件。
实现效果图:
创建Vue项目:
- 在终端输入
npm create vue@latest,取好项目名称然后一路否过去。
- 将你创建的项目用编译器打开,打开终端,输入
npm i安装包。 - 在src文件夹中创建一个component文件夹,再到该文件夹底下创建两个vue文件:shopping.vue和todos.vue,再将这两个文件引入App.vue。这样只需操作shopping.vue和todos.vue就能实现组件化开发。
App.vue
<template>
<div class="app">
<!-- changeTab(1) 直接传入实参 -->
<button class="btn" @click="changeTab(1)">购物车</button>
<button class="btn" @click="changeTab(2)">todos</button>
<!-- 购物车 -->
<shopping v-if="tabIndex === 1"></shopping>
<!-- todos -->
<todos v-else></todos>
</div>
</template>
<script setup>
import {ref} from 'vue'
import shopping from './components/shopping.vue'
import todos from './components/todos.vue'
let tabIndex = ref(1)
const changeTab = (index) => {
console.log(index);
tabIndex.value = index
}
</script>
<style lang="css" scoped>
.app{
text-align: center;
}
.btn{
font-size: 20px;
width: 100px;
height: 40px;
margin: 20px;
}
</style>
分析
创建并给button按钮绑定点击事件@click,函数名为changeTab,为其传入了实参,当标记为1,购物车生效,标记为2,todos生效。let tabIndex = ref(1)让tabIndex变为响应式数据,当tabIndex的值改变时,会被渲染到浏览器页面上。
shopping.vue
- 首先引入书籍的数组
const books = reactive([
{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85.00,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59.00,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39.00,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128.00,
count: 1
},
])
const totalPrice = computed(() => {
let total = 0
books.forEach(item => {
total += item.price * item.count
})
return total
})
- 并且引入
import { reactive, computed } from 'vue'将books变为响应式变量,reactive能帮我们把引用类型的数据变成响应式的。 - 再通过
computed来计算书籍的总价,每次当书籍变化时,会再次触发该函数,完成书籍价格的加减。并且定义函数addCount和decrementCount来实现书籍数量的变化。
const totalPrice = computed(() => {
let total = 0
books.forEach(item => {
total += item.price * item.count
})
return total
})
const addCount = (index) => {
books[index].count++
}
const decrementCount = (index) => {
books[index].count--
}
- 为购物车定义一些样式
table{
margin: 0 auto;
border: 1px solid #e9e9e9;
border-collapse: collapse;
border-spacing: 0;
}
th, td{
padding: 8px 16px;
border: 1px solid #e9e9e9;
}
.counter{
margin: 0 5px;
}
- 在template标签中用table标签来包裹书籍的数据,在tr标签中使用v-for来实现遍历books数组,tr的数据不能写死,再到button按钮上分别绑定点击事件@click,绑定addCount和decrementCount。在
-按钮写入:disabled="book.count <= 0当书籍的数量减为0时,该减号按钮失效。
<template>
<div class="shopping">
<table>
<thead>
<th>序号</th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</thead>
<tbody>
<tr v-for="(book, index) in books">
<td>{{ index + 1 }}</td>
<td>{{ book.name }}</td>
<td>{{ book.date }}</td>
<td>{{ book.price }}</td>
<td>{{ book.count }}</td>
<td>
<button :disabled="book.count <= 0" @click="decrementCount(index)">-</button>
<span class="counter">{{ book.count }}</span>
<button @click="addCount(index)">+</button>
</td>
</tr>
</tbody>
</table>
<h3>总价格:{{ totalPrice }}</h3>
</div>
</template>
todos.vue
- 直接使用已经封装好的样式,就不用我们再写css,在终端输入
npm i todomvc-app-css - 下载好了之后在全局的main.js中引入该文件
- 定义一个todos数组,使用reactive使其变为响应式变量。
const state = reactive({
todos: [
{
id: 1,
title: '学习',
completed: false
},
{
id: 2,
title: '吃饭',
completed: true
},
{
id: 3,
title: '睡觉',
completed: false
}
],
});
- 定义一个newTodo为null用于接收用户在输入框输入的数据,并且将newTodo变为响应式数据。
const newTodo = ref(null); - 定义一个addTodo来用于增加列表
const addTodo = () => {
state.todos.push({
id: state.todos.length + 1,
title: newTodo.value,
completed: false
});
}
- 定义一个com函数用于勾选和取消
const com = () => {
state.todos.completed = !state.todos.completed;
};
- 在template标签中的li标签使用v-for来实现列表渲染,再使用v-model来实现双向绑定。
<template>
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<input type="text" class="new-todo" placeholder="想干的事" @keyup.enter="addTodo" v-model="newTodo">
</header>
<section class="main">
<input type="checkbox" class="toggle-all" id="toggle-all">
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<li class="todo" v-for="(item, index) in state.todos" :key="index">
<div class="view">
<input type="checkbox" class="toggle" v-model="item.completed" @click="com">
<label>{{item.title}}</label>
<button class="destroy"></button>
</div>
</li>
</ul>
</section>
</section>
</template>
总结
Vue组件化开发能够减少代码重复率,提高开发的效率。