Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)

■ 目录

class与style绑定 (以前属性值写固定的,现在放变量 模型中的数据 v-bind 升级版)

todo是啥,todolist是啥

使用axios和fetch作用&区别

计算属性和侦听器应用场景&区别(其实就是普通方法升级版 )

一、Class与Style绑定

概念

标签 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属性值组长】

■ ToDoList综合小案例来一个

TODO. 某某功能存在优化 没有过滤

概念

  • Todo指待完成、备忘

  • ToDoList待完成清单

----------------------------------

  • 相关案例:线上产品
    Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第1张图片

需求

Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第2张图片

准 备:使用【https://github.com/webopenfather/ToDoList】中的静态文件
步骤1:循环显示模型数据(在模型中搞一个list键 参考demo-vue.html文件中的声明)
步骤2:添加数据放到模型中
步骤3:点击删除 移除模型数据

1.循环显示模型数据

<!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>

2.添加数据放到模型中

添加功能用户和网页之间的交互
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}}

3.点击删除移除模型数据

用户和网页之间的交互:你点击删除按钮之后,一条数据没了

步骤1:给删除按钮设置一个点击事件
步骤2:去定义函数,在函数中 移除列表模型中的数据 (留心:因为MVVM思想所以只要数据被移除了 列表会重新渲染)

#二、axios 与 fetch 异步请求!!!

明确需求

Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第3张图片
https://m.maizuo.com/

举个栗子,卖座电影网数据来源于异步请求

那么思考:在vue中如何发送异步请求获取数据

回答:传统(XMLHttpRequest、jq $.ajax) 现在(axios、fetch)

axios简介&语法

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等)
响应头

来一个axios小练习吧

  • 需求1:在day3目录下创建data.json接口文件
{
    "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>

fetch简介&语法

Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第4张图片

留心:像之前的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处理

来一个fetch小练习吧

  • 需求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/jq/fetch关系!!!

最初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()

三、计算属性和侦听器!

计算属性(明确需求)

  • 思考:视图主要负责展示数据,但是如果在视图写过多的逻辑是否有利于后期维护?
  • 回答:肯定不利于后期优化
  • 解决:以前(封装起来,直接调用) 现在(计算属性)
  • 作用:1-减少代码冗余便于维护,2-有缓存提升性能

Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第5张图片

计算属性(语法)

定义

new Vue({
    el,
    data,
    methods,
    // 声明计算属性(名词就是普通方法的升级版:1-减少冗余,2-提升性能 有缓存
    computed: {
        
    }
})

调用:{{ 计算属性函数名 }} 切记切记切记函数升级版 所以不要加小括号

计算属性(小试牛刀)

  • 效果图
    Vue基础(Class与Style绑定、axios&fetch数据请求、计算属性computed、侦听器watch常用于搜索)_第6张图片
  • 需求代码:
<!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中的键(新数据,旧数据) { // 不能调用,将处理的结果保存到模型中
        }
    }
})

get和post区别 (最后补充)

数据传输:post比get能传递更多数据(注:post一般8M后端服务器配置 get根据不同浏览器地址栏有限制
安全角度:post比get相对安全(注:比如登录get提交在地址栏 你在网吧你走了 后面的就从地址栏知道你密码

你可能感兴趣的:(vue,计算属性/侦听器)