<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      木木木森林

      導(dǎo)航

      vue todoList -- 自定義事件版

      main.js
      //引入Vue
      import Vue from 'vue'
      //引入App
      import App from './App.vue'
      //關(guān)閉Vue的生產(chǎn)提示
      Vue.config.productionTip = false
      
      //創(chuàng)建vm
      new Vue({
      	el:'#app',
      	render: h => h(App)
      })
      
      App.vue
      <template>
      	<div id="root">
      		<div class="todo-container">
      			<div class="todo-wrap">
      				<MyHeader @addTodo="addTodo"/>
      				<MyList :todos="todos" :checkTodo="checkTodo" :deleteTodo="deleteTodo"/>
      				<MyFooter :todos="todos" @checkAllTodo="checkAllTodo" @clearAllTodo="clearAllTodo"/>
      			</div>
      		</div>
      	</div>
      </template>
      
      <script>
      	import MyHeader from './components/MyHeader'
      	import MyList from './components/MyList'
      	import MyFooter from './components/MyFooter.vue'
      
      	export default {
      		name:'App',
      		components:{MyHeader,MyList,MyFooter},
      		data() {
      			return {
      				//由于todos是MyHeader組件和MyFooter組件都在使用,所以放在App中(狀態(tài)提升)
      				todos:JSON.parse(localStorage.getItem('todos')) || []
      			}
      		},
      		methods: {
      			//添加一個todo
      			addTodo(todoObj){
      				this.todos.unshift(todoObj)
      			},
      			//勾選or取消勾選一個todo
      			checkTodo(id){
      				this.todos.forEach((todo)=>{
      					if(todo.id === id) todo.done = !todo.done
      				})
      			},
      			//刪除一個todo
      			deleteTodo(id){
      				this.todos = this.todos.filter( todo => todo.id !== id )
      			},
      			//全選or取消全選
      			checkAllTodo(done){
      				this.todos.forEach((todo)=>{
      					todo.done = done
      				})
      			},
      			//清除所有已經(jīng)完成的todo
      			clearAllTodo(){
      				this.todos = this.todos.filter((todo)=>{
      					return !todo.done
      				})
      			}
      		},
      		watch: {
      			todos:{
      				deep:true,
      				handler(value){
      					localStorage.setItem('todos',JSON.stringify(value))
      				}
      			}
      		},
      	}
      </script>
      
      <style>
      	/*base*/
      	body {
      		background: #fff;
      	}
      	.btn {
      		display: inline-block;
      		padding: 4px 12px;
      		margin-bottom: 0;
      		font-size: 14px;
      		line-height: 20px;
      		text-align: center;
      		vertical-align: middle;
      		cursor: pointer;
      		box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
      		border-radius: 4px;
      	}
      	.btn-danger {
      		color: #fff;
      		background-color: #da4f49;
      		border: 1px solid #bd362f;
      	}
      	.btn-danger:hover {
      		color: #fff;
      		background-color: #bd362f;
      	}
      	.btn:focus {
      		outline: none;
      	}
      	.todo-container {
      		width: 600px;
      		margin: 0 auto;
      	}
      	.todo-container .todo-wrap {
      		padding: 10px;
      		border: 1px solid #ddd;
      		border-radius: 5px;
      	}
      </style>
      
      
      MyHeader
      <template>
      	<div class="todo-header">
      		<input type="text" placeholder="請輸入你的任務(wù)名稱,按回車鍵確認(rèn)" v-model="title" @keyup.enter="add"/>
      	</div>
      </template>
      
      <script>
      	import {nanoid} from 'nanoid'
      	export default {
      		name:'MyHeader',
      		data() {
      			return {
      				//收集用戶輸入的title
      				title:''
      			}
      		},
      		methods: {
      			add(){
      				//校驗(yàn)數(shù)據(jù)
      				if(!this.title.trim()) return alert('輸入不能為空')
      				//將用戶的輸入包裝成一個todo對象
      				const todoObj = {id:nanoid(),title:this.title,done:false}
      				//通知App組件去添加一個todo對象
      				this.$emit('addTodo',todoObj,1,2,3)
      				//清空輸入
      				this.title = ''
      			}
      		},
      	}
      </script>
      
      <style scoped>
      	/*header*/
      	.todo-header input {
      		width: 560px;
      		height: 28px;
      		font-size: 14px;
      		border: 1px solid #ccc;
      		border-radius: 4px;
      		padding: 4px 7px;
      	}
      
      	.todo-header input:focus {
      		outline: none;
      		border-color: rgba(82, 168, 236, 0.8);
      		box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
      	}
      </style>
      
      MyList
      <template>
      	<ul class="todo-main">
      		<MyItem 
      			v-for="todoObj in todos"
      			:key="todoObj.id" 
      			:todo="todoObj" 
      			:checkTodo="checkTodo"
      			:deleteTodo="deleteTodo"
      		/>
      	</ul>
      </template>
      
      <script>
      	import MyItem from './MyItem'
      
      	export default {
      		name:'MyList',
      		components:{MyItem},
      		//聲明接收App傳遞過來的數(shù)據(jù),其中todos是自己用的,checkTodo和deleteTodo是給子組件MyItem用的
      		props:['todos','checkTodo','deleteTodo']
      	}
      </script>
      
      <style scoped>
      	/*main*/
      	.todo-main {
      		margin-left: 0px;
      		border: 1px solid #ddd;
      		border-radius: 2px;
      		padding: 0px;
      	}
      
      	.todo-empty {
      		height: 40px;
      		line-height: 40px;
      		border: 1px solid #ddd;
      		border-radius: 2px;
      		padding-left: 5px;
      		margin-top: 10px;
      	}
      </style>
      
      MyItem
      <template>
      	<li>
      		<label>
      			<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>
      			<!-- 如下代碼也能實(shí)現(xiàn)功能,但是不太推薦,因?yàn)橛悬c(diǎn)違反原則,因?yàn)樾薷牧藀rops -->
      			<!-- <input type="checkbox" v-model="todo.done"/> -->
      			<span>{{todo.title}}</span>
      		</label>
      		<button class="btn btn-danger" @click="handleDelete(todo.id)">刪除</button>
      	</li>
      </template>
      
      <script>
      	export default {
      		name:'MyItem',
      		//聲明接收todo、checkTodo、deleteTodo
      		props:['todo','checkTodo','deleteTodo'],
      		methods: {
      			//勾選or取消勾選
      			handleCheck(id){
      				//通知App組件將對應(yīng)的todo對象的done值取反
      				this.checkTodo(id)
      			},
      			//刪除
      			handleDelete(id){
      				if(confirm('確定刪除嗎?')){
      					//通知App組件將對應(yīng)的todo對象刪除
      					this.deleteTodo(id)
      				}
      			}
      		},
      	}
      </script>
      
      <style scoped>
      	/*item*/
      	li {
      		list-style: none;
      		height: 36px;
      		line-height: 36px;
      		padding: 0 5px;
      		border-bottom: 1px solid #ddd;
      	}
      
      	li label {
      		float: left;
      		cursor: pointer;
      	}
      
      	li label li input {
      		vertical-align: middle;
      		margin-right: 6px;
      		position: relative;
      		top: -1px;
      	}
      
      	li button {
      		float: right;
      		display: none;
      		margin-top: 3px;
      	}
      
      	li:before {
      		content: initial;
      	}
      
      	li:last-child {
      		border-bottom: none;
      	}
      
      	li:hover{
      		background-color: #ddd;
      	}
      	
      	li:hover button{
      		display: block;
      	}
      </style>
      
      MyFooter
      <template>
      	<div class="todo-footer" v-show="total">
      		<label>
      			<!-- <input type="checkbox" :checked="isAll" @change="checkAll"/> -->
      			<input type="checkbox" v-model="isAll"/>
      		</label>
      		<span>
      			<span>已完成{{doneTotal}}</span> / 全部{{total}}
      		</span>
      		<button class="btn btn-danger" @click="clearAll">清除已完成任務(wù)</button>
      	</div>
      </template>
      
      <script>
      	export default {
      		name:'MyFooter',
      		props:['todos'],
      		computed: {
      			//總數(shù)
      			total(){
      				return this.todos.length
      			},
      			//已完成數(shù)
      			doneTotal(){
      				//此處使用reduce方法做條件統(tǒng)計
      				/* const x = this.todos.reduce((pre,current)=>{
      					console.log('@',pre,current)
      					return pre + (current.done ? 1 : 0)
      				},0) */
      				//簡寫
      				return this.todos.reduce((pre,todo)=> pre + (todo.done ? 1 : 0) ,0)
      			},
      			//控制全選框
      			isAll:{
      				//全選框是否勾選
      				get(){
      					return this.doneTotal === this.total && this.total > 0
      				},
      				//isAll被修改時set被調(diào)用
      				set(value){
      					// this.checkAllTodo(value)
      					this.$emit('checkAllTodo',value)
      				}
      			}
      		},
      		methods: {
      			/* checkAll(e){
      				this.checkAllTodo(e.target.checked)
      			} */
      			//清空所有已完成
      			clearAll(){
      				// this.clearAllTodo()
      				this.$emit('clearAllTodo')
      			}
      		},
      	}
      </script>
      
      <style scoped>
      	/*footer*/
      	.todo-footer {
      		height: 40px;
      		line-height: 40px;
      		padding-left: 6px;
      		margin-top: 5px;
      	}
      
      	.todo-footer label {
      		display: inline-block;
      		margin-right: 20px;
      		cursor: pointer;
      	}
      
      	.todo-footer label input {
      		position: relative;
      		top: -1px;
      		vertical-align: middle;
      		margin-right: 5px;
      	}
      
      	.todo-footer button {
      		float: right;
      		margin-top: 5px;
      	}
      </style>
      

      posted on 2021-12-29 21:33  木木木森林  閱讀(48)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲视频一区| 女人与牲口性恔配视频免费| 2021亚洲国产精品无码| 亚洲高清WWW色好看美女| 无码人妻一区二区三区兔费| 三都| 国产粉嫩区一区二区三区| 中文国产人精品久久蜜桃| 三上悠亚精品一区二区久久| 国产三级精品片| 少妇特黄a一区二区三区| 狠狠色丁香婷婷综合尤物| 日韩理伦片一区二区三区| 女人香蕉久久毛毛片精品| 国内精品久久久久影院日本| 国产精品免费第一区二区| 97人妻精品一区二区三区| 亚洲码国产精品高潮在线| 亚洲中文字幕精品第一页| 一区二区三区无码免费看| 在线a亚洲v天堂网2018| 人妻少妇偷人无码视频| 久久久久99精品成人片牛牛影视 | 国产中文字幕精品免费| 色综合久久中文综合网| 日韩一区二区三在线观看| 在线看无码的免费网站| 宁南县| 日本中文字幕乱码免费| 亚洲欧美中文字幕5发布| 中文字幕人妻在线精品| 精品人妻av综合一区二区| 国产在线乱子伦一区二区| 蜜臀视频在线观看一区二区| 国产精品人成视频免| 成人免费亚洲av在线| 中国丰满少妇人妻xxx性董鑫洁 | 热久在线免费观看视频| 亚洲欧美综合精品成人网站| av永久天堂一区| 精品乱人伦一区二区三区|