Vue学习笔记一 列表形式数据展示

1. MVC和MVVM

1.1 MVC模式

  MVC模式是Web后端的常用的开发模式。model层一般都是实体类,有时候会多一个dao层用于专门写sql的操作,view层是前端,controller层编写业务逻辑。

1.2 MVVM模式

  Vue.js框架为了方便开发,使用了MVVM模式,它是前端页面的一种开发模式,分为M,V和VM,MVVM提供了数据的双向绑定。

2. 数据双向绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>document</title>
		<!-- 导入Vue的包 -->
		<script src="https://cdn.staticfile.org/vue/2.6.12/vue.min.js"></script>
	</head>
	
	<body>
		
		<!-- MVVM里的View层 -->
		<div id="app">
			<p>{{ msg }}</p>
		</div>
		
		<script>
			// 创建一个Vue的实例,vm就是MVVM里的vm调度者
			var vm = new Vue({
				el: '#app',		//当前Vue对象要控制html页面哪个区域
				// data对应MVVM中的Model
				
				data: {			//data属性中,存放el中要用到的数据
					msg:'欢迎学习Vue'		// 使用 Vue 提供的指令,直接将数据渲染到页面上
				}
			})
		</script>
	</body>
</html>

2.1 v-model双向绑定

  View中的input通过v-model和vm中的id进行双向绑定,input中内容发生变化,在vm中可以检测到。

<div id="app">
	<label>
		Id:
		<input type="text" class="form-control" v-model="id"/>
	</label>
</div>
var vm = new Vue({
	el:'#app',
	data:{
		id:'',		// 与Id文本框进行了双向绑定,可以自动拿到文本框里的值
		list:[
			{ id:1, name:'奔驰',ctime:new Date() },
			{ id:2, name:'宝马',ctime:new Date() }
		]
	}
})

2.2 v-for数据展示

  Vue中数据保存在model中,即上面中的data,以数组的形式存在,如上面的list。

	<!-- 表身 -->
	<tbody>
		<tr v-for="item in list" :key="item.id"><!-- 这里key如果不加:就当做一个字符串了 -->
			<td>{{ item.id }}</td>
			<td>{{ item.name }}</td>
			<td>{{ item.ctime }}</td>
			<td>
				<a href="#">删除</a>
			</td>
		</tr>
	</tbody>

2.3 this.list.push(car)向数组添加元素

	add(){ // 添加一个car的信息
		// console.log('ok!')
		// 1. 获取到id和name
		// 2. 组织出一个对象
		var car = {id:this.id,name:this.name,ctime:new Date()}
		// 3. 把对象添加的 data 中去
		this.list.push(car)
		
		this.id = ''
		this.name = ''
	}

2.4 this.list.splice(index,1)删除数组元素

  删除的时候,1. 先根据拿到想要删除对象的一个属性,比如id,或者name。2. 根据该属性找到对象在数组中的索引,也就是findIndex()函数的作用。3. splice()方法删除该索引位置的对象

	del(id){ // 根据删除一个car的信息
		// 根据id查询对象在list中的index
		var index = this.list.findIndex(item => { 	// 遍历list,将集合中每个元素传入item,
			if (item.id == id){						// 如果返回true,findIndex方法将这个item对应的index 返回
				return true
			}
		})
		this.list.splice(index,1)
	}

3. 关键字查询

  这里关键字查询的操作方式,为前端列表数据的展示提供了一个新的思路。不去遍历整个list数组,而是遍历按照指定条件的查询结果(一个新数组)。
做个总结,查询数组对象的index使用findIndex()方法;查询整个对象用filter()方法

	<tbody>
	<tr v-for="item in search(keywords)" :key="item.id"><!-- 这里key如果不加:就当做一个字符串了 -->
		<td>{{ item.id }}</td>
		<td>{{ item.name }}</td>
		<td>{{ item.ctime }}</td>
		<td>
			<a href="#" @click.prevent="del(item.id)">删除</a>
		</td>
	</tr>
	</tbody>
	search(keywords){
		var newList = this.list.filter(item => {	// 遍历list将集合中每个元素传入item,
			if (item.name.includes(keywords)){		// 如果item.name中包含keywords,返回item
				return item
			}
		})
		return newList
	}

4. 过滤器

  后端传过来的数据,有可能跟想要展示在前台的数据不一样,比如在前端显示时间,通常是按照yyyy-mm-dd的形式展示,但后台拿过来的数据有可能是时间戳。这个时候就需要对数据进行加工处理后,再显示出来。

<td>{{ item.ctime | dateFormat("yyyy-mm-dd") }}</td>
	// 全局过滤器,进行时间格式化
	Vue.filter('dateFormat',function(dateStr,pattern){				
		// 根据字符串拿到时间
		var dt = new Date(dateStr)
		
		// 拿到年月日
		var y = dt.getFullYear()
		var m = (dt.getMonth()+1).toString().padStart(2,'0')	// 使用ES6提供的方法,将月份补充为2位
		var d = dt.getDate().toString().padStart(2,'0')
		
		// 如果输入格式为yyyy-mm-dd
		if (pattern && pattern.toLowerCase() == 'yyyy-mm-dd') {
			return `${y}-${m}-${d}`
		}else{		// 如果输入格式
			var hh = dt.getHours().toString().padStart(2,'0')
			var mm = dt.getMinutes().toString().padStart(2,'0')
			var ss = dt.getSeconds().toString().padStart(2,'0')
			return `${y}-${m}-${d}:${hh}:${mm}:${ss}`
		}
	})

5. 完整代码

