ミックスインは、Vueコンポーネント間で共通のロジックを共有するための機能です。
ミックスイン
記法
const ミックスイン名 = {
=============
ミックスインの定義
=============
};
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ミックスインについて</title>
<link rel="stylesheet" href="./main.css" />
</head>
<body>
<div id="app">
<div class="title">{{ title }}</div>
<div class="task-input">
<input v-model="newTask" placeholder="新しいタスクを入力してください" />
<select v-model="taskListType">
<option value="main">メインタスクリスト</option>
<option value="sub">サブタスクリスト</option>
</select>
<button class="task-input-btn" @click="addTask">追加</button>
</div>
<task-list
:tasks="mainTasks"
title="メインタスクリスト"
@remove-task="removeTask"
></task-list>
<task-list
:tasks="subTasks"
title="サブタスクリスト"
@remove-task="removeTask"
></task-list>
</div>
<!-- CDN -->
<script src="CDNのURL"></script>
<script src="./main.js"></script>
</body>
</html>
// ミックスインの定義
const taskMixin = {
methods: {
toggleTask(id) {
const task = this.tasks.find((task) => task.id === id);
task.completed = !task.completed;
},
removeTask(id) {
this.$emit("remove-task", id);
},
},
};
// タスクリストコンポーネントの定義
const TaskList = {
mixins: [taskMixin],
props: ["tasks", "title"],
template: `
<div class="task-list">
<div class="list-title">{{ title }}</div>
<ul>
<li v-for="task in tasks" :key="task.id">
<span class="task-name">{{ task.name }}</span> <span :class="{ 'completed': task.completed }">{{ task.completed ? '完了' : '未完了' }}</span>
<button @click="toggleTask(task.id)" class="toggle-button">切り替え</button>
<button @click="removeTask(task.id)" class="delete-button">削除</button>
</li>
</ul>
</div>
`,
};
// メインアプリケーションの定義
const app = Vue.createApp({
components: {
TaskList,
},
data() {
return {
title: "タスク管理システム",
newTask: "",
taskListType: "main",
mainTasks: [
{ id: 1, name: "タスク1", completed: false },
{ id: 2, name: "タスク2", completed: true },
],
subTasks: [{ id: 3, name: "タスク3", completed: false }],
};
},
methods: {
addTask() {
if (this.newTask.trim()) {
const newTask = {
id: Date.now(),
name: this.newTask.trim(),
completed: false,
};
if (this.taskListType === "main") {
this.mainTasks.push(newTask);
} else {
this.subTasks.push(newTask);
}
this.newTask = "";
}
},
removeTask(id) {
this.mainTasks = this.mainTasks.filter((task) => task.id !== id);
this.subTasks = this.subTasks.filter((task) => task.id !== id);
},
},
});
app.mount("#app");
.app-body {
font-family: Arial, sans-serif;
background-color: #f8f9fa;
padding: 20px;
}
.title {
font-size: 24px;
color: #007bff;
margin-bottom: 20px;
text-align: center;
}
.task-input {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.task-input input {
width: 300px;
padding: 10px;
margin-right: 10px;
border: 1px solid #dee2e6;
border-radius: 5px;
}
.task-input select {
padding: 10px;
margin-right: 10px;
border: 1px solid #dee2e6;
border-radius: 5px;
}
.task-input button {
background-color: #007bff;
color: #ffffff;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
}
.task-input button:hover {
background-color: #0056b3;
}
.task-list {
background-color: #ffffff;
border: 1px solid #dee2e6;
border-radius: 5px;
padding: 15px;
margin-bottom: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.list-title {
font-size: 20px;
margin-bottom: 10px;
color: #495057;
}
.task-list ul {
list-style-type: none;
padding: 0;
}
.task-list li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #dee2e6;
}
.task-list li:last-child {
border-bottom: none;
}
.task-name {
flex-grow: 1;
}
.completed {
color: green;
}
.task-list button {
color: #ffffff;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
margin-left: 5px;
}
.toggle-button {
background-color: #28a745;
color: #ffffff;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
margin-left: 5px;
}
.toggle-button:hover {
background-color: #218838;
}
.delete-button {
background-color: #dc3545;
color: #ffffff;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
margin-left: 5px;
}
.delete-button:hover {
background-color: #c82333;
}
出力結果
{{ title }}