Vue利用jQuery分页,CheckBox记住上一页下一页选中,包括全选和反选点击下一页依然记住选中

2019年6月2日

前几天有人说这个好像不行,当时是直接从项目分离,没有后台好像你们都运行不了。算了,重新整理一下。代码只是把它变为demo了,因为没有后台分页就算了,只要记住一点v-model相当于一个数组,它会帮你存储数组,利用这个数组会每次自动选上,下面的代码有一个更多选项也是无法演示的。懒得弄了!就直接把全选和反选弄出来吧,要玩自己看我以前的代码,琢磨一下,很锻炼人。弄懂了,以后你就不怕看别人代码看不懂。

讲讲全选和反选的实现原理吧。

首先你的有几个数据,我们就准备

checkboxList:[
            {songId:'1',songName:'name1',songSinger:'123'},
            {songId:'2',songName:'name2',songSinger:'234'},
            {songId:'3',songName:'name3',songSinger:'345'}
        ]

的数据,

然后让它能够在页面上显示,

<li v-for="(list,index) in checkboxList">
                 <div>
                     <label>
                          <input type="checkbox" :value="list.songId" 
                              class="input_agreement_protocol" v-model='checkList'>
                      <span class="lists">{ {list.songName}}</span>
                    </label>
                    <span class="layui-col-md">{ {list.songSinger}}</span>
                </div>
             </li>

利用for循环遍历出实例值,显示在页面上。

然后我们得准备一个全选按钮,所以在页面上你得有

<div class="checkAll">
             <label>
                  <input class="input_agreement_protocol" type="checkbox" class="checkedAll"
                       v-model='checked' v-on:click='checkedAll'/>
            </label>
            <label>全选</label>
         </div>

现在页面上大致东西都有了,还缺少对应控制全选和反选的js代码。

在vue.js对应里你的有

checked: false, //全选框

后面就看代码注释吧。

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
		<div id="app1">
		<div class="checkAll">
 			<label>
			      <input class="input_agreement_protocol" type="checkbox" class="checkedAll"
			      	 v-model='checked' v-on:click='checkedAll'/>
			</label>
			<label>全选</label>
     	</div>
     	
     	<ul >
     		<li>
     			<span>歌曲</span>
     			<span>操作</span>
     			<span>歌手</span>
     		</li>
     		<li v-for="(list,index) in checkboxList">
     			<div>
     				<label>
					      <input type="checkbox" :value="list.songId" 
					      	class="input_agreement_protocol" v-model='checkList'>
				      <span class="lists">{
   
   {list.songName}}</span>
					</label>
					<span class="layui-col-md">{
   
   {list.songSinger}}</span>
				</div>
     		</li>
     	</ul>
     	</div>
     	<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
     	<script src="https://cdn.bootcss.com/vue/2.5.21/vue.min.js"></script>
     	<script src="js/index.js"></script>
	</body>
</html>

index.js 

/*
 * Created with Sublime Text 3.
 * User: 李松林
 * Date: 2018-12-24
 * Time: 16:27:55
 */
var app=new Vue({
	el:'#app1',
	data:{
		datas:[],
		checkboxList:[
			{songId:'1',songName:'name1',songSinger:'123'},
			{songId:'2',songName:'name2',songSinger:'234'},
			{songId:'3',songName:'name3',songSinger:'345'}
		],//后台请求的数据
		checked: false, //全选框
	    checkList: [],//临时存放索引的数组
	    isShow:false,
	},
	methods:{	
		checkedAll: function(){
			//全选和反选
			var _this = this;
//			console.log(_this.checked+"---"+_this.checkList+"----"+_this.checkboxList)
 			this.$nextTick(function() {
 				console.log(_this.checked);
 				//判断是否全选、反选
				if(_this.checked){
					//遍历出后台数据,得到对应值和一个索引
					_this.checkList = _this.checkboxList.map(function(json,index){
						console.log(json+","+index)
						return json.songId;
					})
				}else {
					//如果为反选直接将选中的list清空
					_this.checkList = []
				}
			});
		}
	},
	watch: { //深度 watcher(时刻判断是否处于所有选择框全选,不是就全选框不选择)
	   'checkList': {
	   	//当新选中的选择框的总个数等于后台全部数据时,全选框选中,否则不选
	     handler: function(val, oldVal) {
	       if (val.length === this.checkboxList.length) {
	         this.checked = true;
	       } else {
	         this.checked = false;
	       }
	     },
	     deep: true
	   }
	   
	}
});


