文章目录
# Vue
引入vue.js(这里是文件夹里有vue.js)
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
也可以使用cdn的方式引入,将src中改为相应链接即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
}
})
</script>
</body>
</html>
1. Vue基础语法
1.1 模板语法
1.1.1 插值
-
文本插值
在实例中定义的data的属性message,使用{{message}}进行文本插值。
使用v-once指令插值使插值内容显示后不再修改。
-
HTML插值
使用v-html指令将数据解释成html代码。
<p>Using v-html directive: <span v-html="rawHtml"></span></p> rawHtml:'<span style="color:red">this should be red</span>'
上述将rawHtml属性值作为html元素插入span标签的子节点中。
-
属性插值
使用v-bind绑定属性
<button v-bind:disabled="isButtonDisabled" >Button</button>
使用v-bind动态绑定属性class和style
<div v-bind:class="cor">test...</div> cor:'blue' <style type="text/css"> .red{ color: red; } .blue{ color:blue; font-size: 100px; } </style>
-
插值中使用javascrip表达式
<p>{{number+1}}</p> <p>{{ ok ? 'YES' : 'NO' }}</p> <p>{{ message.split('').reverse().join('') }}</p> <!--反序排列-->
1.1.2 指令
指令就是带有v-前缀的特殊属性。指令属性的值预期是单一JavaScript表达式(出来v-for)。指令的职责是当其表达式的值改变的时候相应地将某些行为应用到DOM上。
-
参数
<a v-bind:href="url">...</a>
这里href是参数,告知v-bind指令将该元素的href属性与表达式url的值绑定。
-
动态参数
<a v-bind:[attributename]="url">...</a>
这里的attributename会作为一个JavaScript表达式进行动态求值,求得的值作为最终的参数来使用。如果其值为href,等价于v-bind:href。
-
修饰符
修饰符是以半角句号“.”指明的特殊后缀,用于指出一个指令应该以特殊方式进行绑定。
<form v-on:submit.prevent="Onsubmit">...</form>
.prevent修饰符告诉v-on指令对于触发的事件调用event.preventDefault()。
1.1.3 过滤器
-
定义过滤器
-
全局过滤器
Vue.filter('过滤器名称',function(value1[,value2,...]){ //逻辑代码 })
-
局部过滤器
new Vue({ filters:{ '过滤器名称':function(value1[,value2,...]){ //逻辑代码 } } })
-
-
过滤器使用的地方
Vue.js允许自定义过滤器,可用于一些常见的文本格式化。过滤器可以用在两种地方:双花括号插值和v-bind表达式。过滤器应该被贴在JavaScript表达式尾部,由“管道”符号指示,格式代码如下:
<!--在双花括号中--> <div>{{数据属性名称|过滤器名称}}</div> <div>{{数据属性名称|过滤器名称(参数值)}}</div> <!--在v-bind中--> <div v-bind:id="数据属性名称|过滤器名称"></div> <div v-bind:id="数据属性名称|过滤器名称(参数值)"></div>
-
实例
局部过滤器实例(在价格前面加上人民币符号’¥’)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="vue.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="app"> <p>计算机价格:{{price|addPriceIcon}}</p> </div> <script> var vm=new Vue({ el:"#app", data:{ price:200 }, filters:{ //处理函数 addPriceIcon(value){ console.log(value)//200 return '¥'+value; } } }) </script> </body> </html>
传递多个参数的过滤器实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<span>{{value1|multiple(value2,value3)}}</span>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
msg:'hello',
value1:10,
value2:20,
value3:30
},
filters:{
//处理函数
'multiple':function(value1,value2,value3){
return value1*value2*value3
}
}
})
</script>
</body>
</html>
全局过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<h3>{{msg|addNamePrefix}}</h3>
</div>
<script>
Vue.filter("addNamePrefix",(value)=>{
return 'my name is '+value
})
var vm=new Vue({
el:"#app",
data:{
msg:'hello'
}
})
</script>
</body>
</html>
1.2 实例及选项
vue通过构造函数来实例化一个Vue对象:var vm=new Vue({}).在实例化时,我们会传入一些选项对象,包含数据选项、属性选项、方法选项、生命周期钩子等常用选项。
1.2.1 数据选项
data是vue实例的数据对象。vue实例创建之后,在控制台输入vm.$data即可访问原始数据对象。
以_或 $ 开头的属性不会被Vue实例代理,因为它们可能与Vue内置的属性或方法冲突。可以使用“vm.$data. _ property”的方式访问这些属性。
1.2.2 属性选项
Vue为组件开发提供了属性(props)选项。可以使用它为组件注册动态属性,来处理业务之间的差异性,使代码可以在相似的应用场景复用。
props选项可以是数组或者对象类型,用于接收从父组件传递过来的参数,并允许为其赋默认值、类型检查和规则校验等。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<message content='hello world'></message>
</div>
<script type="text/javascript">
var Message=Vue.extend({
props:['content'],
data:function(){
return{
a:'it worked'
}},
template:'<h1>{{content}}{{a}}</h1>'
})
Vue.component('message',Message)
var vm=new Vue({
el:"#app",
})
</script>
</body>
</html>
1.2.3 方法选项
可以通过选项属性methos对象来定义方法,并且使用v-on指令来监听DOM事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<button v-on:click="test">点我</button>
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data:{
},
methods:{
test:function(){
console.log(new Date().toLocaleTimeString());
}
}
})
</script>
</body>
</html>
1.2.4 计算属性
在项目开发中,我们展示的数据往往需要处理。Vue提供了计算属性方法,计算属性是当其依赖属性的值发生变化时,这个属性的值会自动更新。
在{{}}中进行一些计算再展示数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<th>学科</th>
<th>分数</th>
</thead>
<tbody>
<tr>
<td>数学</td>
<td><input type="text" v-model="Math"></td>
</tr>
<tr>
<td>语文</td>
<td><input type="text" v-model="Chinese"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model="English"></td>
</tr>
<tr>
<td>总分</td>
<td>{{Math+Chinese+English}}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{(Math+Chinese+English)/3}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data:{
Math:95,
Chinese:96,
English:90
}
})
</script>
</body>
</html>
通过{{}}运算解决问题代码结构不清晰。Vue提供了更好的解决方案——计算属性。computed通常计算相关的函数返回最后计算出来的值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<th>学科</th>
<th>分数</th>
</thead>
<tbody>
<tr>
<td>数学</td>
<td><input type="text" v-model="Math"></td>
</tr>
<tr>
<td>语文</td>
<td><input type="text" v-model="Chinese"></td>
</tr>
<tr>
<td>英语</td>
<td><input type="text" v-model="English"></td>
</tr>
<tr>
<td>总分</td>
<td>{{sum}}</td>
</tr>
<tr>
<td>平均分</td>
<td>{{avg}}</td>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
data:{
Math:95,
Chinese:96,
English:90
},
computed:{
sum:function(){
//this指向vm实例
return this.Math+this.Chinese+this.English;
},
avg:function(){
return this.sum/3;
}
}
})
</script>
</body>
</html>
上述实例只提供了getter读取值的方法,除getter外还可以设置计算数学的setter。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<script type="text/javascript">
var vm=new Vue({
data:{
a:1
},
computed:{
aDouble:function(){
return this.a*2;
},
aPlus:{
get:function(){
return this.a+1;
},
set:function(v){
this.a=v-1;
}
}
}
})
console.log(vm.aPlus);//2
vm.aPlus=5;
console.log(vm.a);//4
console.log(vm.aDouble);//8
</script>
</body>
</html>
1.2.5 表单控件
-
基础用法
可以使用v-model指令在表单< input >、< testarea >、及< select >元素上创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素。v-model本质上是语法糖,负责监听用户的输入事件以便更新数据,并对一些极端场景做一些特殊处理。
-
单行文本可在input元素中使用v-model实现双向数据绑定,代码如下:
<input v-model="message" placeholder="请输入信息......"> <p>Message is:{{message}}</p>
-
多行文本可在testarea元素中使用v-model实现双向数据绑定,代码如下:
<span>Multiline message is:</span> <p style="white-space: pre;">{{message}}</p> <br> <textarea v-model="message" placeholder="add multiple lines"></textarea>
注:在文本区域插值(< textarea >< /textarea >)并不会生效,应用v-model代替。
-
单个复选框,绑定到布尔值,代码如下:
<input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{checked}}</label>
-
多个复选框绑定到同一数组,代码如下:
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="jack">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="jack">Mike</label> <br> <span>Checkednames:{{checkedNames}}</span> var vm=new Vue({ el:"#app", data:{ checkedNames:[] } })
-
-
单选按钮的双向数据绑定,代码如下:
<input type="radio" id="runoob" value="Runoob" v-model="picked"> <label for="runoob">Runoob</label> <br> <input type="radio" id="google" value="Google" v-model="picked"> <label for="google">Google</label> <br> <span>选中值为:{{picked}}</span>
-
选择列表,下拉列表的双向数据绑定。
单选时:
<select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>选中值为:{{selected}}</span>
如果v-model表达式的初始值未能匹配任何选项,则< select >元素将被渲染为“未选中”状态。
多选列表:
<select v-model="selected" multiple style="width: 50px;"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>选中值为:{{selected}}</span>
动态选项,用v-for渲染。
<select v-model="selected" > <option v-for="option in options" v-bind:value="option.value"> {{option.text}} </option> </select> <br> <span>选中值为:{{selected}}</span> data:{ selected:'A', options:[ {text:'one',value:'A'}, {text:'TWO',value:'B'}, {text:'THREE',value:'C'}, ] }
-
绑定value
对于单选按钮、勾选框及选择列表选项,v-model绑定的value通常是静态字符串。
<!--当选中时,picked为字符串a--> <input type="radio" v-model="picked" value="a"> <!--当选中时,toggle为true或false--> <input type="checkbox" v-model="toggle"> <!--当选中时,selected为字符串abc--> <select v-model="selected"> <option value="abc">ABC</option> </select>
实现复选框功能。有时我们想绑定value到Vue实例的一个动态属性上,这时可以用v-bind实现,并且这个属性可以不是字符串。
<input type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value="b"> {{toggle}} data:{ toggle:'', a:'ac', b:'bd' } //当选中时输出字符串ac,当没有选中时输出字符串bd
单选按钮
<input type="radio" v-model="toggle" v-bind:value="a"> data:{ toggle:'', a:'ac' } //选中时在页面控制台输入vm.toggle和vm.a的值相等。
选列表设置
<select v-model="selected"> <!--内联对象字面量--> <option v-bind:value="{number:123}">123</option> </select> data:{ selected:'' } //当选中时在页面控制台输入typepf vm.selected输出’object‘,如果输入vm.selected.number则输出123
-
修饰符
-
.lazy
在默认情况下,v-model每次在input事件触发后将输入框的值和数据进行同步。此时可以添加.lazy修饰符,从而转为在change事件之后进行同步。
<!--在change时而非input时更新--> <input v-model.lazy="msg"> {{msg}}
-
.number
如果想自动将用户的输入值转为数值类型,可以给v-model添加.number修饰符。
<input v-model.number="age" type="number">
通常这很有用,因为即使在“type=number”时,HTML输入元素的值也总会返回字符串。如果这个值无法被parseFloat()解析,则会返回原始的值。
-
.trim
如果要自动过滤用户输入的首尾空白字符,可以给v-model添加.trim修饰符。
<input v-model.trim="msg">
-
1.2.6 生命周期
Vue的整个生命周期中有许多钩子函数,这就给了用户在不同阶段添加自己代码的机会。
- beforeCreate:在实例初始化之后,数据观测和event/watcher事件配置之前被调用。
- Created:实例已经创建完成之后被调用。在这一步,实例已完成下列配置:数据监测、属性和方法的运算以及watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。
- beforeMount:在挂载开始之前被调用,相关的render函数首次被调用。
- Mounted:el被新创建的vm.$el替换,并挂载到实例上调用该钩子。
- beforeUpdate:数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。可以在这个钩子中进一步更改状态,这不会触发附加的重新渲染过程。
- Updated:由于数据更新导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件DOM已经更新,所以现在可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不会被调用。
- beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
- Destroyed:Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会被解绑定,所有的事件监听器都会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不会被调用。
1.3 模板渲染
在我们获取后台数据之后,会按照一定的规则加载到前端写好的模板中,并显示在浏览器中,这个过程称为渲染。
1.3.1 条件渲染
v-if、v-else-if、v-else
v-if、v-else-if、v-else这三个指令后面跟的是表达式。Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素/组件。
<!--if、else指令-->
<p v-if="status==1">当status为1时,显示该行</p>
<p v-else-if="status==2">当status为2时,显示该行</p>
<p v-else-if="status==3">当status为3时,显示该行</p>
<p v-else>否则显示该行</p>
我们需要注意多个v-if、v-else-if、v-else之间需要紧挨着,如果在它们之间插入一行新代码,编译器会报错。
v-show和v-if效果等同。
二者之间的区别:
- 控制显示的方法不同:v-show实际通过修改DOM元素的display属性来实现节点的显示和隐藏,而v-if通过添加/删除DOM节点来实现。
- 编译条件:v-if是惰性的,如果初始条件为假,则什么都不做,此时不会去渲染该元素,只有在条件第一次变为真时才开始局部编译;v-show则不管初始条件是什么,都被编译然后被缓存,而且将DOM元素保留,只是简单地基于CSS进行切换,即v-if条件为true时才会被加载渲染,为false时不加载。v-show不管是true还是false都会被加载渲染。
- 性能消耗:v-if有更高的切换消耗,v-show有更高的初始渲染消耗。
- 使用场景:如果需要非常频繁的切换,则使用v-show为好。如果在运行时条件很少改变,只需要一次显示或隐藏,则使用v-if较好。
key:
Vue会尽可能的渲染元素,通常会复用已有元素而不是从头开始渲染。
<p v-if="ok">
<label>Username</label>
<input placeholder="Enter your username">
</p>
<p v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</p>
<button @click="ok=!ok">切换</button>
页面中输入信息后单击“切换”按钮,此时文本框里的没有清空。
Vue提供了一种方式来声明“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的key属性。
<p v-if="ok">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</p>
<p v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</p>
<button @click="ok=!ok">切换</button>
1.3.2 列表渲染
- v-for循环用于数组。定义一个数组类型的数据items,用v-for将
- 标签循环渲染。
<ul id="app">
<li v-for="item in items">
{{item.name}}
</li>
</ul>
data:{
items:[
{name:'beixi'},
{name:'jzj'}
]
}
还支持一个可选的第二个参数为当前的索引,索引从0开始。分隔符in前的语句使用括号,第二项就是items当前项的索引。可以用of代替in作为分隔符。
<li v-for="(item,index) in items">
{{index}}------{{item.name}}
</li>
-
v-for用于对象
v-for通过一个对象的属性来遍历输出结果。
<ul id="app"> <li v-for="value of Object"> {{value}} </li> </ul> data:{ Object:{ name:'luccy', gender:'男', age:30 } }
遍历属性时有两个可选参数,分别是键名和索引。
<li v-for="(value,key,index) of Object"> {{index}}------{{key}}: {{value}} </li>
-
v-for用于整数
<li v-for="n in 10"> {{n}} </li>
1.4 事件绑定
Vue提供了v-on指令监听DOM事件,在事件绑定上,类似原生JavaScript的onclick事件写法,也是在html上进行监听。
1.4.1 基本用法
语法规则:
v-on:事件名.修饰符=方法名()|方法名|简单的JS表法式
简写:@事件名.修饰符=方法名()|方法名|简单的JS表法式
-
直接使用
直接在标签中书写js方法
单击次数{{count}} <button @click="count++">单击+1</button>
-
调用methods方法
通过v-on绑定实例选项属性methods中的方法作为事件的处理器。
<button @click="say">单击</button> data:{ msg:"say hello" }, methods:{ say:function(){ alert(this.msg) } }
单击button按钮,即可触发say函数,弹出alert框‘say hello’.
-
方法传参,方法在直接调用时在方法内传入参数。
<button @click="say('你好')">单击</button> methods:{ say:function(val){ alert(val) } }
-
-
传入事件对象
<button data-id="123" @click="say($event)">单击</button> methods:{ say:function(e){ console.log(e); //e.srcElement,DOM结点 e.srcElement.style.background='red'; console.log(e.srcElement.dataset.aid);//获取自定义属性的值 } }
1.4.2 修饰符
Vue为指令v-on提供了多个修饰符,方便我们处理一些DOM事件的细节,Vue主要的修饰符如下:
-
.top:阻止事件继续传播,即阻止它的捕获和冒泡过程
@click.stop='handle()'//只要在事件后面加上.stop就可以阻止事件冒泡。
<div style="background-color: aqua;width: 100px;height: 100px;" v-on:click="outer"> 外部单击 <div style="background-color: red;width: 50px;height: 50px;" v-on:click.stop="inner"> 内部单击 </div> </div> methods:{ outer:function(){ console.log("外部单击"); }, inner:function(){ console.log("内部单击"); } }
点击“内部单击”按钮阻止了冒泡过程,即只执行了inner这个方法,如果不加.stop则先执行inner方法然后执行outer方法,即通过了冒泡这个过程。
-
.prevent:阻止默认事件
@click.prevent='handle()'//只要在事件后面加上.prevent就可以阻止默认事件
如下阻止了a标签的默认刷新:
<a href='' v-on:click.prevent>单击</a>
-
.capture:添加事件监听器时使用事件捕获模式,即在捕获模式下触发
@click.capture='handle()'
如在下列实例中,单击最里层的“单击6”时,outer方法会先执行,因为outer方法在捕获模式下执行,先于冒泡事件。按下列顺序执行:outer→set→inner,因为后两个还是冒泡模式下触发的事件。
<div v-on:click.capture="outer"> 外部单击5 <div v-on:click="inner"> 内部单击5 <div v-on:click="set"> 单击6 </div> </div> </div>
-
.self:当前元素自身是触发处理函数时才会触发函数
原理是根据event.target确定是否为当前元素本身,以此来决定是否触发事件/函数。
如下实例,如果单击“内部单击”按钮,冒泡不会执行outer方法,因为event.target指的是内部单击的DOM元素,而不是外部单击的,所以不会触发自己的单击事件。
<div v-on:click.self="outer"> 外部单击 <div v-on:click="inner"> 内部单击 </div> </div>
-
.once:只触发一次
<div v-on:click.once="outer"> 单击once </div>
-
键盘事件
-
方式一
@keydown=‘show($event)’
<input type="text" @keydown='show($event)'/> methods:{ show:function(ev){ console.log(ev.keyCode); if(ev.keyCode==13){ alert('你按了回车键') } } }
-
方式二
<input type="text" @keyup.enter="show()"> <input type="text" @keydown.up="show()"> <input type="text" @keydown.down="show()"> <input type="text" @keydown.left="show()"> <input type="text" @keydown.right="show()">
-
1.5 基础demo案例
使用npm下载bookstrap文件:npm install bootstrap@3
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h2>图书管理系统</h2>
</div>
<div class="panel-body form-inline">
<label for="">id:<input type="text" class="form-control" v-model="id"></label>
<label for="">图书名称:<input type="text" class="form-control" v-model="name"></label>
<input type="button" value="添加" class="btn btn-primary" @click="add">
</div>
</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>id</th>
<th>图书名称</th>
<th>添加时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in arr":key="item.id">
<td v-text="item.id"></td>
<td v-text="item.name"></td>
<td v-text="item.time"></td>
<td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
<script>
var vm=new Vue({
el:"#app",
data:{
arr:[
{'id':1,'name':'三国演义','time':new Date()},
{'id':2,'name':'红楼梦','time':new Date()},
{'id':3,'name':'水浒传','time':new Date()},
{'id':4,'name':'西游记','time':new Date()},
],//创建一些初始数据和格式
id:'',
name:''
},
methods:{
add(){
this.arr.push({'id':this.id,'name':this.name,'time':new Date()});
this.id=this.name='';
},
del(id){
var index=this.arr.findIndex(item=>{
if(this.id==id){
return true;
}
})
//findIndex方法查找索引,实现列表的删除功能
this.arr.splice(index,1)
}
}
})
</script>
</body>
</html>
效果如图: