一、操作样式
1. 控制标签class类名
格式:
<h1 :class="值">元素</h1> 值可以是对象、对象名、数组(数组的方式用的比较少)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: greenyellow;
font-size: 20px;
}
.c2{
font-size: 30px;
}
</style>
</head>
<body>
<div id="app">
<div :class="{c1:num==0,c3:num==0}" class="c2">{{msg}}</div>
<!--<div :class="status?'c1':'c2'">{{msg}}</div>-->
<div :class="status?'c1':'c2'">{{msg}}</div>
<div :class="[m1,]">xxxxx</div>
<input type="text" v-model="num">
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
msg:'hello',
num:0,
status:false,
m1:{
c1:false,
c2:false,
}
}
}
})
</script>
</html>
总结:
给元素绑定class类名。
vue对象的data数据:
data:{
myObj:{
complete:true,
uncomplete:false,
}
}
html元素:
<div class="box" :class="myObj">2222</div>
最终浏览器效果:
<div class="box complete">2222</div>
2.控制标签style样式
格式1:值是json对象,对象写在元素的:style属性中
标签元素:
<div :style="{color: activeColor, fontSize: fontSize + 'px' }"></div>
<!-- 注意:不能出现中横杠,有的话就套上'font-size',或者去掉横杠,后一个单词的首字母大写,比如fontSize -->
data数据如下:
data: {
activeColor: 'red',
fontSize: 30
}
格式2:值是对象变量名,对象在data中进行声明
标签元素:
<div v-bind:style="styleObject"></div>
data数据如下:
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
格式3:值是数组
标签元素:
<div v-bind:style="[style1, style2]"></div>
data数据如下:
data: {
style1:{
color:"red"
},
style2:{
background:"yellow",
fontSize: "21px"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="app">
<!-- 方式1 -->
<div :style="{color:fontColor,backgroundColor: bgc}">
xxxxxxx
</div>
<!-- 方式2 -->
<div :style="xxx">
xxxxxxx
</div>
<input type="text" v-model="fontColor">
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
msg:'hello',
fontColor:'red',
bgc:'green',
xxx:{
'color':'red',
// 'font-size':'80px'
fontSize:'80px'
},
num:0,
status:false,
m1:{
c1:false,
c2:false,
}
}
}
})
</script>
</html>
实例-vue版本选项卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#card{
width: 500px;
height: 350px;
}
.title{
height:50px;
}
.title span{
width: 100px;
height: 50px;
background-color:#ccc;
display: inline-block;
line-height: 50px; /* 设置行和当前元素的高度相等,就可以让文本内容上下居中 */
text-align:center;
}
.content .list{
width: 500px;
height: 300px;
background-color: yellow;
display: none;
}
.content .active{
display: block;
}
.title .current{
background-color: yellow;
}
</style>
<script src="vue.js"></script>
</head>
<body>
<div id="card">
<div class="title">
<span @click="num=1" :class="{current:num===1}">国内新闻</span>
<span @click="num=2" :class="{current:num===2}">国际新闻</span>
<span @click="num=3" :class="{current:num===3}">银河新闻</span>
<!--<span>{{num}}</span>-->
</div>
<div class="content">
<div class="list" :class="{active:num===1}">国内新闻列表</div>
<div class="list" :class="{active:num===2}">国际新闻列表</div>
<div class="list" :class="{active:num===3}">银河新闻列表</div>
</div>
</div>
<script>
// 思路:
// 当用户点击标题栏的按钮[span]时,显示对应索引下标的内容块[.list]
// 代码实现:
var card = new Vue({
el:"#card",
data:{
num:1,
},
});
</script>
</body>
</html>
二、列表渲染指令v-for
在vue中,可以通过v-for指令可以将一组数据渲染到页面中,数据可以是数组或者对象。
数据是数组:
<ul>
<!--i是列表的每一个元素-->
<li v-for="book in book_list">{{book.title}}</li>
</ul>
<ul>
<!-- v-for不仅可以遍历数组,还可以遍历对象,这里大家记住v-for里面的一个东西 :key, 就是v-bind:key,这个key是干
什么的呢,就是为了给现在已经渲染好的li标签做个标记,以后即便是有数据更新了,也可以在这个li标签里面进行数据的更新,不需要再让
Vue做重新生成li标签的dom操作,提高页面渲染的性能,因为我们知道频繁的添加删除dom操作对性能是有影响的,我现在将数据中的id绑定到
这里,如果数据里面有id,一般都用id,如果没有id,就绑定v-for里面那个index(当然你看你给这个索引取的变量名是什么,我这里给索引取
的名字是index),这里面它用的是diff算法,回头再说这个算法 -->
<!-- <li v-for="(item,index) in data.users" :key="item.id" @click> 还可以绑定事件 -->
<li v-for="(item,index) in book_list" :key="item.id"> 第{{index+1}}本图书:{{book.title}}</li>
<!-- v-for的优先级最高,先把v-for遍历完,然后给:key加数据,还有,如果没有bind这个key,有可能你的页面都后期用动态数
据渲染的时候,会出现问题,所以以后大家记着,一定写上v-bind:key -->
</ul>
<script>
var vm1 = new Vue({
el:"#app",
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>
<!--i是每一个value值-->
<li v-for="value in book">{{value}}</li>
</ul>
<ul>
<!--value是每一个value值,attr是每一个键名-->
<li v-for="value,attr in book">{{attr}}:{{value}}</li>
</ul>
<script>
var vm1 = new Vue({
el:"#app",
data:{
book: {
// "attr属性名":"value属性值"
"id":11,
"title":"图书名称1",
"price":200
},
},
})
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="app">
<ul>
<!--<li v-for="(value,index) in data_list" :key="index">-->
<!--<li v-for="value in data_list" :key="value.id">-->
<li v-for="value in data_list" :key="value.id">
{{value.name}}
</li>
<li v-for="(value,index) in personInfo">
{{value}} -- {{index}}
</li>
</ul>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
data_list:[
{id:1,name:'鑫伟1'},
{id:4,name:'鑫伟4'},
],
personInfo:{
name:'chao',
age:18
}
}
}
})
</script>
</html>
练习:
goods:[
{"name":"python入门","price":150},
{"name":"python进阶","price":100},
{"name":"python高级","price":75},
{"name":"python研究","price":60},
{"name":"python放弃","price":110},
]
# 把上面的数据采用table表格输出到页面,价格大于60的那一条数据需要添加背景色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
<tr v-for="(value,index) in goods" :key="index">
<td>{{value.name}}</td>
<td v-if="value.price>60" style="background-color: red;">{{value.price}}</td>
<td v-else>{{value.price}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
goods:[
{"name":"python入门","price":150},
{"name":"python进阶","price":100},
{"name":"python高级","price":75},
{"name":"python研究","price":60},
{"name":"python放弃","price":110},
]
}
}
})
</script>
</html>
三、Vue对象提供的属性功能
1.过滤器
过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中。
定义过滤器的方式有两种,全局和局部过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>{{price}}</p>
<p>{{price.toFixed(2)}}</p>
<p>{{price|yuan}}</p>
<p>{{price|xx}}</p>
<p>{{price|xx|yuan}}</p>
<!-- 过滤器传额外参数 -->
<p>{{price2|yuan2(2)}}</p>
</div>
</body>
<script src="vue.js"></script>
<script>
// 全局过滤器
Vue.filter('xx',function (value) {
return value.toFixed(3) + '圆'
});
let vm = new Vue({
el:'#app',
data(){
return {
price:100,
price2:100.126, //四舍五入
}
},
// 局部过滤器
filters:{
yuan(value){
return value + ' 元'
},
yuan2(value,n){
return value.toFixed(n) + ' 元'
}
}
})
</script>
</html>
2.计算和监听属性
1).计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>{{price}}</p>
<p>{{add}}</p>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
price1:100,
price2:100.126,
}
},
// 计算属性
computed:{
add(){
return this.price1 + this.price2
}
}
})
</script>
</html>
2).监听属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>{{price1}}</p>
<input type="text" v-model="price1">
<button @click="info.xx='ss'">走你</button>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
price1:100,
price2:100.126,
info:{
xx:'oo',
}
}
},
watch:{
// price1(newv,oldv){
// console.log(newv,oldv);
// if (newv == 200){
// alert('200块钱了!!')
// }
//
// }
'info.xx':function(newv,oldv){
if (newv != 'oo'){
alert('不是oo了')
}
}
}
})
</script>
</html>
示例:用户名长度限制4-10位
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="xx">
<span style="color:red;font-size: 12px;">{{msg}}</span>
<button>走你</button>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
xx:'',
msg:'长度不对!'
}
},
watch:{
xx(newv,oldv){
if (newv.length > 4 && newv.length < 10){
this.msg = ''
}else {
this.msg = '长度不对!!!!!!!!'
}
}
}
})
</script>
</html>
3.vue对象的生命周期钩子函数
每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>{{price1}}</p>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
price1:100,
}
},
// beforeCreate(){
// console.log('-----beforeCreate-----');
// console.log(this.$el);
// console.log(this.$data);
// },
created(){ //重点
console.log('-----created-----');
console.log(this.$el);
console.log(this.$data);
},
beforeMount(){
console.log('-----beforeMount-----');
console.log(this.$el);
console.log(this.$data);
},
mounted(){ //
console.log('-----mounted-----');
console.log(this.$el);
console.log(this.$data);
}
})
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
<script>
window.onload = function(){
//$(function(){})() $.ready() -- window.onload = function(){}
var vm = new Vue({
el:"#app",
data:{
num:0
},
beforeCreate:function(){
console.log("beforeCreate,vm对象尚未创建,num="+ this.num); //undefined,就是说data属性中的值还没有放到vm对象中
this.name=10; // 此时没有this对象呢,所以设置的name无效,被在创建对象的时候被覆盖为0
console.log(this.$el) //undefined
},
created:function(){
// 用的居多,一般在这里使用ajax去后端获取数据,然后交给data属性
console.log("created,vm对象创建完成,设置好了要控制的元素范围,num="+this.num ); // 0 也就是说data属性中的值已经放到vm对象中
this.num = 20;
console.log(this.$el) //undefined
},
beforeMount:function(){
console.log( this.$el.innerHTML ); // <p>{{num}}</p> ,vm对象已经帮我们获取到了这个视图的id对象了
console.log("beforeMount,vm对象尚未把data数据显示到页面中,num="+this.num ); // 20,也就是说vm对象还没有将数据添加到我们的视图中的时候
this.num = 30;
},
mounted:function(){
// 用的居多,一般在这里使用ajax去后端获取数据然后通过js代码对页面中原来的内容进行更改
console.log( this.$el.innerHTML ); // <p>30</p>
console.log("mounted,vm对象已经把data数据显示到页面中,num="+this.num); // 30,也就是说vm对象已经将数据添加到我们的视图中的时候
},
// 后面两个简单作为了解吧,测试的时候最好单独测试下面两个方法
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>
自定义最简单的钩子
class A:
def __init__(self):
self.run()
def run(self):
pass
class B(A):
def run(self):
print('xxxx')
b = B()
总结:
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created
4.阻止事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 200px;
}
.c2{
background-color: green;
height: 100px;
width: 100px;
}
</style>
</head>
<body>
<div id="app">
<div class="c1" @click="f1">
<!--<div class="c2" @click.stop="f2" ></div>-->
<div class="c2" @click.stop.prevent="f2" ></div>
<!-- 阻止标签自带的动作 -->
<!--<a href="http://www.baidu.com" @click.stop.prevent="">百度</a>-->
</div>
</div>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
price1:100,
}
},
methods:{
f1(){
alert('111');
},
f2(){
alert('222');
}
}
})
</script>
</html>
综合案例-todolist(计划列表)
<!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" v-model="sm">
<input type="button" name="" value="增加" id="btn1" class="inputbtn" @click="add">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li v-for="(value,index) in dolist" :key="value.id">
<span>{{value.dosm}}</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>
</body>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:'.list_con',
data(){
return {
sm:'',
dolist:[
{id:1,dosm:'学习html'},
{id:2,dosm:'学习css'},
{id:3,dosm:'学习javascript'},
{id:4,dosm:'学习python'},
{id:5,dosm:'学习推油'},
]
}
},
methods:{
add(){
let last_ele = this.dolist[this.dolist.length-1];
if (last_ele){
let ele = {
id:++last_ele.id,
dosm:this.sm,
};
this.dolist.push(ele);
}else {
this.dolist.push({id:1,dosm:this.sm});
}
// console.log(this.dolist);
},
del(index){
this.dolist.splice(index,1);
},
up(index){
if (index > 0){
let delEle = this.dolist.splice(index,1)[0];
// console.log(delEle);
this.dolist.splice(index-1,0,delEle)
}
},
down(index){
let delEle = this.dolist.splice(index,1)[0];
this.dolist.splice(index+1,0,delEle)
}
}
})
</script>
</html>
四、通过axios实现数据请求
1.axios使用
vue.js默认没有提供ajax功能的。
所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互。
注意,axios本质上就是javascript的ajax封装,所以会被同源策略限制。
下载地址:
https://unpkg.com/axios@0.18.0/dist/axios.js
https://unpkg.com/axios@0.18.0/dist/axios.min.js
axios提供发送请求的常用方法有两个:axios.get() 和 axios.post() 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1>
</div>
</body>
<script src="vue.js"></script>
<script src="jquery.js"></script>
<script src="axios.js"></script>
<script>
let vm = new Vue({
el:'#app',
data(){
return {
price1:100,
msg:'',
}
},
created(){
// let ths = this;
// axios.get('http://wthrcdn.etouch.cn/weather_mini?city=北京&city2=xx',{
axios.get('http://wthrcdn.etouch.cn/weather_mini',{
params:{
city:'北京',
//city:'北京',
}
})
.then( (res) => {
// console.log(res);
// console.log(res.data.data.ganmao);
// console.log(this);
// 注意this指向问题
// ths.msg = res.data.data.ganmao;
this.msg = res.data.data.ganmao;
}).catch(function (res) {
})
// $.ajax({
// url:'http://wthrcdn.etouch.cn/weather_mini?city=北京',
// type:'get',
//
// success:function (res) {
// console.log(res);
// }
//
// })
}
})
</script>
</html>
2.json
json是 JavaScript Object Notation 的首字母缩写,单词的意思是javascript对象表示法,这里说的json指的是类似于javascript对象的一种数据格式。
json的作用:在不同的系统平台,或不同编程语言之间传递数据。
- javascript提供了一个JSON对象来操作json数据的数据转换.
方法 | 参数 | 返回值 | 描述 |
---|---|---|---|
stringify | json对象 | 字符串 | json对象转成字符串 |
parse | 字符串 | json对象 | 字符串格式的json数据转成json对象 |
3.ajax
ajax,一般中文称之为:“阿贾克斯”,是英文 “Async Javascript And Xml”的简写,译作:异步js和xml数据传输数据。
ajax的作用: ajax可以让js代替浏览器向后端程序发送http请求,与后端通信,在用户不知道的情况下操作数据和信息,从而实现页面局部刷新数据/无刷新更新数据。
所以开发中ajax是很常用的技术,主要用于操作后端提供的数据接口
,从而实现网站的前后端分离
。
ajax技术的原理是实例化js的XMLHttpRequest对象,使用此对象提供的内置方法就可以与后端进行数据通信。
数据接口
数据接口,也叫api接口,表示后端提供
操作数据/功能的url地址给客户端使用。
客户端通过发起请求向服务端提供的url地址申请操作数据【操作:增删查改】
同时在工作中,大部分数据接口都不是手写,而是通过函数库/框架来生成。
ajax的使用
ajax的使用必须与服务端程序配合使用,但暂时先不涉及到服务端python代码的编写。因此,我们可以使用别人写好的数据接口进行调用。
jQuery将ajax封装成了一个函数$.ajax(),我们可以直接用这个函数来执行ajax请求。
接口 | 地址 |
---|---|
天气接口 | http://wthrcdn.etouch.cn/weather_mini?city=城市名称 |
音乐接口搜索 | http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=歌曲标题 |
音乐信息接口 | http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.play&songid=音乐ID |
同源策略
同源策略,是浏览器为了保护用户信息安全的一种安全机制。所谓的同源就是指代通信的两个地址(例如服务端接口地址与浏览器客户端页面地址)之间比较,是否协议、域名(IP)和端口相同。不同源的客户端脚本[javascript]在没有明确授权的情况下,没有权限读写对方信息。
ajax本质上还是javascript,是运行在浏览器中的脚本语言,所以会被受到浏览器的同源策略所限制。
ajax跨域(跨源)方案之CORS
CORS是一个W3C标准,全称是"跨域资源共享",它允许浏览器向跨源的后端服务器发出ajax请求,从而克服了AJAX只能同源使用的限制。
实现CORS主要依靠后端服务器中响应数据中设置响应头信息返回的。
// 在响应行信息里面设置以下内容:
Access-Control-Allow-Origin: ajax所在的域名地址
Access-Control-Allow-Origin: www.baidu.com # 表示只允许www.baidu.com域名的客户端的ajax跨域访问
// * 表示任意源,表示允许任意源下的客户端的ajax都可以访问当前服务端信息
Access-Control-Allow-Origin: *