-------------------------------------------------分割线-----------------------------------------------------------------------------------------------

2018年12月30日

今天这篇博客打算不写demo了,直接从项目中分离出来,大致讲讲原理和实现方法,当然也会提供相应的关键代码。

首先鸣谢某个作者写的jquery插件,从那里扣下来的记不清,抱歉!让我少写好多代码。当然,使用jquery意味着操作dom,而vue明明已经把它剔除掉,然后我还是要用jquery,原谅我,对于vue完全陌生,刚刚接触不到一周时间,很多原理用法完全摸不着思路。

所以,对于vue.js较差的人,我也讲讲学习vue中遇到问题,和弄懂的相应知识。

大佬就请指出不足之处!

--------------------------------------------------------------------------------分-------------------------割---------------------线-------------------------------------

先讲讲我要实现的功能,可能对于你们有一定帮助。

 上面具体功能是点击分类查询相应的数据,渲染在下面的ul li中,使用vue渲染,很容易的和jslt一样,for循环遍历出ajax得到的json数据渲染上;jsp通过java的get/set方法获取,通过java反射实现转换为xml变成标签对,可以用于HTML,不过本质还是java代码,所以为了前后端分离,利用前端框架实现,那么json无疑是最好的数据格式,渲染方便。

全选复选框具有反选和全选功能,这功能代码照样出自百度某位大佬,不过大佬就是大佬上面代码没有一丝解释,让小白来看,复制粘贴可以运行,但是却并没有弄明白是这样实现,甚至连注释也没有,让人很恼火。

按照jquery的习惯,我写代码当然是以.js文件来写,而不是.vue。这就很恼火,似乎mian.js到现在也没有看懂,组件的使用还是没有弄懂,不过没关系按照jquery的习惯去实现代码。

至少按照java,JavaScript的思想来写vue,首先创建一个vue对象,在vue对象里封装方法,申明对应的属性。

这一切当然得在一个含有盒子的div使用,首先申明id,

HTML

<div id="app-7">

<p>{ { answer }}</p>

</div>

JS

var app7 = new Vue({

 el: '#app-7',//element元素,对应的div id

data:{

    answer:''//申明一个像json格式的属性,同时用于渲染

}

})

上面vue的教程里都有,并不是哗众取宠,只是想再理理原理。

当然,重中之重的分页和记住选项,这个东西弄了我快三四天了,说实话vue有时候非常不好用,遇到一个很大的问题。这里简单讲讲吧,也想听听你们有没有解决之道。

现在我通过vue+axios从后台获取到我要渲染页面的数据,回调函数渲染这些数据,当页面一进来,立马请求后台渲染数据,这时因为分页是jquery插件,每次访问都会自动生成相应的分页,两个独立的东西,因为上面说的分类按钮,点击查询后会重新请求数据,而这时会重新拿到一个新的分页HTML,它会和上一个HTML分页同时存在,相当于追加在下一行。

这时觉得这东西很不好,我就把回调函数的分页插件代码分离出来,写在methods中一个方法中,同时页面一进来就要同时渲染,可是这页数和总数必须从上一个方法中的回调函数拿到相应的数据,可以在mounted中使用睡眠几秒后成功加载数据,但是这不符合需求。

同时加载这两个方案必然是this is 未定义,取不到上一个方法回调函数的值,我想知道如何让上一个方法回调函数完全执行完毕后,调用下一个方法,这玩意试过$nextTick这个方法,不过并没有什么用,最后还是按照将jquery方法写在then的回调函数中,然后操作dom删除上一个元素。

