文章目录
-
-
- 什么是vue
- Vue.js 是什么
- Vue.js 目的
- vue.js的核心思想
- Vue.js 优势
- 在vscode集成终端打开cmd
- vue用法
- vue基本写法
- mvc,mnp了解;mvvm精通
- 渲染方式
- vue数据驱动
- Vue渲染方式
- Vue.js指令
- 常见指令
- bootstrap
- watch监听/侦听
- 计算属性与侦听器的区别:
- 计算属性
- 计算属性VS方法
- 那么计算属性computed和方法有什么区别呢?
- bootstrap--watch案例
- 事件对象
- 事件修饰符
- 插入:promise
-
什么是vue
Vue.js是目前最流行的前端MVVM框架
作者:尤雨溪 ( 华人 ) 前Google员工
Vue.js 是什么
是一套构建用户界面的渐进式的自底向上增量开发MVVM框架,Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件
- 特点还有(优点–无论问到哪个框架,优势相同):轻量级、高效率、上手快、简单易学、文档全面而简洁
对于Vue是一套渐进式框架的理解
每个框架都会有自己的一些特点,会对开发者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。
可以在原有大系统的上面,把一两个组件改用vue实现,也可以整个用vue全家桶开发不会做职责之外的事
对于Vue自底向上增量开发的设计的理解
先写一个基础的页面,把基础的东西写好,再逐一去添加功能和效果,由简单到繁琐的这么一个过程。
Vue.js 目的
Vue.js的产生核心是为了解决如下三个问题
1.解决数据绑定问题。
2.Vue.js主要的目的是为了开发大型单页面应用。
3.支持组件化,也就是可以把页面封装成为若干个组件,把组件进行拼装,这样是让页面的复用性达到最高。
vue.js的核心思想
vue.js的核心思想包括:数据驱动和组件化
Vue.js 优势
简洁:HTML 模板 + Vue 实例 + JSON 数据
轻量:17kb,性能好
设计思想:视图与数据分离,无需操作DOM
社区:大量的中文资料和开源案例
在vscode集成终端打开cmd
设置完成后,关闭集成终端,然后重新打开就可以
vue用法
1.npm init -y 初始化
2.npm(cnpm淘宝镜像) install --save vue 下载vue
vue基本写法
- 1.引包
- 2.创建视图 ---- view
- 3创建vue实例====VM层
- 4创建模型数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 1.引包 -->
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<!-- vue的基本写法 -->
<!-- MVVM -->
<!--
M ---- model(模型====数据)
V ---- view (视图==== 用户可以看见的界面)
VM---- viewModel (视图模型 ==== 用来关联视图于模型中间的数据桥梁)
-->
<!-- 2.创建视图 -->
<div id="demodiv">
{
{text}}
</div>
<script>
// 3.创建vue实例====VM层
new Vue({
el:"#demodiv",
// 4创建模型数据
data:{
text:"你好么么哒"
}
})
</script>
</body>
</html>
xxxxxx
<script>
new Vue({
el:"#box"//跟标签;
data:{
text:"nihao"
}
})
</script>
mvc,mnp了解;mvvm精通
什么是框架
- 封装与业务无关的重复代码,形成框架
框架的优势
- 使用框架提升开发效率(虽然使用框架要遵循框架的语法但是使用框架可以大大提高对于业务逻辑的操作)
- 数据与视图分离
mvc框架
为什么要使用 MVC
- MVC 是一种专注业务逻辑,而非显示的设计思想
- MVC 中没有DOM操作
- 将数据独立出来,方便管理
- 业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
MVC - 表示软件可分成三部分
- 模型(Model)数据的储存和处理,再传递给视图层相应或者展示
- 视图(View)前端的数据展示
- 控制器(Controller)对数据的接收和触发事件的接收和传递
mvp
安卓的
-
MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Presenter表示器
-
MVP与MVC有着一个重大的区别:MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控View与Model之间的间接交互。
mvvm
Vue.js是一套构建用户界面的MVVM框架
MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器MVC的C层)
- 1、 M:模型层,主要负责业务数据相关;
- 2、 V:视图层,顾名思义,负责视图相关,细分下来就是html+css层;
- 3、 VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
小结
- 什么是框架:封装与业务逻辑无关的重复代码形成框架
- MVC 思想:一种将数据层与视图层进行分离的设计思想
- MVVM思想:意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之相同
- MVP思想:MVP的全称为Model-View-Presenter,Model提供数据,View负责显示,Presenter负责逻辑的处理
渲染方式
Vue.js 的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进 DOM,也就是将模板中的文本数据写进DOM中
- 命令式渲染 : 命令我们的程序去做什么,程序就会跟着你的命令去一步一步执行(例如原生的js)
- 声明式渲染 : 我们只需要告诉程序我们想要什么效果,其他的交给程序来做。vue.js是声明式
vue数据驱动
- 通过控制数据的变化来显示vue的数据驱动是视图的内容随着数据的改变而改变
- vue中data的数据可以是 字符串、数据、布尔、对象、数组
Vue渲染方式
{ {}}–表达式(模板语法,双大括号语法)
将双大括号中的数据替换成对应属性值进行响应式的展示
模板语法基本用法
模板语法中可以写入哪些内容
* 数字
* 字符串
* 计算
mvc设计思想,是为了使页面和数据进行很好的分离;如果在表达式中写入过多的逻辑代码,那么违背了最初的设计思想;也就使代码看起来很复杂,难以维护
表达式基本用法
表达式中可以写入哪些内容
* JSON数据
* 数组
* 结合刚开始使用原始方法完成的demo使用vue完成演示数组数据和JSON数据
注意
* 避免在双括号中使用复杂表达式
常见问题
* 如何区分插值中的内容是表达式还是普通文本?
答:Vue.js 会通过是否带引号区分两者
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="demodiv">
<h1>{
{"age"}}</h1>
<h1>{
{sex?"男":"女"}}</h1>
<h1>{
{love[2]}}</h1>
<h1>{
{dawei.b}}</h1>
<h1>{
{num+1}}</h1>
<h1>{
{num>9}}</h1>
<h1>{
{text}}--------{
{text.toUpperCase()}}</h1>
</div>
<script>
new Vue({
el:"#demodiv",
data:{
age:18,
sex:true,
love:["看书","学习","健身"],
dawei:{
a:"狂躁",
b:"闷骚"
},
num:10,
text:"abcdefg"
}
})
</script>
</body>
</html>
小结
- 表达式概念:使用双大括号来包裹 js 代码构成表达式
- 表达式语法:使用双花括号语法
Vue.js指令
什么是html标签的属性
写在html标签的开标签中 并且属性=“属性值”
用来扩展html标签的功能
什么是指令
就是带有v-前缀的html标签的特殊属性
指令写在哪里/功能
- 写在html标签的开标签中 并且v-属性=“属性值”
- 用来扩展html标签的功能/给元素添加特殊功能
- 注意:一个开始标签内可写入多个指令,多个指令间使用空格分隔
常见指令
v-text 指令
作用:操作网页元素中的纯文本内容。{ {}}是他的另外一种写法
v-text与{ {}}区别
v-text与{
{}}等价,{
{}}叫模板插值,v-text叫指令。
有一点区别就是,在渲染的数据比较多的时候,可能会把大括号显示出来,俗称屏幕闪动:
解决闪烁
为了解决这种问题,可以采用以下两种方式:
- ①使用v-text渲染数据
- ②使用{
{}}语法渲染数据,但是同时使用v-cloak指令(用来保持在元素上直到关联实例结束时候进行编译),v-cloak要放在什么位置呢,v-cloak并不需要添加到每个标签,只要在el挂载的标签上添加就可以
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-text与{
{}}</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<!-- v-text 就是网制定区域插入文本 -->
<h1>{
{text}}</h1>
<h1 v-text="text"></h1>
</div>
<script>
new Vue({
data:{
text:"你好么么哒",
},
el:"#demodiv"
})
</script>
</body>
</html>
v-show 指令
作用:控制切换一个元素的显示和隐藏
语法:v-show = 表达式
- 根据表达式结果的真假,确定是否显示当前元素
- true表示显示该元素;false(默认)表示隐藏该元素
- 元素一直存在只是被动态设置了display:none
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<h1>v-show 使用css控制元素的显示和隐藏</h1>
<h1 v-show="bool">测试</h1>
</div>
<script>
new Vue({
el: "#demodiv",
data: {
bool: true
}
})
</script>
</body>
</html>
v-on 指令或者@
作用:为 HTML 元素绑定事件监听
语法:v-on:事件名称=‘函数名称()’
简写语法:@事件名称=‘函数名称()’
- 注:函数定义在 methods 配置项中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="demodiv">
<h1>v-on绑定事件</h1>
<button v-on:click="fun()">点我调用函数</button>
<hr>
<h1 v-show="bool">看我显示和隐藏</h1>
<!-- 使用简写的写法 -->
<button @click="funb()">点我控制</button>
</div>
<script>
new Vue({
el:"#demodiv",
data:{
bool:true
},
// 创建函数
methods:{
fun(){
console.log("我是一个函数")
},
funb(){
this.bool=!this.bool
}
}
})
</script>
</body>
</html>
v-model指令(在登录注册就可以用)
作用:主要是用于表单上数据的双向绑定
语法:v-model = 变量
- 注:v-model 指令必须绑定在表单元素上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="demodiv">
<h1>v-model 用于在表单元素中进行数据的双向绑定
视图中的数据改变了 模型也改变
模型改变了 视图也随之改变
</h1>
<input type="text" v-model="inputval"/>
<hr>
<h1>{
{inputval}}</h1>
<h1>{
{inputval}}</h1>
<h1>{
{inputval}}</h1>
</div>
<script>
new Vue({
el:"#demodiv",
data:{
inputval:""
}
})
</script>
</body>
</html>
v-model扩展
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
v-model 是要绑定在表单元素中的 但是如果绑定到了表单元素中
那么他的值会自动被表单元素进行设置 如 复选框 复选框选中之后就是
true 没有选中 就是 false 如果数据有内容 那么久遵循非0 就是真
<input type="checkbox" v-model="text"/>
<h1>{
{text}}</h1>
<hr>
<input type="checkbox" v-model="bool"/>{
{bool?"勾选了":"取消了"}}
<h1 v-show="bool">看我的显示和隐藏</h1>
</div>
<script>
new Vue({
data:{
text:"你好么么哒",
bool:true
},
el:"#demodiv"
})
</script>
</body>
</html>
使用 v-show、v-on、v-model 指令完成练习
<!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="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
<p @click="fn()">{
{text}}</p>
<input type="text" v-model="text" v-show="bool" />
</div>
</body>
</html>
<script>
new Vue({
el: "#box",
data: {
text:"你好,小可爱",
bool:false
},
methods: {
fn() {
this.bool = !this.bool
// this.text = "你好,小可爱" 加上的话,每次点击都回复这个初始值
}
}
})
</script>
双向绑定
Vue框架核心的功能就是双向的数据绑定。
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
- 双向是指:HTML标签数据 绑定到 Vue对象,另外反方向数据也是绑定的
- 使用 v-model 指令来实现双向数据绑定 把视图数据与模型数据相互绑定
双向绑定–原理数据劫持
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
数据劫持:当我们访问或设置对象的属性的时候,都会触发==Object.defineProperty()==函数来拦截(劫持),然后在返回(get)或设置(set)对象的属性的值。并且当数据发生改变的时候做出反应。
双向绑定–原理发布者-订阅者模式
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
发布者-订阅者模式:其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="demodiv">
<h1>v-model 用于在表单元素中进行数据的双向绑定
视图中的数据改变了 模型也改变
模型改变了 视图也随之改变
</h1>
<input type="text" v-model="inputval"/>
<hr>
<h1>{
{inputval}}</h1>
<h1>{
{inputval}}</h1>
<h1>{
{inputval}}</h1>
</div>
<script>
new Vue({
el:"#demodiv",
data:{
inputval:""
}
})
</script>
</body>
</html>
v-for
作用:遍历 data 中的数据,并在页面进行数据展示
语法:**v-for = ‘(item, index) in arr’**
* item 表示每次遍历得到的元素
* index 表示item的索引,可选参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<h1>v-for 对数据进行遍历展示</h1>
<ul>
<!-- v-for="(遍历的值,遍历的下标) in 你要遍历的数据" -->
<li v-for="(v,i) in arr">
{
{v}}--------{
{i}}
</li>
</ul>
<!-- 遍历数组对象 -->
<table border="1">
<tr v-for="(v,i) in obj">
<td>{
{v.name}}</td>
<td>{
{v.age}}</td>
</tr>
</table>
</div>
<script>
new Vue({
el:"#demodiv"
data:{
arr:["汤姆", "杰克","NOC"],
obj:[
{
name: "dog", age: "10" },
{
name: "peg", age: "15" },
{
name: "peg", age: "15" },
{
name: "peg", age: "15" },
{
name: "peg", age: "15" }
]
},
})
</script>
</body>
</html>
v-bind 指令
作用:绑定 HTML 元素的属性
语法:**v-bind:属性名 = ‘表达式’**
简写 :==:属性名=‘表达式’==
绑定一个属性:< img v-bind:src=‘myUrl’ />
绑定多个属性(不能使用简写):
<img v-bind=‘{src:myUrl, title: msg}’ />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
v-bind 给html的属性插入变量的时候使用
<a v-bind:href="ahref">{
{text}}</a>
简写: 就是:号
<a :href="ahref">{
{text}}</a>
</div>
<script>
new Vue({
data:{
text:"去百度",
ahref:"http://www.baidu.com"
},
el:"#demodiv"
})
</script>
</body>
</html>
使用 v-for、v-on、v-bind 指令完成购物车总价计算
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
<style>
#demodiv{
width: 300px;
}
.red{
background-color: pink;
}
.yellow{
background-color: yellow;
}
</style>
</head>
<body>
<div id="demodiv">
<h1>low购物车</h1>
<ul>
<li v-for="(v,i) in obj" :class="v.style?'red':'yellow'" @click="fun(i)">
{
{v.title}}---------{
{v.num}}
</li>
</ul>
<hr/>
<p>总价是: {
{zong}}</p>
</div>
<script>
new Vue({
data:{
zong:0,
obj:[
{
title:"苹果",num:3,style:true},
{
title:"橘子",num:2.5,style:true},
{
title:"哈哈",num:10,style:true},
{
title:"呵呵",num:5.5,style:true},
{
title:"嘿嘿",num:1,style:true}
]
},
el:"#demodiv",
methods:{
fun(i){
console.log(i)
this.obj[i].style=!this.obj[i].style
}
}
})
</script>
</body>
</html>
v-if指令
作用:判断是否加载固定的内容
语法:v-if = 表达式
- 根据表达式结果的真假,确定是否显示当前元素
- true表示加载该元素;false表示不加载该元素
- 元素的显示和隐藏 是对Dom元素进行添加和删除
v-else 指令
作用:必须配合v-if使用否则无效。当v-if条件不成立的时候执行 登录的时候使用,else显示欢迎xxx登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
v-if 对元素进行添加和删除
<input type="checkbox" v-model="bool"/>
<h1 v-show="bool">我是v-show的效果</h1>
<h1 v-if="bool">我是v-if的效果</h1>
<h1 v-else>我是v-else</h1>
</div>
<script>
new Vue({
data:{
bool:true
},
el:"#demodiv"
})
</script>
</body>
</html>
v-else-if 指令
作用:当有一项成立时执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<h1 v-if="num==1">第1</h1>
<h1 v-else-if="num==2">第2</h1>
<h1 v-else-if="num==3">第3</h1>
<h1 v-else-if="num==4">第4</h1>
<h1 v-else>什么都没有</h1>
</div>
<script>
new Vue({
data:{
num:1
},
el:"#demodiv"
})
</script>
</body>
</html>
v-show和v-if的区别
+ 相同点:v-show和v-if都能控制元素的显示和隐藏
+ 实现本质方法不同
- v-if有更高的**切换消耗**(安全性高)
- v-show有更高的**初始化的渲染消耗**(对安全性无要求选择)
+ 性能
- v-show本质就是通过设置css中的display设置为none,控制隐藏, v-show有更高的初始化的渲染消耗(对安全性无要求选择)
- v-if是动态的向DOM树内添加或者删除DOM元素,v-if有更高的切换消耗(安全性高)
总结:如果要频繁切换某节点时,使用v-show(无论true或者false初始都会进行渲染,此后通过css来控制显示隐藏,因此切换开销比较小,初始开销较大),如果不需要频繁切换某节点时,使用v-if(因为懒加载,初始为false时,不会渲染,但是因为它是通过添加和删除dom元素来控制显示和隐藏的,因此初始渲染开销较小,切换开销比较大)
v-html 指令(插入字符串标签)
作用:双大括号会将数据解释为纯文本,而非 HTML 。为了输出真正的 HTML ,需要使用 v-html 指令
语法:< p v-html=“text”>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv" v-html="newhtml">
v-html 吧字符串标签解析成html
</div>
<script>
new Vue({
data:{
newhtml:"<h1>我是一个字符串标签</h1>"
},
el:"#demodiv"
})
</script>
</body>
</html>
v-once 指令(一次性插值)
作用:当数据改变时,插值处的内容不会更新(会影响到该节点上的所有属性)用在不想改变值的地方
语法: < p v-once>{ {text}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv" >
<input type="text" v-model="text">
<h1>{
{text}}</h1>
<!-- v-once 一次性插值 -->
<h1 v-once>{
{text}}</h1>
</div>
<script>
new Vue({
data:{
text:"我是默认值"
},
el:"#demodiv"
})
</script>
</body>
</html>
小结
v-show:控制切换一个元素的显示和隐藏
v-on:为 HTML 元素绑定事件监听
v-model:将用户的输入同步到视图上
v-for :遍历 data 中的数据,并在页面进行数据展示
v-bind:绑定 HTML 元素的属性
todolist案例
(渲染页面,添加,修改,勾选变色,数量,勾选删除)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
<style>
.red{
background-color: pink;
}
</style>
</head>
<body>
<!-- 1.页面还原 下面的列表是通过假数据遍历出来的 -->
<!--
2.完成添加功能
(1)给按钮添加一个点击事件
(2)在点击之后调用的函数中得到输入框的值
(3)吧输入框的值插入到obj的模型数据中
-->
<!-- 3.任务总数 双花括号中写的是表达式 任务总数是当前obj数组的长度 -->
<!--
4.点击修改
(1)默认情况下 每一行都有一个输入框和一个span 两者只显示一个使用v-if v-else
(2)给span添加点击事件 当点击span的时候让控制显示的 布尔值切换真假
-->
<!--
5勾选变色
(1)我们有n个数据 那么当我们勾选制定行内容的时候需要有一个变量用来保存
当前是否被勾选
-->
<!-- 6.还有
(1)判断当前数据中的style属性是否为假false 如果为false那么久让一个变量++
-->
<!-- 7.勾选删除
1.给每条数据在新增加一个变量用来保存是否被勾选的状态
2.把obj赋值给一个新变量保存
3.把obj清空
4.循环新变量判断当前数据中的勾选状态是否===false 如果===false 就把这条数据
push到obj中
-->
<div id="demodiv">
<h1>todolist</h1>
<p>任务总数:{
{obj.length}};还有:{
{sheng()}} 未完成;【<span @click="del()">完成</span>】</p>
<ul>
<li v-for="(v,i) in obj">
<input type="checkbox" v-model="v.style">{
{v.style}}
<span :class="v.style?'red':''" v-if="v.edit" @click="upbool(i)">{
{v.title}}</span>
<input v-else type="text" v-model="v.title" @blur="upbool(i)">
</li>
</ul>
<input type="text" v-model="inputval"><button @click="add()">添加</button>
</div>
<script>
new Vue({
data:{
inputval:"",
obj:[
{
title:"设计",edit:true,style:false},
{
title:"编写页面代码",edit:true,style:false},
{
title:"编写js代码",edit:true,style:false},
{
title:"设计产品原型",edit:true,style:false}
]
},
el:"#demodiv",
methods:{
add(){
console.log(this.inputval)
this.obj.push({
title:this.inputval,edit:true,style:false})
// 清空输入框
this.inputval=""
},
upbool(i){
this.obj[i].edit=!this.obj[i].edit
},
sheng(){
let num=0
this.obj.forEach(v => {
if(v.style===false){
num++
}
});
return num
},
del(){
let newobj=this.obj;
this.obj=[];
// 循环新变量判断当前数据中的勾选状态是否===false 如果===false 就把这条数据
// push到obj中
for(var i=0;i<newobj.length;i++){
if(newobj[i].style===false){
this.obj.push(newobj[i])
}
}
}
}
})
</script>
</body>
</html>
bootstrap
npm install --save [email protected]
使用方法可以看官网的基本模板,下面的代码为基本模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入-->
<link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<!-- 使用按钮 -->
<button type="button" class="btn btn-primary">(首选项)Primary</button>
<!-- 使用表格 -->
<table class="table table-hover">
<tr>
<td>xxxxx</td>
<td>xxxxx</td>
<td>xxxxx</td>
</tr>
<tr>
<td>xxxxx</td>
<td>xxxxx</td>
<td>xxxxx</td>
</tr>
<tr>
<td>xxxxx</td>
<td>xxxxx</td>
<td>xxxxx</td>
</tr>
</table>
<!-- 引入-->
<script src="./node_modules/jquery/dist/jquery.min.js"></script>
<script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
</body>
</html>
模态框开始 bs3-modal 回车后自动出来
类名 data-toggle=“modal” href=’#modal-id’
watch监听/侦听
watch:可以监听模型数据 当模型数据改变的时候就会触发
watch:{
监听的data数据(newval,oldval){
console.log(newval+"---"+oldval)
}
}
watch初始化的时候不会运行,只有数据被改变之后才会运行
什么时候使用watch
当需要在数据变化时执行异步或开销较大的操作时,watch这个方式是最有用的。
计算属性与侦听器的区别:
当watch监听的值发生改变就会被调用,watch可以在数据变化时做一些异步处理或者开销大的操作
计算属性是计算依赖的值,当依赖的值发生改变才会触发。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<!-- watch 用来监听data模型数据 当数据改变watch就会自动触发 -->
<input type="text" v-model="text">{
{text}}
</div>
<script >
new Vue({
el:"#demodiv",
data:{
text:"你好"
},
methods:{
},
watch:{
text(newval,oldval){
console.log(newval+"-------"+oldval)
}
}
})
</script>
</body>
</html>
计算属性
<p>{
{text.toUpperCase().substr(2,1)}}</p>
概念:
概念:顾名思义,首先它是一种属性,其次它有**“计算”**这个特殊性质。每次取得它的值得时候,它并不像普通属性那样直接返回结果,而是经过一系列的计算之后再返回结果。同时只要在它的当中里引用了 data 中的某个属性,当这个属性发生变化时,计算属性仿佛可以嗅探到这个变化,并自动重新执行。
为什么要用计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护
语法
computed: {
需要返回的数据: function () {
return 处理操作
}
}
使用
改造把数据转大写并且截取的例子
computed:{
demoText:function(){
return this.text.toUpperCase().substr(2,1);
}
}
计算属性VS方法
上面的例子也可以使用方法来完成
methods:{
textfun(){
return this.text.toUpperCase().substr(2,2)
}
}
那么计算属性computed和方法有什么区别呢?
- 计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
- 方法绑定数据只要被调用,方法将总会再次执行函数。
计算属性相对于方法在处理特定场合下节省资源性能
computed案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<!-- 如果在视图中有大量的业务数据处理没有问题 但是会影响我们的代码
可读性 官方不推荐我们这样子写 而且区公司也不能这样子写 -->
<!-- {
{text.toUpperCase()}}
{
{text}}
{
{text.toUpperCase().substr(2,3)}} -->
<!-- 如果 一条数据需要被处理之后再进行展示的话 可以使用计算属性
或者是 一条数据在不同位置展示数不同的形态 可以使用计算属性 -->
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<h1>{
{newtext}}</h1>
<h1>{
{newbtext}}</h1>
<hr>
<h1>方法</h1>
<h2>{
{fun()}}</h2>
<h2>{
{funb()}}</h2>
<h2>{
{fun()}}</h2>
<h2>{
{funb()}}</h2>
<h2>{
{fun()}}</h2>
<h2>{
{funb()}}</h2>
<h2>{
{fun()}}</h2>
<h2>{
{funb()}}</h2>
<h2>{
{fun()}}</h2>
<h2>{
{funb()}}</h2>
</div>
<script >
new Vue({
el:"#demodiv",
data:{
text:"abcdefg"
},
methods:{
fun(){
console.log("我是方法")
return this.text.toUpperCase()
},
funb(){
return this.text.toUpperCase().substr(2,4)
}
},
watch:{
},
computed:{
newtext(){
console.log("我是计算属性")
return this.text.toUpperCase()
},
newbtext(){
return this.text.toUpperCase().substr(2,4)
}
}
})
</script>
</body>
</html>
bootstrap–watch案例
<!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>
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<!-- 我们在写bootstrap的时候需要些布局容器container两边有留白 -->
<div class="container">
<div class="form-group">
<label for="uname">请输入用户名</label>
<input type="text" class="form-control" id="uname" v-model="input1">
</div>
<div class="form-group">
<label for="uage">请输入年龄</label>
<input type="text" class="form-control" id="uage" v-model="input2">
</div>
<button type="button" class="btn btn-primary" @click="add()" :disabled="bool">添加</button>
<button type="button" class="btn btn-danger">清空</button>
<table class="table table-bordered">
<tr>
<td>序号</td>
<td>名字</td>
<td>年龄</td>
<td>操作</td>
</tr>
<tr v-for="(v,i) in arr">
<td>{
{i+1}}</td>
<td>{
{v.name}}</td>
<td>{
{v.age}}</td>
<td><button class="btn btn-success" data-toggle="modal" href='#modal-id' @click="delnum=i">删除</button>
</td>
<tr class="text-right" v-if="arr.length!=0">
<td colspan="4">
<button type="button" class="btn btn-warning" data-toggle="modal" href='#modal-id'
@click="delnum=-1">删除全部</button>
</td>
</tr>
<tr class="text-center" v-else>
<td colspan="4">
<span>暂无数据.....</span>
</td>
</tr>
</tr>
</table>
<!-- 模态框开始 bs3-modal 回车后自动出来 -->
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">是否删除?</h4>
</div>
<div class="modal-body">
删了就没有了
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" @click="del()">确定</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<!--模态框结束 -->
</div>
</body>
</html>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="node_modules/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: ".container",
data: {
bool:true,
input1: "",
input2: "",
delnum: -100,
arr: [
{
name: "汤姆", age: 18 },
{
name: "杰克", age: 19 },
]
},
methods: {
add() {
this.arr.push({
name: this.input1, age: this.input2 });
this.input1 = "";
this.input2 = "";
},
del() {
console.log("1")
if(this.delnum===-1){
this.arr = []
}else if(this.delnum >= 0){
// 单行删除
this.arr.splice(this.delnum, 1)
}
}
},
watch:{
// 监听的data数据(newval,oldval){
// console.log(newval+"---"+oldval)
// }
input1(nerval,oldel){
// 判断两个输入框是否为空
if(this.input1==""||this.input2==""){
this.bool = true
}else {
this.bool = false
}
},
input2(nerval,oldel){
if(this.input1==""||this.input2==""){
this.bool = true
}else {
this.bool = false
}
}
}
})
</script>
事件对象
语法:
<div @click=‘fn($event)’></div>中,$event为事件对象
作用:
作用:记录事件相关的信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
</head>
<body>
<div id="demodiv">
<input type="text" @keydown.ctrl="fun($event)">
</div>
<script >
new Vue({
el:"#demodiv",
data:{
},
methods:{
fun(e){
// console.log(e)
// if(e.keyCode==17){
console.log("用户按下了ctrl")
// }
}
},
watch:{
},
computed:{
}
})
</script>
</body>
</html>
事件修饰符
概念:v-on指令提供了事件修饰符来处理DOM事件细节
按键修饰符: .up, .down, .ctrl, .enter, .space等等
** 语法**:@click.修饰符=‘fn()’
- prevent修饰符:阻止事件的默认行为(submit提交表单)
- stop修饰符:阻止事件冒泡
- capture修饰符:与事件冒泡的方向相反,事件捕获由外到内
- self:只会触发自己范围内的事件,不包含子元素
- once:只会触发一次
注意:修饰符可以串联使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="node_modules/vue/dist/vue.min.js"></script>
<style>
.fu{
width: 500px;
height: 500px;
background-color: pink;
}
.zi{
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<div id="demodiv">
<div class="fu" @click="fufun()">
<div class="zi" @click.stop.once="zifun()"></div>
</div>
</div>
<script >
new Vue({
el:"#demodiv",
data:{
},
methods:{
fufun(){
console.log("夫妇付付付付付付")
},
zifun(){
console.log("zizizzizizizizizzizi")
}
},
watch:{
},
computed:{
}
})
</script>
</body>
</html>
插入:promise
promise是一个一部解决方案,主要是为了解决回调地狱,回调地狱就是会点函数层层嵌套