牛骨文教育服务平台(让学习变的简单)
博文笔记

vue.js 实现 todo list 任务表单-2

创建时间:2017-04-18 投稿人: 浏览次数:149

---------------------------------------------------------------------------------------------------

这个实在 我的前一篇 新添加的 任务表单功能  

 ps: 前一篇链接 点击打开链接

添加 功能有

   1.    双击任务 重新编辑此任务  

               弹出输入框   输入框初始值为原任务的内容    并且只展示输入框 此任务的其他部分隐藏  如果输入为空则不改变原任务

  2. 回车改变任务

 3. 双击任务 输入框自动获取焦点    

            ****  这里获取焦点采用的是 vue.js的自定义指令       具体可参考点击打开链接 

4. 失去焦点 也改变任务  和按回车一个效果

---------------------------------------------------------------------------------------------------------------

具体实现代码中有详细注释

html

<!DOCTYPE html>
<html>
<head>
	
	<meta charset="utf-8" />
	<title>todo list</title>
	<link rel="stylesheet" type="text/css" href="./todo-list.css" />
</head>
<body>
     <div id="head">
     	  任务计划列表
     </div>    
     <div id="main">
     	  <div class="name">添加任务</div>
     	  <!-- 添加键盘事件   并将input的value值 用intext获取 -->
     	  <input type="text" v-model="intext" v-on:keyup.enter="addList" v-focus />
     	  <!-- 添加隐藏的指令 并给出依据 show show不等于0时展示 -->
     	  <div class="task" v-show="show">
     	      <span><i v-text="num"></i>个任务未完成</span>
     	      <div class="task_type">
     	      	<a href="javascript:void(0)">所有任务</a>
     	  	    <a href="javascript:void(0)">未完成任务</a>
     	  	    <a href="javascript:void(0)">完成任务</a>
     	      </div>
     	  	  
     	  </div>
     	  <div class="list">
     	  	   <ul>
     	  	      <!-- 循环产生li标签及其内部标签   并判断是否有内容 没有则不展示 因为在初始化时会产生一个空标签所以才会判断 以免产生空任务 -->
     	  	   	   <li v-for="item in items" v-show="item.text" id="oli" >
     	  	   	    <!-- 动态添加class 当点击选中时添加hidd 目的是显示复选框和删除  
     	  	   	          input 的选择中状态由 ischecked 的值决定 -->
     	  	   	   	  <div id="box"><input type="checkbox" class="
     	  	   	   	  chex" :class="{hidd:item.isChecked,dblclickhidd:item.showed}" v-model="item.isChecked" v-on:click="clickInput(item)"/></div>
     	  	   	   	  <!-- class和前面一样里面包含选中时出现删除线  标签内的内容由text决定 而text由输入内容决定 -->
     	  	   	   	  <!-- 点击重新编辑任务  即点击时隐藏原任务 并且出现输入框  输入框内容为元任务内容-->
     	  	   	   	  <span v-on:click="clickselect(item)" :class="{hidd:item.isChecked}" 
     	  	   	   	    v-on:dblclick="showinput(item)" v-show="!item.showed">{{item.text}}</span>
     	  	   	   	    <!-- 输入框的值用newtext表示  输入完成后将值传给 item.text  v-show 给item中定义showed 初始weifalse 双击后 为true   按回车时将newtext的值传给text   v-focu 自定以聚焦函数  当双击时获取焦点   失去焦点时执行和回车相似功能 -->
     	  	   	   	  <input  type="text" id="newtext"  v-model = "newtext"  v-show="item.showed"  v-on:keyup.enter="addnewtext(item)" v-focu="item.showed"  v-on:blur="blurhidd(item)"/>
     	  	   	   	  <!-- class相同   添加点击删除函数  并且函数接受当前的item,由于去判断在数组中的索引 确定位置 -->
     	  	   	   	  <a href="javascript:void(0)"  :class="{Ahidd:item.isChecked,dblclickhidd:item.showed}" v-on:click="deletList(item)">删除</a>
     	  	   	   	  <a href="javascript:void(0)" :class="{Ahidd:item.isChecked,dblclickhidd:item.showed}" v-on:click="showinput(item)">编辑</a>
     	  	   	   </li>
     	  	   	   
     	  	   </ul>
     	  	   </ul>
     	  </div>
     </div>
     <script type="text/javascript" src="./vue.js"></script>
     <script type="text/javascript" src="./todo-list.js"></script>
