这是我参与8月更文挑战的第17天,活动详情查看: 8月更文挑战
微信公众号搜索【程序媛小庄】 – 没有白走的路,每一步都算数
Vue & jQuery
- jquery的定位是获取元素完成特效
- vue的定位是方便操作和控制数据完成特效
VUE介绍
vue.js是目前前端web开发最流行的工具库,由尤雨溪在2014年2月发布的。
另外几个常见的工具库:react.js /angular.js/jQuery
官方网站:
英文:vuejs.org/
vue.js目前有1.x、2.x和3.x 版本,我们学习2.x版本的。
vue两种开发模式
- 脚本化引入(vue.js文件在项目根目录下)
<script src="vue.js"></script>
复制代码
- 组件化开发,drf组件化开发
vue基本使用
- 基本使用步骤
1.在head标签内引入vue.js文件 --- 脚本化引入
<script src='vue.js'></script>
2.创建标签,为其设置id
<div id='app'><div>
3.在body标签中创建script标签对html页面上的其他标签进行操作
3.1 vue的使用是从创建Vue对象开始的
var vm = new Vue();
3.2 创建vue对象的时候需要传递参数,传递的参数必须是json格式的数据,并且此数据至少有两个属性成员el以及data
var vm = new Vue({
el:'#app',
data:{
数据变量:'变量值',
message:'哈哈',
},
})
el:设置vue可以操作的html内容范围,值一般就是css的id选择器
data:保存vue对象中要显示到html页面的数据
3.3 将vue对象中保存的数据通过模版语法展示到html页面
<div id='app'>
{{message}}
</div>
复制代码
- 注意事项
1.实例化vue对象时每个对象名必须是唯一的,一个页面有多个vue对象,每个对象对应一个功能
2.js中所有的变量和语法都是区分大小写的
3.script标签的位置
复制代码
VUE的框架思想 — MVVM
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式。
Model
:指代的就是vue对象的data属性里面的数据。这里的数据要显示到页面中。
View
:指代的就是vue中数据要显示的HTML页面,在vue中,也称之为“视图模板” 。
ViewModel
:指代的是vue.js中我们编写代码时的vm对象了,它是vue.js的核心,负责连接 View 和 Model,保证视图和数据的一致性,所以前面代码中,data里面的数据被显示在p标签中就是vm对象自动完成的。
在代码中标识每一部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<!-- View -->
<div id="app">
{{message}}
</div>
<script>
// View Model
let vm = new Vue({
el:'#app',
// Model
data:{
message:'hahah'
}
});
</script>
</body>
</html>
复制代码
在浏览器中可以在 console.log通过 vm对象可以直接访问el和data属性,甚至可以访问data里面的数据
$表示vm对象的属性,这些属性都是vm对象初始化的时候进行赋值的
console.log(vm.$el) // vm对象可以控制的范围
console.log(vm.$data); // vm对象要显示到页面中的数据
console.log(vm.$data.message); // 访问data里面的数据
console.log(vm.message); // 这个 message就是data里面声明的数据,也可以使用 vm.变量名显示其他数据,message只是举例.
复制代码
模版语法显示数据
- 文本插值:
{{}}
or 指令v-text
在双标签中显示纯文本数据要通过{{ }} or 指令v-text
来完成数据显示,双括号中还可以支持js表达式和符合js语法的代码
<p id="app">
{{message}}
<span v-text="message"></span>
<span v-once>{{ message }}</span>
</p>
<!--
{{}}和属性v-text等价
无论何时,绑定的数据对象上 msg变量发生了改变,插值处的内容都会更新。
如果使用了指令v-once则数据仅仅执行一次插值,当数据改变时,插值处的内容不会更新
-->
复制代码
双大括号内可以使用变量、表达式、函数等合法的js语法,以下都是合法的
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
但是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}
<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }
复制代码
- 在表单输入框中显示data中的数据要添加v-model属性来完成数据显示
<span id="app">
<input type="text" v-model="message">
<textarea name="" id="" cols="30" rows="10" v-model="message"></textarea>
</span>
<!--
使用v-model把data里面的数据显示到表单元素以后,一旦用户修改表单元素的值,则data里面对应数据的值也会随之发生改变,甚至,页面中凡是使用了这个数据都会发生变化。
-->
复制代码
- 如果双标签的内容要显示的数据包含html代码则需要使用v-html属性
<body>
<span id="app">
<span v-html="message"></span>
</span>
<script>
let vm = new Vue({
el:'#app',
data:{
message:'<h1>msg</h1>'
}
})
</script>
</body>
复制代码
指令
指令介绍
指令 (Directives) 是带有“v-”前缀的特殊属性。每一个指令在vue中都有固定的作用。
在vue中,提供了很多指令,常用的有:v-if、v-model、v-for等等。
指令会在vm对象的data属性的数据发生变化时,会同时改变元素中的其控制的内容或属性。
因为vue的历史版本原因,所以有一部分指令都有两种写法:
vue1.x写法 vue2.x的写法
v-html ----> v-html
{{ 普通文本 }} {{普通文本}}
v-bind:属性名 ----> :属性
v-on:事件名 ----> @事件名
复制代码
绑定指令
vue1.x写法 | vue2.x的写法 |
---|---|
v-bind:属性名 | :属性名 |
v-bind的作用:就是绑定,动态的将标签的属性值与vue对象中的数据变量绑定到一块,实现在vue对象中对标签的属性、样式、class类等进行操作
属性操作
将vue对象data属性中的值动态渲染给标签的属性值,相当于告诉属性名你的值是一个来自于vue对象中的变量而不是字符串
<div id="app">
<!-- vue1.x版本 -->
<a v-bind:href="url">百度</a>
<!-- vue2.x版本 -->
<a :href="url">百度</a>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
url:'http://www.baidu.com',
}
})
</script>
复制代码
类操作
类的值可以是字符串/对象/对象名/数组
<div id="app">
<!-- :的意思是告诉属性名你的值是来自vue对象的变量所对应的值 -->
<p :class="cls1">类的值是字符串</p>
<p :class="{cls1:false}">类的值是对象,对象的值是false,cls1对应的样式就不会生效</p>
<p :class="cls3">类的值是对象名称</p>
<p :class="[cls1,cls2]">类的值是数组,数组中的样式会同时生效,批量给元素增加多个class样式类</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
cls1:'box1',
cls2:'box2',
cls3:{'box1':false,'box2':true},
}
})
</script>
复制代码
样式(style)操作
样式的值可以是字符串/对象/对象名/数组
<div id="box">
<div style="color: red; background: blue">style1,普通的样式写法</div>
<div :style="{color:fc,backgroundColor:'blue'}">vue修改行内样式,值是对象</div>
<div :style="sty">vue修改行内样式,值是对象名</div>
<div :style="[sty,sty1]">vue修改行内样式,值是数组</div>
</div>
<script>
var vm = new Vue({
el:'#box',
data:{
fc:'red',
ac:'blue',
sty:{color:'yellow',backgroundColor:'black'},
sty1:{fontSize:'50px',border:'5px solid blue'}
},
})
</script>
复制代码
条件指令
条件指令介绍
条件指令 是用来控制元素的显示与隐藏的(条件为真显示,条件为假不显示),即用于条件性的渲染某一块内容
v-if & v-else-if & v-else
可以出现多个v-else-if语句,但是v-else-if之前必须有一个v-if开头。后面可以跟着v-else,也可以没有。
v-else指令来表示 v-if 的“else 块”,v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
<div id="app">
<p v-if="num==0">{{num}}</p>
<p v-else-if="num==1">one</p>
<p v-else>else</p>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
num:1
}
})
</script>
复制代码
v-show
<p v-show="num==1">v-show{{num}}</p>
复制代码
v-if与v-show的异同
用法和v-if大致一样,区别在于2点:
- v-show后面不能有v-else或者v-else-if
- v-show隐藏元素时,使用的是display:none来隐藏的,而v-if是直接从HTML文档中移除元素[ DOM操作中的remove ]
标签元素:
<h1 v-show="ok">Hello!</h1>
data数据:
data:{
ok:false // true则是显示,false是隐藏
}
复制代码
循环指令
在vue中,可以通过v-for指令将一组数据渲染到页面中,数据可以是数组或者对象
- 循环数组
<div id="goods">
<table border="3">
<tr>
<td>序号</td>
<td>id</td>
<td>name</td>
<td>price</td>
</tr>
<!--第一个元素是数据,第二个元素是索引下标-->
<tr v-for="goods,index in book_list">
<td>{{index}}</td>
<td>{{goods.id}}</td>
<td>{{goods.title}}</td>
<td>{{goods.price}}</td>
</tr>
</table>
</div>
<script>
var vm = new Vue({
el:'#goods',
data:{
book_list:[
{"id":1,"title":"图书名称1","price":200},
{"id":2,"title":"图书名称2","price":200},
{"id":3,"title":"图书名称3","price":200},
{"id":4,"title":"图书名称4","price":200},
]
}
})
</script>
复制代码
- 循环对象
<ul>
<!--第一个元素是值,第二个元素是键-->
<li v-for="value, attr in book">{{attr}}:{{value}}</li>
</ul>
复制代码
- 总结:循环取值时,不显示数组的索引或者键的方式是循环是只使用一个变量接收
<li v-for="book in book_list">{{book.title}}</li>
<li v-for="value in book">{{value}}</li>
复制代码
事件绑定指令
事件指令介绍
vue1.x版本 | vue2.x版本 |
---|---|
v-on:事件名称 | @事件名称 |
vue中的事件名称全部都是js的事件名
js中的事件 | vue中的事件名称 |
---|---|
onsubmit | @submit |
onfocus | @focus |
onblur | @blur |
onclick | @click |
简单事件
简单事件处理逻辑直接写在字符串中即可
<div id="app">
<!--实现输入框内数据加减操作-->
<button @click="num++">+</button>
<input type="text" v-model="num">
<button @click="num--">-</button>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
num:0
}
})
</script>
复制代码
复杂事件
复杂事件的处理逻辑,单独写在一个函数放在vue对象的methods中通过函数命名调用执行
<div id="app">
<button @click="myalert">alert</button>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
num:0,
name:'hello'
},
methods:{
myalert(){
alert(this.name + '!')
}
}
})
</script>
复制代码
Vue对象属性功能
过滤器
自定义过滤器用于一些常见的文本格式化,过滤器可以用在两个地方:双花括号插值和绑定指令的后面
全局过滤器
- 语法格式
Vue.filter('过滤器的名字','fucntion(args){return args.方法}')
复制代码
- 代码案例 — 将vue对象data中的price属性保留两位小数输出到前端页面
<div id="app">
{{price}}
{{price|foo}}
</div>
<script></script>
复制代码
- 全局过滤器总结
全局过滤器:语法格式Vue.filter('过滤器的名字','function(args){return args.方法}}')
将data中某一个数据当作过滤器的参数,传给过滤器函数,然后返回过滤器处理后的结果
处理后的结果可以通过模版语法输出,模版语法+过滤器的语法格式{{需要处理的数据|过滤器的函数名}}
复制代码
局部过滤器
- 语法格式
filters:{
函数名(args){return args.方法}
}
复制代码
- 代码案例
<div id="app">
{{price}}
{{price|format}}
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
price:8.1536
},
// 局部过滤器
filters:{
format(money){
return money.toFixed(2)+'元'
}
},
})
</script>
复制代码
- 局部过滤器总结
局部过滤器只对当前vue对象中的数据产生效果
局部过滤器是放在当前的vue对象中的filters属性中定义的函数
复制代码
vue对象的计算属性
计算属性:相当于创建一个新的变量保存数据计算的结果
<div id="app">
<input type="text" v-model="num">+
<input type="text" v-model="num1">=
<span>{{mySum}}</span>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
num:0,
num1:1
},
computed:{
// mySum接收计算结果
mySum(){
// this指代vue对象
return parseFloat(this.num)+parseFloat(this.num1)
}
}
})
</script>
复制代码
vue对象的侦听属性
侦听属性,可以帮助我们侦听data中某个数据的变化,从而做相应的自定义操作。
侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是一个函数,当侦听的data数据发生变化时,会自动执行对应的函数,这个函数在被调用的时候,需要两个形参,第一个是变化前的数据值,第二个是变化后的数据值。
<div id="app">
<input type="text" v-model="num">
<button @click="num++" >+</button>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
num:0
},
watch:{
// 可以简写为num(v1,v2){}
num:function (v1,v2) {
if(this.num>=5){this.num=5}
console.log(v1,v2)
}
}
})
</script>
复制代码
vue对象的生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.min.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:"#app",
data:{
num:0
},
beforeCreate:function(){
console.log("beforeCreate,vm对象尚未创建,num="+ this.num); //undefined
this.name=10; // 此时没有this对象呢,所以设置的name无效,被在创建对象的时候被覆盖为0
},
created:function(){
console.log("created,vm对象创建完成,设置好了要控制的元素范围,num="+this.num ); // 0
this.num = 20;
},
beforeMount:function(){
console.log( this.$el.innerHTML ); // <p>{{num}}</p>
console.log("beforeMount,vm对象尚未把data数据显示到页面中,num="+this.num ); // 20
this.num = 30;
},
mounted:function(){
console.log( this.$el.innerHTML ); // <p>30</p>
console.log("mounted,vm对象已经把data数据显示到页面中,num="+this.num); // 30
},
beforeUpdate:function(){
// this.$el 就是我们上面的el属性了,$el表示当前vue.js所控制的元素#app
console.log( this.$el.innerHTML ); // <p>30</p>
console.log("beforeUpdate,vm对象尚未把更新后的data数据显示到页面中,num="+this.num); // beforeUpdate----31
},
updated:function(){
console.log( this.$el.innerHTML ); // <p>31</p>
console.log("updated,vm对象已经把过呢更新后的data数据显示到页面中,num=" + this.num ); // updated----31
},
});
}
</script>
</head>
<body>
<div id="app">
<p>{{num}}</p>
<button @click="num++">按钮</button>
</div>
</body>
</html>
复制代码
- 总结
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是修改页面的数据,在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created
在页面加载完成之前,对后台发起http请求获取数据,代码写在created中
复制代码
阻止事件冒泡和刷新页面
事件冒泡:指代js中子元素的事件触发以后,会导致父级元素的同类事件一并被触发到。
事件冒泡有好处,也有坏处。
好处:如果能正确利用这种现象,可以实现事件委托,提升特效的性能
坏处:如果没有正确使用,则会导致不必要的bug出现。
- @click.stop来阻止事件冒泡
- @click.prevent来阻止表单提交
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box1{
width: 200px;
height: 200px;
background: #ccc;
}
.box2{
width: 100px;
height: 100px;
background: pink;
}
</style>
<script src="vue.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:"#app",
data:{}
})
}
</script>
</head>
<body>
<div id="app">
<div class="box1" @click="alert('box1')">
<div class="box2" @click.stop.prevent="alert('box2')"></div> <!-- @click.stop来阻止事件冒泡 -->
</div>
<form action="#">
<input type="text">
<input type="submit">
<input type="submit" value="提交02" @click.prevent=""> <!-- @click.prevent来阻止表单提交 -->
</form>
</div>
</body>
</html>
复制代码
综合案例 — TODOLIST
- 源html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
.list_con{
width:600px;
margin:50px auto 0;
}
.inputtxt{
width:550px;
height:30px;
border:1px solid #ccc;
padding:0px;
text-indent:10px;
}
.inputbtn{
width:40px;
height:32px;
padding:0px;
border:1px solid #ccc;
}
.list{
margin:0;
padding:0;
list-style:none;
margin-top:20px;
}
.list li{
height:40px;
line-height:40px;
border-bottom:1px solid #ccc;
}
.list li span{
float:left;
}
.list li a{
float:right;
text-decoration:none;
margin:0 10px;
}
</style>
</head>
<body>
<div class="list_con">
<h2>To do list</h2>
<input type="text" name="" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li>
<span>学习html</span>
<a href="javascript:;" class="up"> ↑ </a>
<a href="javascript:;" class="down"> ↓ </a>
<a href="javascript:;" class="del">删除</a>
</li>
<li><span>学习css</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
<li><span>学习javascript</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
</ul>
</div>
</body>
</html>
复制代码
- 实现效果代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
.list_con{
width:600px;
margin:50px auto 0;
}
.inputtxt{
width:550px;
height:30px;
border:1px solid #ccc;
padding:0px;
text-indent:10px;
}
.inputbtn{
width:40px;
height:32px;
padding:0px;
border:1px solid #ccc;
}
.list{
margin:0;
padding:0;
list-style:none;
margin-top:20px;
}
.list li{
height:40px;
line-height:40px;
border-bottom:1px solid #ccc;
}
.list li span{
float:left;
}
.list li a{
float:right;
text-decoration:none;
margin:0 10px;
}
</style>
<script src="vue.js"></script>
</head>
<body>
<div class="list_con" id="app">
<h2>To do list</h2>
<input type="text" v-model="content" id="txt1" class="inputtxt">
<input type="button" @click="add" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li v-for="item,index in todolist">
<span>{{item}}</span>
<a href="javascript:;" class="up" @click="up(index)"> ↑ </a>
<a href="javascript:;" class="down" @click="down(index)"> ↓ </a>
<a href="javascript:;" class="del" @click="del(index)">删除</a>
</li>
</ul>
</div>
<script>
let vm = new Vue({
el:'#app',
data:{
content:'',
todolist:['学习html','学习css','学习javascript','学习c'],
},
methods:{
add(){
// js中追加一个数组成员使用push,添加
this.todolist.push(this.content);
// 添加之后将输入框中的信息清空
this.content=''
},
del(index){
// js中splice高阶函数可以指定从指定下标的位置删除成员的个数,在指定位置替换成员
// splice(删除开始的下标,删除成员的数量,替代被删除的元素)
this.todolist.splice(index,1);
},
up(index){
// 上移
// 首先删除移动的元素保存到内存中,再将删除的元素插入到数组的指定位置,即下标减一,splice会返回一个内容 --- 被操作的数据对象
let currentItem = this.todolist.splice(index,1)[0];
this.todolist.splice(index-1,0,currentItem)
},
down(index){
// 下移
// 原理和上移是类似的
let currentItem = this.todolist.splice(index,1)[0];
this.todolist.splice(index+1,0,currentItem)
}
}
})
</script>
</body>
</html>
复制代码
结语
文章首发于微信公众号程序媛小庄,同步于掘金。
码字不易,转载请说明出处,走过路过的小伙伴们伸出可爱的小指头点个赞再走吧(╹▽╹)