好了,就不废话了。下面是必须理解的知识。

要想实现vue分页记住选项,你得明白v-model的使用,这个用处就大了。它能记住你的选项,而你只需要从数据库中查询出来的值有一定的唯一索引,其实明白这一步你已经能完成功能了。相较于自己写的JavaScript,取消选中和选中后放入数组中,然后根据数组中的数据回显选中复选框,这个真的非常方便。

不过弄懂这一原理,已是我思考的第三天了。哎......................

还有一个点,全选框其实将v-model="checked"  vue中申明一个checked:false,这样他就有了选中和不选状态,只要添加一个点击事件,让下面的复选框同时具有v-model=“checkList”元素,名字随便取,将你从后台请求到的数据遍历出唯一索引赋值给这个所有数据的复选框checkList,这样就可以全选,当然那个checked是否为true或false,没有选中就赋值checkList=【】,空数组就行。

这代码吧,大家都能百度到的,我只是完善和说说其中我的理解。

这中间还有一个问题,当我点击全选,然后再点击第二页,那么复选框会同时取消,因为你的checkList没有这些索引,这是第二次请求而来的数据,理所当然的没有选中,而你只需要按照上面的方式,遍历出索引赋值给checkList就行,这样就选中了。

下面就是部分相应代码

因为是用了layui的后台模板,就不贴那些干扰视线的代码,很可能会扣掉部分代码。

<div class="layui-btn-group classification" v-for="item in datas">
       <a class="layui-btn layui-btn-primary" href="javascript:void(0);"
 v-on:click="showSong($event)" :id="item.typeId" v-text="item.typeName"></a>
</div>

这是分类的html

  <link rel="stylesheet" href="../../layuiadmin/style/MySong.css" />


<div class="panel-body layadmin-homepage-shadow">
      <div class="checkAll">
            <label class="my_protocol">
				<input class="input_agreement_protocol" type="checkbox"
				 v-model='checked' v-on:click='checkedAll'/>
			</label>
			<label>全选</label>
      </div>
             	
       <ul class="list-inline song">
            <li>
                <span class="song_left layui-col-md7">歌曲</span>
             	<span class="layui-col-md3">操作</span>
             	<span class="singer_right layui-col-md2">歌手</span>
             </li>
             <li class="layui-col-md12" v-for="(list,index) in checkboxList">
             	<div class="layui-col-md7 song_left">
             		<label class="my_protocol">
						<input type="checkbox" :value="list.songId" 
					     class="input_agreement_protocol" v-model='checkList'>
						<span class="lists">{
   
   {list.songName}}</span>
				    </label>
             	</div>
				<div class="layui-col-md4 singer_right">
					<span class="layui-col-md8">
						<i class="layui-icon layui-icon-play"></i>
						<i class="layui-icon layui-icon-add-1"></i>
						<i class="layui-icon layui-icon-file"></i>
						<i class="layui-icon layui-icon-edit"></i>
					</span>
					<span class="layui-col-md">{
   
   {list.songSinger.singerName}}</span>
				</div>
              </li>
           </ul>
             	 
       </div>
       <div id="pageTool"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>

  <script src="../../music/query.js"></script>
  <script src="../../music/paging.js"></script>
  <script src="../../music/song.js"></script>

其中的query.js和paging.js和MySong.css都是我从别人的代码复制过来的,代码就不贴了,直接打包在百度云里,要用就用。

song.js