在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Document</title>
		<!-- 导入View.js包 -->
		<script src="https://cdn.staticfile.org/vue/2.6.12/vue.js"></script>
		<!-- 导入bootstrap样式 -->
		<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" />
	</head>
	
	<body>
		
		<div id="app">
			
			<!-- 添加品牌,panel面板 -->
			<div class="panel panel-primary">
				
				<!-- panel面板header -->	
				<div class="panel-heading">
					<h3 class="panel-title">添加品牌</h3>
				</div>
				
				<!-- panel面板body -->
				<div class="panel-body form-inline">
					<label>
						Id:
						<input type="text" class="form-control" v-model="id"/>
					</label>
					
					<label>
						Name:
						<input type="text" class="form-control" v-model="name" @keyup.enter="add()" />
					</label>
					
					<input type="button" value="添加" class="btn btn-primary" @click="add()"/>
					
					<label>
						搜索:
						<!-- 这里v-color中如果不加单引号,表示data中的变量,加了表示字符串 -->
						<input type="text" class="form-control" v-model="keywords" v-focus v-color="'red'" />
					</label>
					
				</div>
			</div>
			
			<!-- 品牌列表 -->
			<table class="table table-bodered table-hover table-striped">
				<!-- 表头 -->
				<thead>
					<tr>
						<th>Id</th>
						<th>Name</th>
						<th>Ctime</th>
						<th>Operation</th>
					</tr>
				</thead>
				
				<!-- 表身 -->
				<tbody>
					<tr v-for="item in search(keywords)" :key="item.id"><!-- 这里key如果不加:就当做一个字符串了 -->
						<td>{{ item.id }}</td>
						<td>{{ item.name }}</td>
						<td>{{ item.ctime | dateFormat("yyyy-mm-dd") }}</td>
						<td>
							<a href="#" @click.prevent="del(item.id)">删除</a>
						</td>
					</tr>
				</tbody>
			</table>
			
		</div>
		
		<script>
			// 全局过滤器,进行时间格式化
			Vue.filter('dateFormat',function(dateStr,pattern){				
				// 根据字符串拿到时间
				var dt = new Date(dateStr)
				
				// 拿到年月日
				var y = dt.getFullYear()
				var m = (dt.getMonth()+1).toString().padStart(2,'0')	// 使用ES6提供的方法,将月份补充为2位
				var d = dt.getDate().toString().padStart(2,'0')
				
				// 如果输入格式为yyyy-mm-dd
				if (pattern && pattern.toLowerCase() == 'yyyy-mm-dd') {
					return `${y}-${m}-${d}`
				}else{		// 如果输入格式
					var hh = dt.getHours().toString().padStart(2,'0')
					var mm = dt.getMinutes().toString().padStart(2,'0')
					var ss = dt.getSeconds().toString().padStart(2,'0')
					return `${y}-${m}-${d}:${hh}:${mm}:${ss}`
				}
				
			})
			
			// 自定义按键修饰符
			Vue.config.keyCodes.f2 = 113	// 将f2键的keyCode为113,将113和f2绑定
			
			// 自定义指令,调用指令时需要加v-
			Vue.directive('focus',{
				bind: function(el){
					
				},
				inserted: function(el){	// inserted 表示元素插入到DOM中到时候,会执行inserted函数,el为JS原生元素
					el.focus()			// 从内存渲染到页面上的时候,执行inserted
				}
			})
			
			Vue.directive('color',{
				bind: function(el,binding){
					// binding.expression = 'red',binding.value=red
					el.style.color = binding.value		// 一加载到内存中去,就调用
				}										// 不管元素有没有被插入到页面中去,这个元素就已经有了一个内联样式
			})
			
			var vm = new Vue({
				el:'#app',
				data:{
					id:'',		// 与Id文本框进行了双向绑定,可以自动拿到文本框里的值
					name:'',	// 与Name 文本框进行了双向绑定,可以自动拿到文本框里的值
					keywords:'',	// 搜索的关键字
					list:[
						{ id:1, name:'奔驰',ctime:new Date() },
						{ id:2, name:'宝马',ctime:new Date() }
					]
				},
				methods:{
					add(){ // 添加一个car的信息
						// console.log('ok!')
						// 1. 获取到id和name
						// 2. 组织出一个对象
						var car = {id:this.id,name:this.name,ctime:new Date()}
						// 3. 把对象添加的 data 中去
						this.list.push(car)
						
						this.id = ''
						this.name = ''
					},
					del(id){ // 根据删除一个car的信息
						// 根据id查询对象在list中的index
						var index = this.list.findIndex(item => { 	// 遍历list,将集合中每个元素传入item,
							if (item.id == id){						// 如果返回true,findIndex方法将这个item对应的index 返回
								return true
							}
						})
						this.list.splice(index,1)
					},
					search(keywords){
						var newList = this.list.filter(item => {	// 遍历list将集合中每个元素传入item,
							if (item.name.includes(keywords)){		// 如果item.name中包含keywords,返回item
								return item
							}
						})
						return newList
					}
					
					
				}
			});	
		</script>
	</body>
</html>

6. 疑问

  • 这里的添加操作,仅仅是向vue中的model中添加数据,并没有添加到数据库中。如果单纯为了演示效果的话,这个例子可以理解。问题是,在实际项目中,这样的操作,会有应用场景吗?
  • 查询并不是从数据库中过滤数据,而是从model中过滤数据,有什么样的应用场景?
  • 像这种逻辑性较强的编程式渲染,会影响浏览器加载页面的速度吗?
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值