Vue笔记(二)

跑马灯效果

<div id="app0">
	<button @click="go()">走起来</button>
	<button @click="stop()">停下来</button>
	<p>{{msg}}</p>
</div>
const vm = new Vue({
	el:'#app0',
	data:{
		msg:'走起来呀走起来,停停停!!',
		intervalId:null,  //在data上定义定时器id
	},
	methods:{
		go(){
			if(this.intervalId != null ) return;
			this.intervalId = setInterval( () => {
				//先获得 第一个字符,注意用substring, 不改变原来的字符串
				var start = this.msg.substring(0, 1)
				//获得 除了第一个字符以外,剩下的所有的字符串
				var end = this.msg.substring(1)
				//将第一个字符start 添加到字符串end 的后面
				this.msg = end + start
			},400)
			//subtring(beginIndex, endIndex)方法返回字符串的子字符串  
			//beginIndex:起始索引(包括), 索引从 0 开始。
			//endIndex:结束索引(不包括)
			
			//this 指向问题:在ES6中,箭头函数内部的this与箭头函数外部的this指向是一样的
			//也可以用普通匿名函数:function(){},只不过在这个函数外边,先重新定义一下this:var _this=this,在函数体内部,把this全部换成_this,结果是一样的。
		},
		stop(){
			clearInterval(this.intervalId);
			//每当清除了定时器之后,要重新把intervalId设置为null。
			this.intervalId = null
		},
	},

打开的效果如下图:在这里插入图片描述
点击【走起来】按钮以后,下边的文字就会开始走动,过一段时间,点击【停下来】按钮,就会停止,再次点击【走起来】会在停止的基础上接着走起来。在这里插入图片描述

点击那个,那个的文字变成红色

可以应用在导航切换等地方

<style>
	.active{ color:red; }
</style>

<div id="app1">
	<ul>
    	<li :class="{active:currentIndex == index}" 
    		@click="btnClick2(index)"  
    		v-for="(item,index) in movies">
    		{{index}} -- {{item}}
    	</li>
    </ul>
</div>
var vm=new Vue({
	el:'#app1',
	data:{
		movies:['海王','泰坦尼克号','速度与激情','花木兰','我和我的祖国','大鱼海棠'],
		currentIndex:0,    //数字为下标,如果是null就表示默认的没有选择任何一个。
	},
	methods:{
		btnClick2 (index){ this.currentIndex = index; },
	},
})

默认的打开以后,效果如下图:在这里插入图片描述

品牌案例,添加新的品牌,删除,筛选

添加和删除比较容易,添加用push,删除用splice就可以实现,下面是添加和删除的案例

<!--引入bootstrap.css-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<div id="app2">
	<div class="table-box">
		<div class="panel panel-primary">
			<div class="panel-heading">
				<h3 class="panel-title">添加品牌</h3>
			</div>
			<div class="panel-body form-inline">
				<label>Id:<input type="text" class="form-control" v-model="id"/></label>
				<!-- @keyup.enter 键盘事件监听,监听回车键 -->
				<label>Name:<input type="text" class="form-control" v-model="name" @keyup.enter="addTr"/></label>
				<button @click="addTr" class="btn btn-primary">添加</button>
			</div>
		</div>
		<table class="table table-bordered table-hover table-striped">
			<thead>
				<tr>
					<th>Id</th>
					<th>品牌名称</th>
					<th>添加时间</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody>
				<tr v-for="(value,index) in list">
					<td>{{value.id}}</td>
					<td v-text="value.name"></td>
					<td>{{value.ctime}}</td>
					<td><a @click="deleteTr(index)">删除</a></td>
				</tr>
			</tbody>
		</table>
	</div>
</div>
var vm=Vue({
	el:"#app2",
	data:{
		list:[
			{id:1,name:'宝马',ctime:new Date()},
			{id:2,name:'奔驰',ctime:new Date()}
		],
		id:'',
		name:'',
		keywords:'',  //Vue.js 调试工具 devtools
	},
	methods:{
		//添加  list.push()
		addTr(){
			var newTr = {
				id:this.id, 
				name:this.name, 
				ctime:new Date()
			};
			this.list.push(newTr);
			this.id = this.name = '';
		},
		//删除 list.splice(要删除项的下标,1)
		deleteTr(index){
			this.list.splice(index,1)
		},
	},
})

过滤:这里的例子主要是过滤表格中的“ 品牌名称 ”这一列。用 filter 和 includes 结合来进行过滤
        展示的列表是因为循环了list数组,根据内容才展示出来的。我们现在需要根据新的关键字,来确定下边展示的列表内容(过滤关键字),也就是这个列表的内容是不固定的。所以这时候,就不能循环list数组了,要循环一个新数组,并且在循环数组的div上要绑定一个key,这个key就是关键字。

<tr v-for="(value,index) in search(keywords)" :key='value.id'>... ...</tr>

        要根据关键字搜索,在表格列表上方添加一个输入框,输入需要搜索的关键字,并且对这个输入框进行一个双向绑定

<label>搜索名称关键字:<input type="text" class="form-control" v-model="keywords" /></label>

完整的代码:

<!--引入bootstrap.css-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<div id="app2">
	<div class="table-box">
		<div class="panel panel-primary">
			<div class="panel-heading">
				<h3 class="panel-title">添加品牌</h3>
			</div>
			<div class="panel-body form-inline">
				<label>Id:<input type="text" class="form-control" v-model="id"/></label>
				<!-- @keyup.enter 键盘事件监听,监听回车键 -->
				<label>Name:<input type="text" class="form-control" v-model="name" @keyup.enter="addTr"/></label>
				<button @click="addTr" class="btn btn-primary">添加</button>
				<label>搜索名称关键字:<input type="text" class="form-control" v-model="keywords" /></label>
			</div>
		</div>
		<table class="table table-bordered table-hover table-striped">
			<thead>
				<tr>
					<th>Id</th>
					<th>品牌名称</th>
					<th>添加时间</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody>
				<!--之前都是在list数组中循环渲染过来的,现在定义了一个search方法,
					同时把搜索的关键字,通过传参的形式传递给search方法
					search方法 通过for循环 过滤list数组上的数据,把符合的数据保存到一个新数组中,
					再重新进行渲染
				-->
				<tr v-for="(value,index) in search(keywords)" :key='value.id'>
					<td>{{value.id}}</td>
					<td v-text="value.name"></td>
					<td>{{value.ctime}}</td>
					<td><a @click="deleteTr(index)">删除</a></td>
				</tr>
			</tbody>
		</table>
	</div>
</div>
var vm=Vue({
	el:"#app2",
	data:{
		list:[
			{id:1,name:'宝马',ctime:new Date()},
			{id:2,name:'奔驰',ctime:new Date()}
		],
		id:'',
		name:'',
		keywords:'',  //Vue.js 调试工具 devtools
	},
	methods:{
		//添加  list.push()
		addTr(){
			var newTr = {
				id:this.id, 
				name:this.name, 
				ctime:new Date()
			};
			this.list.push(newTr);
			this.id = this.name = '';
		},
		//删除 list.splice(要删除项的下标,1)
		deleteTr(index){
			this.list.splice(index,1)
		},
		search(keywords){
			var newList = [];
			this.list.forEach(item => {
				if(item.name.indexOf(keywords) != -1){ //indexOf 查询复合字符串的下标
					newList.push(item);
				}
			})
			return newList
			
//			【注意】forEach    some    filter    findIndex  这些都属于数组新方法
//			都会对数组中的每一项,进行遍历,执行相关的操作。
			//ES6中新增的字符串方法,string.prototype.includes("要包含的字符串"),包含返回true,不包含返回false
//			var newList = this.list.filter(item => {
//				if(item.name.includes(keywords)){          //includes 判断是否包含指定字符串,空都包含
//					return item
//				}
//			})
//			return newList;
		},
	},
})

这里,时间的格式不是标准的时间格式,我们可以对时间进行一个调整,这里可以用vue里面提供的过滤器 filter 来进行格式化。
过滤器可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache插值和v-bind表达式。放在script表达式的尾部。
先写个 filter 例子:

<div id="app4">
	<!--每个过滤器可以有多个替换值,用逗号隔开。
		过滤器可以多次调用,用 “管道” 也就是 “ | ” 隔开就可以-->
	<p>{{msg | msgFormat("123","哈哈哈") | test}}</p>
</div>
Vue.filter('msgFormat', function(msg, arg, arg2){
	return msg.replace(/单纯/g, arg + arg2);
})
Vue.filter('test',function(msg){
	return msg + "======"
})
var vm=new Vue({
	el:'#app4',
	data:{
		msg:'单纯的少年,单纯的问,谁是最单纯的人?'
	}
})

渲染出来的效果:在这里插入图片描述
现在就根据上边说的filter的特性,给 品牌案例 的 “添加事件” 做修改吧。
(包括把一位数的时间调成为两位数,这里用了两种方法)

<!--引入bootstrap.css-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<div id="app2">
	<div class="table-box">
		<div class="panel panel-primary">
			<div class="panel-heading">
				<h3 class="panel-title">添加品牌</h3>
			</div>
			<div class="panel-body form-inline">
				<label>Id:<input type="text" class="form-control" v-model="id"/></label>
				<!-- @keyup.enter 键盘事件监听,监听回车键 -->
				<label>Name:<input type="text" class="form-control" v-model="name" @keyup.enter="addTr"/></label>
				<button @click="addTr" class="btn btn-primary">添加</button>
				<label>搜索名称关键字:<input type="text" class="form-control" v-model="keywords" /></label>
			</div>
		</div>
		<table class="table table-bordered table-hover table-striped">
			<thead>
				<tr>
					<th>Id</th>
					<th>品牌名称</th>
					<th>添加时间</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody>
				<!--之前都是在list数组中循环渲染过来的,现在定义了一个search方法,
					同时把搜索的关键字,通过传参的形式传递给search方法
					search方法 通过for循环 过滤list数组上的数据,把符合的数据保存到一个新数组中,
					再重新进行渲染
				-->
				<tr v-for="(value,index) in list">
					<td>{{value.id}}</td>
					<td v-text="value.name"></td>
					<td>{{value.ctime | dateFormat()}}</td>
					<td><a @click="deleteTr(index)">删除</a></td>
				</tr>
			</tbody>
		</table>
	</div>
</div>
//全局过滤器  过滤   定义时间格式
Vue.filter('dateFormat',function(dateStr,pattern="" ){
	//根据给定的字符串,得到特定的时间
	var dt = new Date(dateStr)
	var y = dt.getFullYear()
	var m = dt.getMonth() + 1
	var d = dt.getDate()
	//不确定是大写还是小写,就先统一一下,这里都统一成小写的
	if(pattern.toLowerCase() === 'yyyy-mm-dd'){
	return `${y}-${m}-${d}`
	}else{
		var hh = dt.getHours()
		var mm = dt.getMinutes()
		var ss = dt.getSeconds()
		return `${y}-${t(m)}-${t(d)} ${t(hh)}:${t(mm)}:${t(ss)}`
	}
	function t(s){return s<10 ? '0'+s : s}  //时间写成两位数的
})
var vm=Vue({
	el:"#app2",
	data:{
		list:[
			{id:1,name:'宝马',ctime:"2021-10-18 16:5:4"},
			{id:2,name:'奔驰',ctime:new Date()}
		],
		id:'',
		name:'',
		keywords:'',  //Vue.js 调试工具 devtools
	},
	methods:{
		addTr(){
			var newTr = {
				id:this.id, 
				name:this.name, 
				ctime:new Date()
			};
			this.list.push(newTr);
			this.id = this.name = '';
		},
		deleteTr(index){
			this.list.splice(index,1)
		},
		search(keywords){
			var newList = [];
			this.list.forEach(item => {
				if(item.name.indexOf(keywords) != -1){ //indexOf 查询复合字符串的下标
					newList.push(item);
				}
			})
			return newList
		},
	},
	filters:{   
		//定义私有过滤器,过滤器有两个条件,过滤器名称和函数
		//过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致,优先私有过滤器
		dateFormat(dateStr,pattern="" ){
			var dt = new Date(dateStr)
			var y = dt.getFullYear()
			var m = dt.getMonth() + 1
			var d = dt.getDate()
			if(pattern.toLowerCase() === 'yyyy-mm-dd'){
				return `${y}-${m}-${d}`
			}else{
				//把时间定义成两位(比如8分钟写成08)
				//第一种方法
				//function t(s){return s<10 ? '0'+s : s} 
				//var hh = dt.getHours()
				//var mm = dt.getMinutes()
				//var ss = dt.getSeconds()
				//return `${y}-${t(m)}-${t(d)} ${t(hh)}:${t(mm)}:${t(ss)} ~~~~~`
				
				//第二种 使用ES6中的字符串新方法String.prototype.padStart(maxLength, fillString='')
				//或者String.prototype.padEnd(maxLength, fillString='') 来填充字符串
				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} ~~~~~`
			}	
		},
	}
})

我们希望啊,页面刚打开的时候,搜索关键字的输入框可以 自动获焦 ,我们可以用autofocus属性,也可以自己 自定义一个属性,得到我们要的结果。

使用 Vue.directive() 自定义全局的指令 v-focus。【注意】局部的指令,用directives:{focus:{… …}}
参数1:指令的名称,注意,在定义的时候,指令的名称前边,不需要加 v- 前缀,
但是在调用的时候,需要在指令名称前加上 v- 前缀
参数2:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

//注意:在每个函数中,第一个参数,永远是el,代表被绑定的元素,这个el参数,是一个原生的JS对象
Vue.directive('focus',{
	//	bind:function(el){ el.focus() }
	//每当指令绑定到元素上的时候, 会立即执行这个bind 函数,只执行一次		
	//在元素刚绑定了指令的时候,还没有插入到DOM中去,这时候,调用focus方法没有作用,因为,一个元素,只有插入DOM之后,才能获取焦点
	//样式,只要通过指令帮顶给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联样式
	//将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然回解析样式,应用给这个元素。
	和样式相关的操作,一般都可以在bind执行
	
	//	inserted 表示元素插入到DOM中的时候,会执行inserted函数,触发一次
	和JS行为有关的操作,最好在 inserted 中去执行
	inserted:function(el){ el.focus() }
	
	//	updated:function(el){ el.focus() }
	//当组件 VNode 更新的时候,会执行updated,可能会触发多次
})

Vue.directive('color',{
//这里用bind就可以,因为样式不需要关心这个元素在哪里。
//而上边自定义的focus,是要给制定的DOM元素设置的,只能用inserted,它表示元素插入到DOM中了已经

//	bind:function(el){el.style.color = 'red'}
	bind(el,binding){ 
		console.log(binding.name)
		console.log(binding.value)
		console.log(binding.expression)
		el.style.color = binding.value 
	}
})

也可以在Vue的内部使用 directives 属性,进行自定义的设置:

var vm=new Vue({
	el:'#app2',
	//定义私有  自定义指令,名称和函数体
	directives:{
		'bold':{
			bind:function(el,binding){ el.style.fontWeight = binding.value }
		}
	}
})

在bind函数里边,参数中的第二个参数 bingding 是怎么来的?在vue的文档里边有说明
在这里插入图片描述
在HTML中进行应用:

<label>搜索名称关键字:<input type="text" class="form-control" v-model="keywords" v-focus v-color="'blue'" /></label>

【注意】v-color=" ‘blue’ " 这里面的blue是字符串类型的,如果不加里边的引号,就是变量了。

最终最终的完整代码如下:

<!--引入bootstrap.css-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<div id="app2">
	<div class="table-box">
		<div class="panel panel-primary">
			<div class="panel-heading">
				<h3 class="panel-title">添加品牌</h3>
			</div>
			<div class="panel-body form-inline">
				<label>Id:<input type="text" class="form-control" v-model="id"/></label>
				<!-- @keyup.enter 键盘事件监听,监听回车键 -->
				<label>Name:<input type="text" class="form-control" v-model="name" @keyup.enter="addTr"/></label>
				<button @click="addTr" class="btn btn-primary">添加</button>
				<label>搜索名称关键字:<input type="text" class="form-control" v-model="keywords" v-focus v-color="'blue'" /></label>
			</div>
		</div>
		<table class="table table-bordered table-hover table-striped">
			<thead>
				<tr>
					<th>Id</th>
					<th>品牌名称</th>
					<th>添加时间</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody>
				<!--之前都是在list数组中循环渲染过来的,现在定义了一个search方法,
					同时把搜索的关键字,通过传参的形式传递给search方法
					search方法 通过for循环 过滤list数组上的数据,把符合的数据保存到一个新数组中,
					再重新进行渲染
				-->
				<tr v-for="(value,index) in list">
					<td>{{value.id}}</td>
					<td v-text="value.name"></td>
					<td>{{value.ctime | dateFormat()}}</td>
					<td><a @click="deleteTr(index)">删除</a></td>
				</tr>
			</tbody>
		</table>
	</div>
</div>
//全局过滤器  过滤   定义时间格式
Vue.filter('dateFormat',function(dateStr,pattern="" ){
	//根据给定的字符串,得到特定的时间
	var dt = new Date(dateStr)
	var y = dt.getFullYear()
	var m = dt.getMonth() + 1
	var d = dt.getDate()
	//不确定是大写还是小写,就先统一一下,这里都统一成小写的
	if(pattern.toLowerCase() === 'yyyy-mm-dd'){
	return `${y}-${m}-${d}`
	}else{
		var hh = dt.getHours()
		var mm = dt.getMinutes()
		var ss = dt.getSeconds()
		return `${y}-${t(m)}-${t(d)} ${t(hh)}:${t(mm)}:${t(ss)}`
	}
	function t(s){return s<10 ? '0'+s : s}  //时间写成两位数的
})
//自定义属性 v-focus
//注意:在每个函数中,第一个参数,永远是el,代表被绑定的元素,这个el参数,是一个原生的JS对象
Vue.directive('focus',{
	inserted:function(el){ el.focus() }
})
//自定义属性 v-color
Vue.directive('color',{
	bind(el,binding){ 
		el.style.color = binding.value 
	}
})
var vm=Vue({
	el:"#app2",
	data:{
		list:[
			{id:1,name:'宝马',ctime:"2021-10-18 16:5:4"},
			{id:2,name:'奔驰',ctime:new Date()}
		],
		id:'',
		name:'',
		keywords:'',  //Vue.js 调试工具 devtools
	},
	methods:{
		addTr(){
			var newTr = {
				id:this.id, 
				name:this.name, 
				ctime:new Date()
			};
			this.list.push(newTr);
			this.id = this.name = '';
		},
		deleteTr(index){
			this.list.splice(index,1)
		},
		search(keywords){
			var newList = [];
			this.list.forEach(item => {
				if(item.name.indexOf(keywords) != -1){ //indexOf 查询复合字符串的下标
					newList.push(item);
				}
			})
			return newList
		},
	},
	//定义私有的 自定义指令,名称和函数体
	directives:{     
		'bold':{
			bind:function(el,binding){ el.style.fontWeight = binding.value }
		},
		'fontsize':function(el,binding){   //注意:这个function等同于把代码写到了bind和updated中去
			el.style.fontSize = parseInt(binding.value)+'px' 
		},
	},
	filters:{   
		//定义私有过滤器,过滤器有两个条件,过滤器名称和函数
		//过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致,优先私有过滤器
		dateFormat(dateStr,pattern="" ){
			var dt = new Date(dateStr)
			var y = dt.getFullYear()
			var m = dt.getMonth() + 1
			var d = dt.getDate()
			if(pattern.toLowerCase() === 'yyyy-mm-dd'){
				return `${y}-${m}-${d}`
			}else{
				//把时间定义成两位(比如8分钟写成08)
				//第一种方法
				//function t(s){return s<10 ? '0'+s : s} 
				//var hh = dt.getHours()
				//var mm = dt.getMinutes()
				//var ss = dt.getSeconds()
				//return `${y}-${t(m)}-${t(d)} ${t(hh)}:${t(mm)}:${t(ss)} ~~~~~`
				
				//第二种 使用ES6中的字符串新方法String.prototype.padStart(maxLength, fillString='')
				//或者String.prototype.padEnd(maxLength, fillString='') 来填充字符串
				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} ~~~~~`
			}	
		},
	}
})

默认打开的样子是这样的
在这里插入图片描述
添加一个“宝宝”,渲染以后是这样的在这里插入图片描述
在过滤的input框输入“宝”,结果只显示两项,如图在这里插入图片描述
点击“宝宝”一行的“删除”,这一行都删除了,结果如下
在这里插入图片描述

购物车案例

<div id="app4">
	<!--如果购物车有内容-->
	<div v-if="books.length">
	   	<table border="1" cellspacing="0">
	    	<thead>
	    	<tr>
	    		<td></td>
	    		<td>书籍名称</td>
	    		<td>出版日期</td>
	    		<td>价格</td>
	    		<td>购买数量</td>
	    		<td>操作</td>
	    	</tr>
	    	</thead>
	    	<tbody>
	    	<tr v-for="(item,index) in books">
	    		<td>{{item.id}}</td>
	    		<td>{{item.name}}</td>
	    		<td>{{item.date}}</td>
	    		<td>{{item.price | showPrice}}</td>    <!--<td>{{'¥' + item.price.toFixed(2)}}</td>--> <!--<td>{{result(item.price)}}</td>-->
	    		<td>
	    			<!--<button @click="reduceNum(index)" :disabled="item.num <= 1">-</button>-->
	    			<button @click="reduceNum(index)">-</button>
	    			{{item.num}}
	    			<button @click="addNum(index)">+</button>
	    		</td>
	    		<td><button @click="deleteTr(index)">移除</button></td>
	    	</tr>
	    	</tbody>
	    </table>
	    <h3>总价格:{{allPrice | showPrice}}</h3>
	</div>
	<!--如果没有数据,购物车为空-->
	<div v-else><h3>购物车为空</h3></div>
</div>
var vm=new Vue({
	el:'#app4',
	data:{
		books:[
	    	{id:1,name:'算法导论',date:'2006-9',price:85.00,num:5},
	    	{id:2,name:'UNIX编程艺术',date:'2006-2',price:59.00,num:1},
	    	{id:3,name:'编程珠玑',date:'2008-10',price:39.00,num:1},
	    	{id:4,name:'代码大全',date:'2006-3',price:128.00,num:1}
	    ]
	},
	methods:{
		result (price){ return '¥' + price.toFixed(2) },
		reduceNum(index){ 
			if(this.books[index].num > 1) {
				this.books[index].num -= 1;
			} else {
				alert('不能再减了'); 
			}  
		},
		addNum(index){ this.books[index].num += 1; },
		deleteTr(index){ 
			let result = confirm("确定要删除吗?");
			if(result == true){
			this.books.splice(index,1)
			}
		},
	},
	computed:{
		allPrice(){
			let result = 0;
			for(let i in this.books){
				result += this.books[i].price * this.books[i].num;
			}
			return result;
			//第二种
			//let result = 0;
			//for(let item of this.books){
			//	  result += item.price * item.num;
			//}
			//return result;
			//第三种
			//reurn this.books.reduce(function(pre,book){
			//	  return pre + book.price * book.count
			//},0)
		}
	},
	filters:{
		showPrice(price){ return '¥' + price.toFixed(2) }
	},
})

效果如下图:
在这里插入图片描述
删除第一项(书籍名称为《算法导论》的一行),效果如下图:
在这里插入图片描述
全部删除的时候,执行v-else 的语句,效果如下图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值