var app=new Vue({
	el:'#app1',
	data:{
		datas:[],
		checkboxList:[],//后台请求的数据
		checked: false, //全选框
	    checkList: [],//选中的索引集合
	},
	created:function(){
        //一次加载的数据(不在更新)
		this.showClassification();
	},
	mounted:function(){
        //可变动的数据
		this.showSong();
	},
	methods:{	
		showClassification:function(){
			axios.get('http://127.0.0.1:8045/api/type/selectbysingertypeall',{  //params参数必写 , 如果没有参数传{}也可以
			})
	        .then(function (response) {
	            var arr=response.data.data.typeAll;
	            for(var i=0;i<arr.length;i++){
	            	app.datas.push(arr[i]);
	            }
	        })
	        .catch(function (error) {
	         
	        });
		},
		showSong:function(e){
			var _this=this;
			var id=0;
			if(e!=undefined){
				id=e.target.id;
			}
			axios.get('http://127.0.0.1:8045/api/findbisinger',{ //params参数必写 , 如果没有参数传{}也可以
				params:{
					typeId:id//歌手类型
				}
			}).then(function (response) {
	            var arr=response.data.data.list;
                //直接将后台拿到的数据赋值给checkboxList
	            app.checkboxList=arr;
	            console.log(arr);
                //因为后台拿到的数据为pageInfo,所以相应的数据
	            console.log("每页显示条数:"+response.data.data.pageSize+",总数:"+response.data.data.total
	            +",第几页:"+response.data.data.pageNum);
	            this.$nextTick(pageTool(id,response.data.data.pageSize,response.data.data.total));
	        }).catch(function (error) {
	         	
	        });
		},
		checkedAll: function(){
			//全选和反选
			var _this = this;
//			console.log(_this.checked+"---"+_this.checkList+"----"+_this.checkboxList)
 			this.$nextTick(function() {
                //当全选框选中为true时
 				console.log(_this.checked);
				if(_this.checked){
                    //将后台请求的索引给checkList数组
					_this.checkList = _this.checkboxList.map(function(json,index){
						console.log(json+","+index)
						return json.songId;
					})
				}else {
                     //没有选中清空里面数据
					_this.checkList = []
				}
			});
		}
	},
	watch: { //深度 watcher
       //监听事件,当这个数组的新数据长度和请求到的分页数据条数一样,设置全选框的v-mode=“checked”的checked为true或false,然后就能相当于取消选中一样的效果
	   'checkList': {
	     handler: function(val, oldVal) {
	       if (val.length === this.checkboxList.length) {
	         this.checked = true;
	       } else {
	         this.checked = false;
	       }
	     },
	     deep: true
	   }
	   
	}
});
function pageTool(id,pagesize,count){
    //先删除上一个分页HTML
	$('#pageTool').children().remove();
//这里会自动生成相应的分页HTML,只要pagesize:每页显示条数,count:请求数据的总数  $('#pageTool').Paging({pagesize:pagesize,count:count,callback:function(page,size,count){
    	//删除上一页选中项
		//去除掉在checked对象中的对象
		//遍历获取那一页所有的id,比对选中的数组
		console.log("完整的一次复选框",app.checkList);
		console.log(app.checked)
//		app.checkList=[1,2,3,1238];
		$("input:checked").prop('checked','');
		axios.get('http://127.0.0.1:8045/api/findbisinger',{
    		params:{
    			typeId:id,//歌手类型
    			pageNo:arguments[0]
    		}
    	}).then(function(response){
    		var arr=response.data.data.list;
    		app.checkboxList=arr;
    		//当全选被选中,所有复选框选中
    		if(app.checked){
				app.checkList = app.checkboxList.map(function(json,index){
					console.log(json+","+index)
					return json.songId;
				})
			}
    		
    	}).catch(function(error){
    		
    	});
//			console.log('当前第 ' +page +'页,每页 '+size+'条,总页数:'+count+'页')
    }});
}

以上就是全部我对于这个的理解,还有那个相应的jquery百度云在这:链接:https://pan.baidu.com/s/1LtzpK4p-SZldvrDn2-GZwQ 
提取码:acsn 
当然,你们也可以实现完全自主的vue分页,要是写好了,而且好用的话,可否私信给我瞧瞧大佬写的。

猜你喜欢

转载自blog.csdn.net/qq_41520636/article/details/85391078