元件間通信傳遞消息,很多時候傳遞的都是資料;
而slot可以傳遞标簽
TodoFooter.vue元件
<template>
<div class="todo-footer">
<label>
<!--<input type="checkbox" v-model="checkAll"/>-->
<slot name="checkAll"></slot>//設計成插槽
</label>
<span>
<slot name="size"></slot> //設計成插槽
<!-- <span>已完成{{completeSize}} / 全部{{todos.length}}</span>-->
</span>
<slot name="delete"></slot> //設計成插槽
<!-- <button class="btn btn-danger" v-show="completeSize" @click="deleteAllCompleted">清除已完成任務</button>-->
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
此時TodoFooter元件上的插槽是空的,要在App上進行設計并傳遞
App.vue元件
<template>
<div class="todo-container">
<div class="todo-wrap">
<!--<TodoHeader @addTodo="addTodo"/>-->
<TodoHeader ref="header"/>
<TodoList :todos="todos"/>
<TodoFooter>
<input type="checkbox" v-model="checkAll" slot="checkAll"/>
<span slot="size">已完成{{completeSize}} / 全部{{todos.length}}</span>
<button class="btn btn-danger" v-show="completeSize" @click="deleteAllCompleted" slot="delete">清除已完成任務</button>
</TodoFooter>
</div>
</div>
</template>
<script>
import PubSub from 'pubsub-js'
import TodoHeader from './components/TodoHeader.vue'
import TodoList from './components/TodoList.vue'
import TodoFooter from './components/TodoFooter.vue'
import storageUtils from './utils/storageUtils'
export default {
data () {
return {
// todos: JSON.parse(localStorage.getItem('todos_key') || '[]') // 讀取localStorage儲存的資料
todos: storageUtils.readTodos()
}
},
mounted () {
// 綁定自定義事件(addTodo)監聽
// this.$on('addTodo', this.addTodo) 綁定監聽的目标不對
this.$refs.header.$on('addTodo', this.addTodo)
// 訂閱消息(deleteTodo)
PubSub.subscribe('deleteTodo', (msg, index) => {
this.deleteTodo(index)
})
},
//計算屬性
computed: {
completeSize () {
return this.todos.reduce((preTotal, todo) => preTotal + (todo.complete?1:0) ,0)
},
checkAll: {
get () { // 決定是否勾選
return this.completeSize===this.todos.length && this.completeSize>0
},
set (value) {// 點選了全選checkbox value是目前checkbox的選中狀态(true/false)
this.selectAll(value)
}
},
},
methods: {
addTodo (todo) {
this.todos.unshift(todo)
},
deleteTodo (index) {
this.todos.splice(index, 1)
},
// 删除所有已完成的
deleteCompleteTodos () {
this.todos = this.todos.filter(todo => !todo.complete)
},
// 全選/全不選
selectAll (isSelectAll) {
this.todos.forEach(todo => {
todo.complete = isSelectAll
})
},
deleteAllCompleted () {
if(window.confirm('确定清除已完成的嗎?')) {
this.deleteCompleteTodos()
}
}
},
watch: {
todos: {
deep: true, // 深度監視
/*handler: function (val) {
// 将資料(json)儲存到localStorage
// localStorage.setItem('todos_key', JSON.stringify(val))
storageUtils.saveTodos(val)
}*/
// handler的值應該是一個函數, 且函數應該要有一個形參(接收todos最新的值)
handler: storageUtils.saveTodos,
/*handler: function (todos) {
localStorage.setItem(TODOS_KEY, JSON.stringify(todos))
}*/
}
},
components: {
TodoHeader,
TodoList,
TodoFooter
}
}
</script>
<style>
</style>
現在有個問題,就是這些标簽是在父元件裡編譯好了之後再插到TodoFooter裡面去;标簽中對應的計算屬性都應該放到父元件中去