1.Vue.js概述
Vue.js是一款用于构件用户界面的渐进式框架,能帮助减少不必要的DOM操作(DOM操作开销比较大)。
- 渐进式框架:声明式渲染->组件系统->客户端路由->集中式状态管理->项目构件。
- dom操作:由于HTML文档被浏览器解析后就是一棵DOM树,改变HTML的结构,需要通过js操作DOM。
2.Vue.js使用
2.1 Vue的基本使用步骤
- 1.需要提供标签用于填充数据
- 2.引入vue.js库文件--点击此处下载
2.2 实例
<body>
<div id="app">
<div>{{msg+'-----'}}</div>
</div>
//从官网下载的vue.js文件,将其放到项目目录下的js目录下
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
// el-元素的挂载位置(值可以是CSS选择器或DOM元素)
el: '#app',
//模型数据(值是一个对象)
data: {
msg: 'Hello World'
}
});
</script>
</body>
2.3 Vue代码运行原理分析
对于<div>{{msg+'-----'}}</div>这段代码,浏览器并不知道如何去解析。之所以能正常显示在浏览器页面上,是由于Vue框架将Vue代码解析成了原生的js代码。
3.Vue模板语法
3.1 指令
Vue中的指令的格式以v-开始。
3.2 v-cloak指令解决闪动问题
前面说到,Vue框架会将代码解析成原生的js代码,之后由浏览器渲染结果,所以用户在刷新页面的时候,可能能看到后面的代码。使用v-cloak可避免这种显示效果。
根据官网上给出的用法:v-cloak指令,在Head中指定样式:
<style type="text/css">
[v-cloak]{
display: none;
}
</style>
然后即可在div中添加v-cloak指令:
<div id="app" v-cloak>
{{msg+'------'}}
</div>
能够实现这种效果的本质在于,先通过样式隐藏内容,然后在内存中进行值的替换,替换好之后再显示最终的结果。
3.3 数据绑定指令之v-text
v-text指令用于插入纯文本,例如:<span v-text="msg"></span>可与前面的{{msg+'------'}}显示同样的效果,并且不用添加v-cloak解决闪动问题,所以更推荐使用v-text绑定数据。
3.4 数据绑定指令之v-html
v-html指令用于插入HTML片段,例如在data中增加
msg1:'<br>123<br><h2>测试内容</h2>'
使用
<span v-html="msg1"></span>
插入html片段。
3.5 数据绑定指令之v-pre
v-pre指令用于显示原始信息,跳过Vue的解析阶段。例如:
<span v-pre>{{这句话不会被编译}}</span>
显示效果:
3.6.数据相应式指令v-once
响应式指的是数据变化而导致页面内容的变化。也就是打开浏览器后,使用F12进入控制台,可以使用vm.msg=123修改内容。但是使用:
<div id="app" v-once>
<p>{{msg+'------'}}</p>
<span v-text="msg"></span>
<span v-html="msg1"></span>
<span v-pre>{{这句话不会被编译}}</span>
</div>
v-once指令声明代码块只编译一次,不具有响应式之后,就不能通过控制台修改页面内容了。
3.7 数据的双向绑定v-model
数据的双向绑定指的是Model与View的内容实现同步更新。例如:
<input type="text" v-model='msg'>
即可实现这种效果:
注意:在View中更改msg的值,Model中的msg也会同样修改,同时通过Console修改Model中的值,View中也会有相应的显示。
3.8 事件的绑定v-on
举例:
<p>{{num}}</p>
<button v-on:click="num++">+1</button>
<button v-on:click="num--">-1</button>
num在data中的初值为零:
不过num++,num--这样的函数一般会将其写在单独的函数中,提高可读性:
<button v-on:click="add">+1</button>
<button @click="minus">-1</button>
可以用@替代v-on:。
methods:{
add:function () {
this.num++
},
minus:function(){
this.num--
}
}
3.9 事件参数的传递
在前面的例子中,我们将num++,num--这样的操作抽取到函数中,那么对于函数中需要传递参数的情况:
<button v-on:click="add(num,$event)">+1</button>
<button @click="minus">-1</button>
methods:{
add:function (num,event) {
if(num<10){
++this.num
}
console.log(event.target.innerHTML)
console.log("还有"+(10-num)+"次机会")
},
minus:function(event){
console.log(event.target.tagName)
this.num--
}
}
效果:
tagName为BUTTON,innerHTML为+1;
结论:
- 1.如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数。
- 2.如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event。
3.10 v.stop阻止冒泡
假设将代码改成这样:
<div id="app" v-on:click="add(num,$event)">
<p>{{num}}</p>
<button>+1</button>
<button @click="minus">-1</button>
</div>
可以发现,点击+1会进行+1操作,但是点击-1数字却不会变化。这是由于在执行button中的操作时,同样会执行div中的操作,一减一加,所以看起来数字不发生改变。
所以需要在minus中阻止冒泡:
minus:function(event){
event.stopPropagation();
console.log(event.target.tagName)
this.num--
}
这种方式也可以简化为:
<button v-on:click.stop="minus">-1</button>
3.11 v.prevent阻止默认操作
存在如下a标签:
<a href="http://www.zhihu.com" target="_blank" v-on:click="another($event)">知乎</a>
我们知道,点击“知乎”即可默认跳转到知乎的首页,并且绑定了another函数。但是在another中加上:
event.preventDefault();
即可阻止这种默认行为。同时这种方式也可以简化为:
v-on:click.prevent
3.12 v.self只有自身可以触发事件
即排除冒泡所触发的情形,对于这种情况:
<div id="app" v-on:click.self="add(num,$event)">
<button v-on:click="add(num,$event)">+1</button>
<button v-on:click="minus">-1</button>
</div>
只有在点击“+1”时,才会调用add()方法,由于点击“-1”而冒泡调用的add()方法不会执行。
3.13 修饰符之间的串联
当然,修饰符之间可以串联,例如:v.on:click:prevent.self会阻止自身以及冒泡调用方法。
3.14 v.enter/v.delete 按键修饰符
对于用户提交表单的情况,我们需要实现用户点击enter也可以进行提交,这时候就需要用到v-on:keyup指令。例如:
<body>
<div id="app">
<form action="">
<div>
用户名:
<input v-model="username" type="text" />
</div>
<div>
密码:
<input v-model="password" v-on:keyup.enter="handel" type="text" />
</div>
<div>
<input type="button" v-on:click="handel" value="提交" />
</div>
</form>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
username: '',
password: ''
},
methods: {
handel: function(username) {
console.log(this.username, this.password);
}
}
});
</script>
</body>
即可实现,键盘输入enter也可提交表单。注意:v-on:keyup后需要加.enter,否则按任何键都可触发提交操作。v.delete同理。
3.15 自定义按键修饰符
首先我们知道,键盘上的每一个按键都有一个唯一的数字标识,称之为keyCode。可使用:
<div>
<input type="text" v-on:keyup="number" />
</div>
number: function(event) {
console.log(event.keyCode);
}
查看对应的值。
知道键盘上每个按键对应的数值后,可以使用:
v-on:keyup.65来定义a键的操作,使用v-on:keyup.32来定义空格键的操作。
根据官网提示,可以通过配置别名来给对应ASCII码的键盘数字取别名。例如:
Vue.config.keyCodes.show = 65;
3.16 v-bind属性绑定
我们知道,在<a>标签中可以将标签名与链接相绑定,但是需要使用某个变量代替url时:
<a href="url" target="_blank">知乎</a>
data: {
url: 'http://www.zhihu.com'
},
这时候之间点击知乎是会报错的,这时候需要用到v-bind指令:
<a v-bind:href="url" target="_blank">知乎</a>
或者可以简写为:
<a :href="url" target="_blank">知乎</a>
那么其实前面用到的双向数据绑定v-model,本质上也用到了v-bind。例如:
<input type="text" v-bind:value="url" v-on:input="write" />
write: function(event) {
this.url = event.target.value;
}
也可以实现v-model的相同效果。或者,可以直接将其简写为:
v-on:input="url=$event.target.value"
3.17 v-bind的class样式处理
可以使用v-bind:class动态的切换class:
<style>
.boder {
border: 4px solid red;
width: 80px;
height: 100px;
}
.background {
background: blue;
}
.font {
color: white;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50px;
}
</style>
<body>
<div id="app">
<div v-bind:class="{active:isActive,backgroundColor:isBack}"></div>
<button v-on:click="change">显示/隐藏边框</button>
<button v-on:click="change1">显示/隐藏底色</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
isActive: 'true',
isBack: 'true'
},
methods: {
change: function() {
this.isActive = !this.isActive;
},
change1: function() {
this.isBack = !this.isBack;
}
}
});
</script>
</body>
</html>
v-class的数组绑定:
<body>
<div id="app">
<div v-bind:class="[boderClass,backgroundClass]"></div>
<button v-on:click="change">隐藏</button>
<button v-on:click="return1">显示</button>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
boderClass: 'boder',
backgroundClass: 'background'
},
methods: {
change: function() {
(this.boderClass = ''), (this.backgroundClass = '');
},
return1: function() {
(this.boderClass = 'boder'), (this.backgroundClass = 'background');
}
}
});
</script>
</body>
显示效果:
其他注意事项:
- 1.对象绑定和数组绑定可以结合使用,例如:
<div v-bind:class="[boderClass,backgroundClass,{font:isWhite}]">
- 2.class绑定的值可以简化处理,例如:
arrayClass: ['circle', 'background', 'boder']
一个属性名可以绑定多个属性。
- 3.默认的class会被保留。例如:
<div class="font" v-bind:class="arrayClass">测试用文字</div>
font属性不会被覆盖,而是会跟arrayClass中的属性一同显示。
3.18 style样式处理(内联样式处理)
在前面我们介绍了通过v-bind:class=''控制对象的样式,那么同样可以使用v-bind:style=''修改样式。举例:
<div v-bind:style="{border:borderStyle,background:backgroundStyle,width:widthStyle,height:heightStyle}"></div>
data: {
borderStyle: '2px solid red',
backgroundStyle: 'blue',
widthStyle: '80px',
heightStyle: '100px',
circlestyle: 'circle'
},
上面这种书写方式可以简写为:
<div v-bind:style="circlestyle"></div>
circlestyle: {
width: '100px',
height: '100px',
border: '2px solid blue',
background: 'red'
}
同样v-bind:style中也可以使用数组例如:
<div v-bind:style="[circlestyle,circlestyle1]"></div>
注意:如果circlestyle中的属性与circlestyle1中的属性有重复的,那么后者会覆盖前者,不重复的则会相互补充。
4.分支循环结构
分支结构包括:
- v-if
- v-else
- v-else-if
- v-show(控制元素是否显示)
4.1 分支
首先我们知道,在methods中可以使用if/else实现相应的逻辑:
methods: {
calculate: function() {
if (this.score > 90) {
this.result = '优秀';
} else {
this.result = '良好';
}
}
}
那么也可以采用这种方式:
<div v-if="100>=score&&score>=90">优秀</div>
<div v-else-if="score<90&&score>=80">良好</div>
4.2 循环
对于for循环,使用v-for指令,举例说明:
data: {
weeks: ['monday','tuesday','wednesday','thrusday','friday','saturday','sunday']
},
遍历:
<ul>
<li v-for="week in weeks">{{week}}</li>
</ul>
注意:
- 在这里week是别名,用于代表数组中的一个示例。
- in是关键字
如果需要索引的话,可以这样使用:
<li :key='index' v-for="(week,index) in weeks">{{week}}-星期{{index+1}}</li>
index也是关键字。
4.3 v-for循环遍历对象
例如: data中存在这样一个对象:
aMan: {
username: 'zhangsan',
password: 'password',
timestamp: '2020-02-20'
}
通过循环将对象中的属性逐一显示出来:
<div v-for="(v,k,i) in aMan">{{v+'---'+k+'---'+i}}</div>
v代表value, k代表key,i代表index。
5.Vue常用特性
概览: 1.表单操作 2.自定义指令 3.计算属性 4.过滤器 5.侦听器 6.生命周期
5.1 基于Vue的表单操作
- input 单行文本
- textarea 多行文本
- select 下拉多选
- radio 单选框
- checkbox 多选框
示例:
- 1.input单行文本
<input type="text" v-model="uname" />
- 2.select 下拉多选
<div>
<span>掌握语言:</span>
<select v-model="langunage" multiple="true">
<option value="1">Java</option>
<option value="2">c</option>
<option value="3">c++</option>
<option value="4">python</option>
</select>
</div>
- 3.radio单选框
<div>
<span>性别:</span>
<!-- label的name设置为一致,则只能选中一个 -->
<input
type="radio"
name="sex"
id="male"
value="1"
v-model="gender"
/>
<label for="male">男</label>
<input
type="radio"
name="sex"
id="female"
value="2"
v-model="gender"
/>
<label for="female">女</label>
</div>
- 4.checkbox多选框
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model="hobby" />
<label for="ball">篮球</label>
<input type="checkbox" id="sing" value="2" v-model="hobby" />
<label for="sing">唱</label>
<input type="checkbox" id="jump" value="3" v-model="hobby" />
<label for="jump">跳</label>
<input type="checkbox" id="rap" value="4" v-model="hobby" />
<label for="rap">rap</label>
</div>
- 5.textarea多行文本
<div>
<span>自我介绍:</span>
<textarea v-model="resume" cols="30" rows="2"></textarea>
</div>
5.2 表单域修饰符
- number:转化为数值 示例:
<input type="text" v-model.number="len" size="2" disabled="disabled" />
- trim:去掉开始和结尾的空格
<input type="text" v-model.trim="message" size="10" />
- lazy:将input事件切换为change事件
<div v-text="message"></div>
<input type="text" v-model.lazy="message" />
改变input中内容不会马上引起div显示内容的变化,当输入框失去焦点时,才会引起change的变化。
5.3 自定义指令
官网中给出的例子:
// Vue.directive-Vue指令中的API,定义指令函数
// 函数的第一各参数为指令的名称,第二个参数实现对应名称的逻辑
Vue.directive('focus', {
inserted: function(el) {
// el表示指令所绑定的元素
el.focus();
}
});
实现效果在于:加上v-focus标识后,每次打开页面时,焦点自动对应到选定的区域。
5.4 带参数的自定义指令
根据官网的描述,示例:
Vue.directive('color', {
bind: function(el, binding) {
// 将元素的背景色指定为所绑定的对象属性中的color
el.style.backgroundColor = binding.value.color;
}
});
在input中指定参数:
<input type="text" v-color="msg" />
msg内容:
msg: {
color: 'red'
},
5.5 局部指令
可通过在new Vue()中添加directives的方式注册局部指令:
directives: {
color: {
bind: function(el, binding) {
// 将元素的背景色指定为所绑定的对象属性中的color
el.style.backgroundColor = binding.value.color;
}
}
}
与全局指令不同,局部指令只能在本组件中使用。
5.6 计算属性
使用计算属性可以使得模板内容更加简洁。
computed: {
reverseMessage: function() {
return this.message
.split('')
.reverse()
.join('');
}
}
可以通过直接调用属性名获取属性:
<span v-text="reverseMessage"></span>
计算属性与方法的区别:
- 1.计算属性是基于他们的依赖进行缓存的。
- 2.函数每调用一次就会执行一次,不存在缓存。
5.7 侦听器
- 1.侦听器用于数据变化时执行异步或开销较大的操作。 举例,输入姓和名,自动拼接姓名:
watch: {
firstname: function(val) {
this.fullname = val + ' ' + this.lastname;
},
lastname: function(val) {
this.fullname = this.firstname + ' ' + val;
}
}
调用监听器的名称,获取监听器的属性:
<input type="text" v-model="fullname" size="5" />
效果:
实例:验证用户名是否存在
<div>
<span>名称:</span>
<input type="text" v-model.lazy="uname" />
<span>{{message}}</span>
</div>
methods: {
checkname: function(uname) {
//在此处调用接口,但是可以使用定时任务的方式模拟接口调用
//在setTimeout函数中的this指的是windows,所以需要在外面缓存this
var that = this;
setTimeout(function() {
if (uname == 'admin') {
that.message = '用户名已被使用,请选择其他用户名...';
} else {
that.message = '用户名可以被使用...';
}
}, 3000);
}
},
watch: {
uname: function(val) {
this.checkname(val);
this.message = '用户名正在核查...';
}
}
5.8 Vue过滤器
自定义过滤器:
Vue.filter('过滤器名称',function(value){
//过滤器业务逻辑
})
按照官网的提示定义一个过滤器:
Vue.filter('upper1', function (val) {
return val.charAt(0).toUpperCase() + val.slice(1);
});
调用过滤器:
<div>
{{msg|upper1}}
</div>
过滤器之间可以串联:
Vue.filter('lower', function (val) {
return val.charAt(0).toLowerCase() + val.slice(1);
});
val默认是需要处理的数据,既lower,调用方法:
<div>
{{msg|upper |lower}}
</div>
另一种调用方法:
Vue.filter('formate', function (val) {
return val.slice(1);
});
<div>
<a v-bind:href="url | formate" target="_blank">测试跳转</a>
</div>
带参数的过滤函数:
Vue.filter('add', function(val, formateType) {
if (formateType == 'yyyy-mm-dd') {
var formateDate = '';
formateDate +=
val.getFullYear() +
'-' +
(val.getMonth() + 1) +
'-' +
val.getDate();
}
return formateDate;
});
data: {
formateType: 'yyyy-mm-dd',
date: new Date()
},
显示效果:
5.9 生命周期
主要阶段:
- 1.挂载(初始化相关属性)
- 2.更新(元素或组件的变更操作)
- 3.销毁(销毁相关属性)
在Vue中用方法表示为以下几个阶段:
- beforeCreate:在实例初始化之后,数据观测和事件配置之前被调用。
- created:在实例创建完成后被立即调用。
- beforeMount:在挂载开始之前被调用。
- mounted:el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。
- beforeUpdate:数据更新时调用,发生在虚拟DOM打补丁之前。
- Updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。
- beforeDestroy:实例销毁之前调用。
- Destroy:实例销毁之后调用。
举例说明:
<div id="app">
<input type="text" v-model="msg" />
<div>
<button v-on:click="update">更新内容</button>
<button v-on:click="destroy">删除内容</button>
</div>
</div>
methods: {
update: function() {
this.msg = '456';
},
destroy: function() {
this.$destroy();
}
},
beforeCreate: function() {
console.log('beforeCreate');
},
created: function() {
console.log('created');
},
beforeMount: function() {
console.log('beforMount');
},
mounted: function() {
console.log('mounted');
},
beforeUpdate: function() {
console.log('beforeUpdate');
},
updated: function() {
console.log('updated');
},
beforeDestroy: function() {
console.log('beforeDestroy');
},
destroyed: function() {
console.log('destroyed');
}
定义两个按钮,分别表示更新和删除操作,可以看到每个阶段所调用的函数:
6.MVVM开发思想
MVVM是Model-View-ViewModel的缩写,Model实现模型控制,View控制页面展示,VM控制逻辑。
- DOM Listeners-DOM监听
- Data Bindings-数据绑定
7. script的type类型
type用以属性规定脚本的 MIME 类型。MIME 类型包括两部分:media type 和 subtype。对于 JavaScript,MIME 类型是 "text/javascript"。在HTML5中type类型默认为"text/javascript"。
一些常用的值:
- text/javascript (默认)
- text/ecmascript
- application/ecmascript
- application/javascript
- text/vbscript
8.项目实战-图书管理系统
数组相关API:
1.变异方法:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
2.替换数组(生成新的数组)
- filter()
- concat()
- slice
3.响应式更改数组数据:
Vue.set(vm.bookName, 2, '兄弟');
vm.$set(vm.page1, 1, '朝花夕拾');
//数组响应式变化
vm.$set(vm.user, 'age', 18);
4.常用特性应用场景
- 过滤器(格式化日期)
- 自定义指令(获取表单焦点)
- 计算属性(统计图书数量)
- 侦听器(验证图书存在性)
- 声明周期(图书数据处理)
5.代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style type="text/css">
[v-cloak] {
display: none;
}
.gridTable {
/* 设置外边距属性 */
margin: auto;
width: 500px;
text-align: center;
}
.gridTable table {
width: 100%;
/* 表格属性,表示两个表格的边框合并为一个,默认为separate表示不合并,collapse表示合并边框 */
border-collapse: collapse;
}
.gridTable th,
td {
padding: 10;
/* dashed表示虚线 */
border: 1px solid rgb(15, 15, 15);
height: 35px;
line-height: 35px;
}
.gridTable th {
/* background-color: rgb(93, 205, 240); */
}
.gridTable total {
/* height: 300px;
line-height: 300px;
background-color: orange;
border-top: 1px orange solid; */
}
.center {
text-align: center;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div class="gridTable">
<table>
<tr>
<th>
<div class="center">
<p v-html="message"></p>
</div>
</th>
</tr>
</table>
<table>
<tbody>
<tr>
<th>
<label for="id">编号:</label>
<input
type="text"
id="id"
size="3"
v-model="newBookId"
v-bind:disabled="noEditBookId"
v-focus
/>
</th>
<th>
<label for="name">书名:</label>
<input type="text" id="name" size="12" v-model="newBookName" />
</th>
<th>
<label for="name">姓名:</label>
<input
type="text"
id="userName"
size="8"
v-model="newUserName"
/>
</th>
<th>
<button v-on:click="addItem" v-bind:disabled="submitFlag">
提交
</button>
</th>
</tr>
</tbody>
</table>
<table>
<tr>
<th>
<div class="total">
<span>图书总数:</span>
<span>{{total}}</span>
</div>
</th>
</tr>
</table>
<table>
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>借出时间</th>
<th>借阅人</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<div>
<tr :key="index" v-for="(book,index) in books">
<td>{{book.id}}</td>
<td>{{book.name}}</td>
<td>{{book.lendTime |formate}}</td>
<td>{{book.userName}}</td>
<td>
<a href="" v-on:click.prevent="editBook(book.id)">编辑</a>
<span>|</span>
<a href="" v-on:click.prevent="deleteItem(book.id)">删除</a>
</td>
</tr>
</div>
</tbody>
</table>
</div>
<p class="center">
<span style="color: red;font-weight: bold;">{{tips}}</span>
</p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
Vue.filter('formate', function(val) {
return (
val.getFullYear() +
'-' +
val.getMonth() +
'-' +
val.getDate() +
' ' +
val.getHours() +
':' +
val.getMinutes() +
':' +
val.getSeconds()
);
});
Vue.directive('focus', {
inserted: function(parm) {
parm.focus();
}
});
var vm = new Vue({
el: '#app',
data: {
noEditBookId: false,
submitFlag: false,
newBookName: '',
newBookId: '',
newUserName: '',
message: '<h2>---欢迎使用图书管理系统V1.0---<h2>',
tips: '',
books: []
},
methods: {
addItem: function() {
if (this.noEditBookId == false) {
if (this.newBookName != '') {
var el = {};
el.name = this.newBookName;
el.id = this.newBookId;
el.lendTime = new Date();
el.userName = this.newUserName;
this.books.push(el);
} else {
this.tips = '书名不能为空!';
}
this.noEditBookId = false;
} else {
//根据当前的ID去更新数组中对应的数据
//使用数组的遍历,定位到需要修改的数组对象
// this.books.some(function(val){
// this(some是Vue中自带的函数,所以在这里的this指的是windows)
// });
this.books.some(parm => {
//在这里的this同样指的是windows
if (parm.id == this.newBookId) {
parm.name = this.newBookName;
parm.userName = this.newUserName;
return true;
}
});
this.noEditBookId = false;
}
// 修改或者增加书籍后,将输入框置空
(this.newBookId = ''),
(this.newBookName = ''),
(this.newUserName = '');
},
deleteItem: function(id) {
// // 根据id从数组中查找元素的索引
// var index = this.books.findIndex(function(parm) {
// return parm.id == id;
// });
// this.books.splice(index, 1);
// 方法2:使用数组的filter方法
this.books = this.books.filter(function(parm) {
return parm.id != id;
});
},
editBook: function(id) {
// 定位对应ID的Book
// 返回结果是包含对应ID的对象的数组
var readToEdit = this.books.filter(function(item) {
return item.id == id;
});
this.newBookId = readToEdit[0].id;
this.newBookName = readToEdit[0].name;
this.newUserName = readToEdit[0].userName;
this.noEditBookId = true;
}
},
computed: {
total: function() {
return this.books.length;
}
},
watch: {
newBookName: function(parm) {
var flag = this.books.some(function(item) {
return item.name == parm;
});
if (flag) {
this.submitFlag = true;
} else {
this.submitFlag = false;
}
}
},
mounted: function() {
// 该声明周期钩子函数被触发的时候,模板已经可以使用
// 此时一般用于获取后台数据,然后把数据填充到模板
var data = [
{
id: 1,
name: '许三观卖血记',
lendTime: new Date(),
userName: '张三'
},
{
id: 2,
name: '活着',
lendTime: new Date(),
userName: '李四'
},
{
id: 3,
name: '在细雨中呐喊',
lendTime: new Date(),
userName: '王五'
}
];
this.books = data;
}
});
</script>
</body>
</html>
页面:
9.参考文档
- 1.廖雪峰的官方文档-MVVM www.liaoxuefeng.com/wiki/102291…