</body>
</html>

js

// 实例化

         //自定义指令 自动获取焦点
    	 // 注册一个全局自定义指令 v-focus
		Vue.directive("focus", {
			  // 当绑定元素插入到 DOM 中。
			  inserted: function (el) {
			    // 聚焦元素
			    
			    el.focus()
			  }
			});
var main = new Vue({
    el:"#main",
    
    data:{
    	items:[
    		 {text:null ,  showed: false , isChecked:false },   // ischecked 判断是否被选中
    	],                      // showed 判断是否展示改变任务的输入框
    	intext:"请输入任务",
       
        show: 0,    // 添加判断是否展示输入框下的任务栏依据 初始为0 不展示 
        num: 0,         //  判断未完成的任务数量 初始为0 即没有添加任何任务时
        newtext:"",
    },
    // 自定义局部指令
   directives: {
		  focu: {
		    // 指令的定义---
              update:function (el,binding) {
			    // 聚焦元素

			    if(binding.value)
			        
			        { el.focus()}

			  },
		  }
		},

    methods:{
    	 // 添加任务函数
    	addList: function(){
              console.log(this.intext);
              console.log(this.items[0].text);
              if(this.intext.length!=0)      // 判断输入框是否有输入内容
              {
              	this.items.push({          
              	 		text: this.intext,  // 将输入内容添加到 items.text内
              	 		isChecked:false,     // 使刚输入的未被选中 (注意即使不添加这句也会不选中
              	 		showed:false,        // 但是数组items内相应位置就不会出现ischecked 会使后面需要选中时出现问题)
              	 		
              			});
              	this.show = this.show+1;    //每添加一个任务 任务的总个数加一
              	this.num =  this.num+1;      // 每添加一个任务 未完成任务的总个数加一
              }
              
              // 清空输入框内容
              this.intext = "";  
    	},
    	//双击重新编辑任务
    	 showinput: function(lsi){
    	 	   var om = this.items.indexOf(lsi);       //获取相应的索引值
    	 	   console.log(om);
    	 	   //显示输入框
    	 	   this.items[om].showed = true ;
    	 	   this.newtext = this.items[om].text; 
    	 	   // 隐藏复选框 删除 
    	 	   this.items[om].isChecked = false;
    	 	   console.log(this.items[om].showed );
    	 	   //输入框自动获取焦点

    	 },
    	 //元素失去焦点时
    	 blurhidd:function(lsi){

    	 		var om = this.items.indexOf(lsi);       //获取相应的索引值
    	 		 this.items[om].showed = false;
    	 		 // 判断是否输入内容 如果输入为空则不改变元任务
    	 		if(this.newtext.length != 0)
    	 		{
                     this.items[om].text =  this.newtext;
    	 		}
    	 },

    	 //回车添加新任务
    	 addnewtext:function(lsi){
    	 		var om = this.items.indexOf(lsi);       //获取相应的索引值
    	 		// 隐藏输入框显示任务
    	 		  this.items[om].showed = false;
    	 		// 判断是否输入内容 如果输入为空则不改变元任务
    	 		if(this.newtext.length != 0)
    	 		{
                     this.items[om].text =  this.newtext;
    	 		}

    	 },
    	 // 失去焦点是
    	// 点击文字选中复选框
    	clickselect:function(lsi){
    		   console.log(this.items.indexOf(lsi));
    		   var om = this.items.indexOf(lsi);       //获取相应的索引值
    		   this.items[om].isChecked = !this.items[om].isChecked;  // 当点击相应任务时
    		   														// 选择的状态发生改变
               if(this.items[om].isChecked)
               {                             //如果选中未完成任务减一 否则加一

    		      this.num =  this.num-1;     
               }
               else
               {
               	   this.num =  this.num+1; 
               }
    	},
    	clickInput: function(lsi){

    		  var om = this.items.indexOf(lsi);       //获取相应的索引值
    		   if(this.items[om].isChecked)
               {                             //如果选中未完成任务减一 否则加一

    		      this.num =  this.num-1;     
               }
               else
               {
               	   this.num =  this.num+1; 
               }
    	},
    	// 点击删除
    	deletList: function(lsi){
    		  var om = this.items.indexOf(lsi);
    		  // this.items[om].text=""; //这样并没有完全从数组清除
              
              // 当点击删除时 未完成任务数量变化
              // 变化依据任务是否已经被选中而变化
              // 不能将移出数组先执行 这样就会导致无法判断是否之前已经被选中
              if( this.items[om].isChecked == true)   
              {
              	this.num =  this.num;
              }
              else
              {
              	this.num =  this.num-1;
              }
              this.show= this.show-1;     // 任务总数减一  如果总数等于0时 隐藏
    		  this.items.splice(om,1);     // 移出相应任务

    	}
    }


})


