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

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

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

      木木木森林

      導航

      vue todoList -- props版

      • main.js
      點擊查看代碼
      //引入Vue
      import Vue from 'vue'
      //引入App
      import App from './App.vue'
      //關閉Vue的生產提示
      Vue.config.productionTip = false
      
      //創建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中(狀態提升)
      				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
      				})
      			},
      			//清除所有已經完成的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="請輸入你的任務名稱,按回車鍵確認" v-model="title" @keyup.enter="add"/>
      	</div>
      </template>
      
      <script>
      	import {nanoid} from 'nanoid'
      	export default {
      		name:'MyHeader',
      		//接收從App傳遞過來的addTodo
      		props:['addTodo'],
      		data() {
      			return {
      				//收集用戶輸入的title
      				title:''
      			}
      		},
      		methods: {
      			add(){
      				//校驗數據
      				if(!this.title.trim()) return alert('輸入不能為空')
      				//將用戶的輸入包裝成一個todo對象
      				const todoObj = {id:nanoid(),title:this.title,done:false}
      				//通知App組件去添加一個todo對象
      				this.addTodo(todoObj)
      				//清空輸入
      				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傳遞過來的數據,其中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)"/>
      			<!-- 如下代碼也能實現功能,但是不太推薦,因為有點違反原則,因為修改了props -->
      			<!-- <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組件將對應的todo對象的done值取反
      				this.checkTodo(id)
      			},
      			//刪除
      			handleDelete(id){
      				if(confirm('確定刪除嗎?')){
      					//通知App組件將對應的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">清除已完成任務</button>
      	</div>
      </template>
      
      <script>
      	export default {
      		name:'MyFooter',
      		props:['todos','checkAllTodo','clearAllTodo'],
      		computed: {
      			//總數
      			total(){
      				return this.todos.length
      			},
      			//已完成數
      			doneTotal(){
      				//此處使用reduce方法做條件統計
      				/* 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被調用
      				set(value){
      					this.checkAllTodo(value)
      				}
      			}
      		},
      		methods: {
      			/* checkAll(e){
      				this.checkAllTodo(e.target.checked)
      			} */
      			//清空所有已完成
      			clearAll(){
      				this.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:26  木木木森林  閱讀(40)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 人成午夜免费大片| AV无码免费不卡在线观看| 免费A级毛片樱桃视频| 国产成人免费午夜在线观看| 中国少妇人妻xxxxx| 国产成人精品亚洲午夜麻豆| 国产精品国产高清国产av| 亚洲午夜香蕉久久精品| 日韩精品中文女同在线播放| 国内精品伊人久久久久影院对白| 天堂国产一区二区三区四区不卡 | 国产农村乱人伦精品视频| 免费十八禁一区二区三区| 精品 日韩 国产 欧美 视频| 欧美做受视频播放| 国产午夜精品在人线播放| 国产99在线 | 免费| 日本高清一区免费中文视频| 日本精品aⅴ一区二区三区| 国产精品日韩精品日韩| 精品久久人人做爽综合| 亚洲国产大胸一区二区三区| 福利视频在线一区二区| 毛葺葺老太做受视频| 日本夜爽爽一区二区三区| 久久国产精品色av免费看| 国产精品自拍一二三四区| 亚洲另类激情专区小说图片| 亚洲深深色噜噜狠狠网站| 日韩精品亚洲 国产| 麻豆国产va免费精品高清在线| 欧美激情一区二区| 伊人无码精品久久一区二区| 中文字幕人妻日韩精品| 欧美精品一区二区三区中文字幕 | 日本高清视频网站www| 中文字幕人妻少妇引诱隔壁| 亚洲无人区一码二码三码| 青草成人精品视频在线看| 亚洲人成亚洲人成在线观看| 欧美性猛交xxxx免费看|