class与style绑定 (以前属性值写固定的,现在放变量 模型中的数据 v-bind 升级版)
todo是啥,todolist是啥
使用axios和fetch作用&区别
计算属性和侦听器应用场景&区别(其实就是普通方法升级版 )
标签 class属性 style属性
希望 这两个属性的值 使用模型数据 v-bind 但是不够用 得用升级语法 vue 针对于这个两个属性单独定的规则
比如:class=“类1 类2 … 类n”
思考1:标签的class和style属性 一定是固定的 ?
回答1:不一定,还是有很多场景需要通过js动态追加类名,举个栗子导航、tab选项卡等
思考2:如何实现,仅仅通过v-bind语法就可以?
回答2:不够,因为我们需要放多个 不方便
解 决:vue针对情况,基于v-bind升级了语法 单独记
class使用模型数据
单个【直接写字符串】 v-bind:class="data中的键是个字符串"
多个-数组【数组中的每个值就是要显示的class】 v-bind:class="data中的键是个数组"
多个-对象【键就是要显示的class,值来控制是否展示bool】 v-bind:class="data中的键是个对象"
style使用模型数据
多个-对象【键是css属性名,值是css属性值】 v-bind:style="data中的键是个对象"
多个-数组【上面一个个对象】 v-bind:style="data中的键是个数组"
需求:给class和Style绑定模型数据
需求代码:直接复制
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.bgRed {background: red;}
.bgBlue {background: blue;}
.bgGreen {background: green;}
.fontRed {color: red;}
.fontBlue {color: blue;}
.fontGreen {color: green;}
</style>
</head>
<body>
<div id="app">
<!-- bgRed -->
<h1>class绑定模型数据(字符串语法)</h1>
<!-- bgBlue显示该类/fontRed不现实该类 -->
<h1>class绑定模型数据(对象语法) </h1>
<h1>class绑定模型数据(数组语法)</h1>
<!-- bgGreen/fontRed -->
<!-- 背景红色/字体20px -->
<h1>style绑定模型数据(对象语法)</h1>
<h1>style绑定模型数据(数组语法)</h1>
<!-- 背景黄色 -->
</div>
</body>
</html>
class绑定模型数据(字符串语法)
class绑定模型数据(对象语法)
class绑定模型数据(数组语法)
style绑定模型数据(对象语法)
style绑定模型数据(数组语法)
明确:咱们视图层直接 v-bind:class/style=“data中的键”
class
一个类 【模型中直接写字符串】
多个类-对象 【对象的键-就是类名,对象的值-布尔型控制类名是否显示】
对个类-数组 【数值中的值就是要显示的类名】
style
对象 【对象的键-就是css属性名,对象的值-就是css属性值】
数组 【数组中的值-是一个个对象,每个对象有CSS属性名:CSS属性值组长】
TODO. 某某功能存在优化 没有过滤
Todo指待完成、备忘
ToDoList待完成清单
----------------------------------
准 备:使用【https://github.com/webopenfather/ToDoList】中的静态文件
步骤1:循环显示模型数据(在模型中搞一个list键 参考demo-vue.html文件中的声明)
步骤2:添加数据放到模型中
步骤3:点击删除 移除模型数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<style type="text/css">
ul li { list-style: none; }
.main { width: 100%; display: flex; align-items: center; justify-content: center; margin: 15px 0px;}
.cc { float: right; }
td { display: flex; align-items: center; justify-content: space-between; padding: 5px 20px !important; }
</style>
<body>
<div class="container" id="app">
<h1 style="text-align: center;">ToDoList</h1>
<div class="main">
<div class="left">
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入内容" v-model="qq">
</div>
<div class="right">
<!-- 添加 -->
<button type="button" class="btn btn-primary">添加</button>
</div>
</div>
<table class="table table-condensed">
<tr>
<td class="active" v-for="item in lists">
{{item.name}}
<button type="submit" class="btn btn-default cc">
删除
</button>
</td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
lists: [
{name: '吃饭'},
{name: '睡觉'},
{name: '挤痘痘'},
{name: '抠脚'},
{name: '扣鼻'}
]
}
})
</script>
</body>
</html>
添加功能用户和网页之间的交互
1. 用户点击input框输入内容
2. 用户点击了添加按钮 数据就出来了
传统
1. 给按钮增加点击事件
2. 在事件处理函数中
2.1 获取input框里面的数据
2.2 通过js或jq在tr里面追加一个td
现在:思路不同,语法不同(双向绑定)
明确:VUE是按照MVVM思想写的,所以它会统一数据管理
因此:
1. 先将用户输入的数据同步到模型中 v-model
2. 给按钮设置点击事件
3. 在事件处理函数中 直接获取保存的数据,push到列表数据模型中
留心:因为列表模型数据改变了会自动同步到视图
todolist
ToDoList
{{item.name}}
用户和网页之间的交互:你点击删除按钮之后,一条数据没了
步骤1:给删除按钮设置一个点击事件
步骤2:去定义函数,在函数中 移除列表模型中的数据 (留心:因为MVVM思想所以只要数据被移除了 列表会重新渲染)
#二、axios 与 fetch 异步请求!!!
举个栗子,卖座电影网数据来源于异步请求
那么思考:在vue中如何发送异步请求获取数据
回答:传统(XMLHttpRequest、jq $.ajax) 现在(axios、fetch)
Axios[æk’si:əʊ]是一个用JS写的HTTP库(配合vue使用从而获取接口数据)
基于ajax和promise封装的
------------------------------------------------------------------------------------
手 册:https://www.kancloud.cn/yunye/axios/234845
库地址:https://cdn.bootcss.com/axios/0.18.0/axios.js
GET请求/POST请求
axios({
url
method
data
headers
}).then().catch()
###GET
axios({
method:"get"
//方案1
//url:"http://118.31.9.103/请求路径?参数1=值1&....&参数n=值n",
//方案2(推荐)
url:"http://118.31.9.103/请求路径",
params: {键:值,...,键n:值n}
}).then(res => {
}).catch(error=>{
console.log(error)
})
###POST
axios({
url:"http://118.31.9.103/请求路径",
method:"post",
data:"参数1=值1&....&参数n=值n"
}).then(res => {
}).catch(error=>{
console.log(error)
})
整理一下:
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
HTTP是啥呢:
请求头:请求地址、请求状态码、请求方式/HTTP动词(get、post、delete、put等)
响应头
{
"meta": {
"msg": "提示信息",
"status": 200
},
"data": [
{"id": 1, "title": "test1"},
{"id": 2, "title": "test2"},
{"id": 3, "title": "test3"},
{"id": 4, "title": "test4"}
]
}
需求2:通过axios请求data.json本地文件
需求3:通过axios请求线上“卖座电影正在热映”
<!DOCTYPE html>
<html lang="en">
<head>
<title>vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>本地请求</h1>
<button @click="fn1">点击发送请求</button>
<h1>线上请求</h1>
<button @click="fn2">点击发送请求</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
/*
1. 引入文件
2. 使用下述语法
axios发送异步请求
axios({
url: "",
method: "get",
方法1:直接在url后面写?键=值&...&键=值
方法2:通过params: {}
}).then(res => {})
// 推荐
axios.get(请求地址?键=值&...&键=值).then(res=>{})
axios.get(请求地址, {
// 声明get参数
params: {键:值, ..., 键:值}
// http里面有请求头 我想自定义
headers: {}
}).then(res => {})
*/
const vm = new Vue({
el: '#app',
data: {
},
methods: {
fn1() {
// 注:请求data.json是不需要传递参数的
// 但是呢:我们为了练习传递参数 所以加上
// console.log(axios.get('./data.json'))
// axios.get('./data.json?username=webopenfather&age=18')
// .then(res => { // res 是英文result 的缩写 结果
// console.log(res)
// console.log(res.data)
// // 留心:默认使用axios发送异步请求
// // 返回:携带HTTP相关信息的数据
// // 需要接口里面的数据:res.data
// // 拿到数据了,this.list = res.data.data
// })
axios.get('./data.json', {
params: {username: 'webopenfather', age: 18}
}).then(res=>{
console.log(res.data)
// 拿到数据了
// this.list = res.data.data
// 将拿到的数据保存到模型中 然后同步页面展示
})
},
fn2() {
axios.get("https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=9918769", {
// params
headers: {
// 思考:为什么需要自定义请求头,加下面两个参数呢
// 因为:卖座网,接口特殊 你请求它的接口 就必须加下述参数
// 对象的键可以不写引号 但是js不支持- 所以这里的键必须加引号
"X-Client-Info": '{"a":"3000","ch":"1002","v":"5.0.4","e":"1585118219919123002493","bc":"110100"}',
"X-Host": "mall.film-ticket.cinema.list"
}
})
.then(res => {
console.log(res)
})
}
}
})
</script>
</body>
</html>
留心:像之前的XMLHttpRequest 但并不真的是,而是代替的
fetch(请求地址,{
method: 请求方式,
headers:{},
// 当post请求用body get请求则在请求地址写?键=值&...&键=值
//body:"name=kerwin&age=100"
body:JSON.stringify({
数据1: 值1,
数据n: 值n
})
}).then(res=> res.json()).then(res=>{
console.log(res);
})
脚下留心:
promise对象
.then(res => {
return 666
})
.then(res => {
console.log(res) // 输出666 第一个then的值会交给第二个then处理
})
.catch(err => {}) // 所有then的异常都会交给catch处理
需求1:通过axios请求data.json本地文件
需求2:通过axios请求线上“卖座电影正在热映”
<!DOCTYPE html>
<html lang="en">
<head>
<title>vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>本地请求</h1>
<button @click="fn1">点击发送请求</button>
<h1>线上请求</h1>
<button @click="fn2">点击发送请求</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
/*
fetch(请求地址,{
method: 'get/post',
headers: {},
body: '键=值&...&键=值'
}).then()
*/
const vm = new Vue({
el: '#app',
data: {
},
methods: {
fn1() {
// fetch('./data.json')
// .then(res => {
// console.log(res) // Response 对象
// // console.log(res.json()) // promise对象 里面是我们想要的数据 交给第二个then处理获取
// return res.json()
// })
// .then(res => {
// console.log('-------')
// console.log(res)
// })
fetch('./data.json',{
method:'get', //默认get
// headers:{},
// 当post请求用body get请求则在请求地址写?键=值&...&键=值
// body:"name=kerwin&age=100"
// body:JSON.stringify({
// // 数据1: 值1,
// // 数据n: 值n
// a: 1,
// b: 2
// })
}).then(res=> res.json()).then(res=>{
console.log(res);
})
},
fn2() {
fetch('https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3912640', {
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"1585118219919123002493","bc":"110100"}',
'X-Host': 'mall.film-ticket.cinema.list'
}
})
.then(res => res.json())
.then(res => {
console.log(res)
})
}
}
})
</script>
</body>
</html>
最初ajax(XMLHttpRequest ECMA组织) 瑕疵:1-语法麻烦太多,2-异步回调地狱,3-语法有兼容性问题
后台jq(第三方作者)
明确:JQ里面的$.ajax是基于XMLHttpRequest封装的
好处:语法更简单、解决很多兼容性问题
瑕疵:异步回调地狱还在
解决:通过promise技术
最后fetch(ECMA组织) :仿原来的异步请求结合promise技术而生
fetch和axios
明确:以前vue官方推荐vue-resource 后来官方推荐axios
相同点:
1. 都是用来发送异步请求的
2. 都是基于promise封装
不同点:
1. 作者 axios是第三方,fetch是ECMA组织官方
2. 功能 axios更强(可以写全局的拦截所有请求 做数据处理,拦截所有响应做数据处理 咱们后期写项目就需要
3. 瑕疵 fetch每次都需要res.json()
定义
new Vue({
el,
data,
methods,
// 声明计算属性(名词就是普通方法的升级版:1-减少冗余,2-提升性能 有缓存
computed: {
}
})
调用:{{ 计算属性函数名 }} 切记切记切记函数升级版 所以不要加小括号
<!DOCTYPE html>
<html lang="en">
<head>
<title>vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>需求:翻转字符串</h1>
<p>
默认显示:{{msg}}
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: "hello,webopenfather"
},
methods: {
}
})
</script>
</body>
</html>
vue
需求:翻转字符串
默认显示:{{msg}}
简单实现:{{ msg.split('').reverse().join('') }} (注:缺点模板投放太多逻辑会让模板过中且难维护)
简单实现:{{ msg.split('').reverse().join('') }} (注:缺点模板投放太多逻辑会让模板过中且难维护)
普通方法:{{ reverseStrFn() }}
普通方法:{{ reverseStrFn() }}
计算属性:{{reverseStrComputed}}
计算属性:{{reverseStrComputed}}
思考:做商城项目的话,是否需要写搜索功能?
回答:肯定
思考:以前js如何写搜索的?
回答:1-给搜索框加键盘松开事件,2-获取内容,键盘松开发送异步请求
现在:vue新技术 侦听器 (其实也是普通方法升级版 另类使用
侦听器:名词解释不清,也是方法的升级版 可以监听模型数据变化,交给函数处理
定义
new Vue({
el,
data,
methods,
computed,
// 通过watch键来声明侦听器,作用:监控模型数据变化
watch: {
...
// 切记切记方法名必须是模型数据(也就是data中的键)
方法名(新数据,旧数据) { // 形参是系统传递进来的
}
}
})
调用:不能调用,怎么办?(监听数据变化,进行数据处理后 将处理后的数据保存到模型中)
<!DOCTYPE html>
<html lang="en">
<head>
<title>vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
搜索框: <input type="text" v-model="search" placeholder="请输入你要搜索的内容..."/>
<hr />
搜索结果:{{searchContent}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 搜索
// 传统:1.给input增加键盘松开事件,2-在事件处理函数中获取搜索的数据,3-发送异步请求,4-页面展示
// 现在:1.通过双向绑定将搜索内容同步模型,2-通过侦听器监控模型数据变化,发送异步请求
const vm = new Vue({
el: '#app',
data: {
search: '',
searchContent: ''
},
methods: {
},
computed: {
},
// 声明侦听器 监听模型数据变化
watch: {
search(newData, oldData) {
// console.log(newData, oldData)
// 将获取的新数据,通过axios发送异步请求
// 异步请求得到的数据 - 保存到模型中,然后再页面展示
this.searchContent = '异步请求数据'
}
}
})
</script>
</body>
</html>
1. 语法角度(定义:都是普通方法的升级
2. 研发角度:避免视图层写太多逻辑,导致后期维护麻烦
优化而生
1. 从语法角度(调用:计算属性调用不加小括号,侦听器不能调用
2. 从功能角度:计算属性有缓存,侦听器没有常用于搜索
什么时候用普通方法:1-事件调用,2-视图层有太多相同的代码 封装使用普通方法
什么时候用计算属性:普通方法多次调用并且单次特别耗性能 -> 通过计算属性优化
什么时候用侦听器:需要监控数据变化,常用与搜索
语法潜规则
new Vue({
el:,
data:,
methods:,
computed:{
函数名() {//后期调用直接函数名即可 ,有缓存
}
}
watch:{
data中的键(新数据,旧数据) { // 不能调用,将处理的结果保存到模型中
}
}
})
Class与Style绑定
明确:咱们视图层直接 v-bind:class/style="data中的键" 显示模型数据。
但是:针对class和style属性vue专门提供了语法处理
##class
一个类 【模型中直接写字符串】
多个类-对象 【对象的键-就是类名,对象的值-布尔型控制类名是否显示】
对个类-数组 【数值中的值就是要显示的类名】
##style
对象 【对象的键-就是css属性名,对象的值-就是css属性值】
数组 【数组中的值-是一个个对象,每个对象有CSS属性名:CSS属性值组长】
axios 与 fetch 异步请求
###axios
1 引入库
2 使用语法
axios.get(请求地址,可选参数对象类型)
{
params: {参数键:值,...,参数键:值},
headers: {}
...
}
axios.post(请求地址,{参数键:值,...,参数键:值})
axios.put(请求地址,{参数键:值,...,参数键:值})
axios.delete(请求地址)
###fetch
1 不用引入库
2 使用语法
fetch(请求地址,可选参数)
.then(res => res.json())
.then(res => {
console.log(res)
})
可选参数 { method: 'get/post',headers: {}, body: '键=值&...&键=值'} 注:post请求用body
计算属性和侦听器
- 什么时候用普通方法:1-事件调用,2-视图层有太多相同的代码 封装使用普通方法
- 什么时候用计算属性:普通方法多次调用并且单次特别耗性能 -> 通过计算属性优化
- 什么时候用侦听器:需要监控数据变化,常用与搜索
- 语法潜规则
new Vue({
el:,
data:,
methods:,
computed:{
函数名() {//后期调用直接函数名即可 ,有缓存
}
}
watch:{
data中的键(新数据,旧数据) { // 不能调用,将处理的结果保存到模型中
}
}
})
数据传输:post比get能传递更多数据(注:post一般8M后端服务器配置 get根据不同浏览器地址栏有限制
安全角度:post比get相对安全(注:比如登录get提交在地址栏 你在网吧你走了 后面的就从地址栏知道你密码