css

 

body{padding: 0;margin:0; font-size: 14px; font-family: "微软雅黑";}
ul,li,a,div,input,span {padding: 0; margin:0;}
a{text-decoration: none; color: #000;}
ul,li {list-style-type: none;}
/*顶部布局*/
#head {
		width: 100%;
		height: 50px;
		font-size: 18px;
		font-weight: bold;
		line-height: 50px;
		text-align: center; }

#main {
	   width: 400px;
	   margin:5px auto;

}
#main .name {
	    font-size: 16px;
	    font-weight: bold;
}
#main input {
	   width: 400px;
	   height: 35px;
       outline: none;
}
#main .task{
	  margin:10px 0;
	  height: 32px;
	  overflow: hidden;
	  line-height: 32px;
}
#main .task span {
	 display: block;
	 height: 30px;
	 float: left;
}
#main .task  .task_type{
	 float: right;
}
#main .task  .task_type a{
		display: block; 
		height: 30px; 
		padding: 0 5px;
		line-height: 30px; 
		border:1px solid #ccc;
		text-decoration: center;
		float: left;
		margin-left: 10px;
	    }
#main .list {
	   width: 400px;

	   clear: both;
}
#main .list ul{
	  width: 400px;
}
#main .list ul li {
	  width: 400px;
	  height: 30px;
	  line-height: 30px;
	  display: block;
	  overflow: hidden;
}
#main .list ul li #newtext{
	  height: 28px;
	  border:1px solid #ccc;
	  width: 250px;
	  float: left;
}
#main .list ul li #box {
	 float: left;
	 width: 16px;
	 height:16px;
	 margin:7px 0;
}
#main .list ul li .chex{
	 display: none;
	
	 width: 16px;
	 height:16px;
	


}
#main .list ul li:hover a{
     display: block;
}
#main .list ul #oli:hover .dblclickhidd{
     display: none;
}
#main .list ul li:hover .chex{
     display: block;
}
#main .list ul li .hidd {
	display: block;
	color: #ccc;
	text-decoration: line-through;
}
#main .list ul li .Ahidd {
	display: block;
	/*color: #ccc;*/
	/*text-decoration: line-through;*/
}
#main .list ul li span {
	 display: block;
	 float: left;
	 margin-left: 20px;

}

#main .list ul li a{

	 display: none;
	 float: left;
	 margin-left: 20px;
}


// 编辑截图


-----------------------------------------------------------

如果有什么不理解可以留言 

如果有错误 请留言指出   谢谢

或者更好的建议

-------------------------------------------------------------


声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。