框架级的数据请求
- axios ( 第三方库 — 别人封装好的库 )
- fetch ( javascript 原生提供 )
- vue数据请求的发展
- vue-resource ( Vue 以前自己封装使用的请求类库 ) ,但是 vue-resource作者已经放弃更新了
- vue-resource 作者推荐我们使用 axios
- vue-resource 用法 和 axios 相似度 90% +
- vue2.0我们基本上使用的都是 fetch / axios
- vue-resource 是有jsonp的
- vue-resource 如果在vue中使用,是挂载当前的 实例( 组件 ) 的$http属性身上的
- 举例 this. h t t p ( o p t i o n s ) t h i s . http( options ) this. http(options)this.http.get() this.$http.post
- axios 和 fetch 没有jsonp 数据请求类型的
- axios 和 fetch 都是promise
- axios会对我们请求来的结果进行再一次的封装( 让安全性提高 )
- axios案例:
new Vue({
el: '#app',
methods: {
getData () {
//进行get请求
// axios.get() -- $.get()
// axios.post() ---$.post()
// axios(options) -- $.ajax(options)
// var p = axios({
// url: './data/data.json'
// })
// console.log( p ) Promise对象
axios({
url: './data/data.json',
method: 'get',//默认就是get请求
})
.then( res => console.log( res ))
.catch( error => conosle.log( error ))
},
postData () {
// 进行post请求
},
get_myself_php_data () {
axios({
url: 'http://localhost/get.php',
params: {
a: 1,
b: 2
}
})
.then( res => console.log( res ))
.catch( error => console.log( error ))
},
get_be_data () {
// 跨域请求线上数据 - 卖座
axios({
url: 'https://m.maizuo.com/gateway',
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"154549400038873748996477"}',
'X-Host': 'mall.film-ticket.film.list'
},
params: {
cityId: 330100,
pageNum: 1,
pageSize: 10,
type: 1,
k: 7675918
}
})
.then( res => console.log( res ))
.catch( error => console.log( error ))
}
}
})
- axios 中 post请求(官网案例有错误)
var params = new URLSearchParams() //得到params对象,用来接收参数
// params.append( key, value ) key就是参数名,value就是参数值
params.append( 'a', 2 )
params.append( 'b', 2 )
axios({
url: 'http://localhost/post.php',
method: 'post',
headers: {
'Content-Type': "application/x-www-form-urlencoded" //请求头设置为表单提交的请求头
},
data: params
})
.then( res => console.log( res ))
.catch( error => console.log( error ))
- fetch要手动进行一次数据格式化,但是axios是内部进行了数据的格式化
- fetch get 方法请求数据,参数要直接连接在url上
- fetch 格式化数据 有三种 处理方法
- .json() 格式化 json 类型数据, 将 json类型 string 转换成 json 对象
- .text() 格式化文本
- .blob() 格式化二进制数据
- fetch 如果按照官网文档书写post请求,也有坑, 携带数据出现了问题
- fetch post处理
- 设置请求头
- 通过 new URLSearchPrams 来携带参数
- fetch案例
<body>
<div id="app">
<button @click = "getData"> get </button>
<button @click = "postData"> post </button>
</div>
</body>
<script>
/*
fetch是原生javascript提供的 , 所以它 可以当做全局变量使用 ,它是挂载在window对象身上的
*/
new Vue({
el: '#app',
methods: {
getData () {
fetch('./data/data.json')
.then( res => res.json() ) //对数据进行格式化
.then( data => console.log( data ) ) // 这里的data就是格式化后的数据
.catch( error => console.log( error ))
// fetch('https://m.maizuo.com/gateway?cityId=330100&pageNum=1&pageSize=10&type=1&k=7675918')
},
postData () {
fetch( 'http://localhost/post.php',{
method: 'post',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
}),
body: new URLSearchParams([["a", 1],["b", 2]]).toString()
})
.then( res => res.text() )
.then( data => console.log( data ))
.catch( error => console.log( error ))
}
}
})
</script>
----------------------------- 侦听属性 watch ---------------------------
watch
- 作用
- 用来监听data中定义的数据,当data中定义的数据发生了变化,那么watch中的key就会触发
- watch是一个对象
watch: {} - watch中可以设置多个类型的键值
- 使用方式( 重点 )
- 方法
watch: {
fn () {}
}
- 对象: ( 深度监听 )
watch: {
fn: {
handler(){},
deep: true
}
}
## 计算属性
1. 使用方式
- 里面存放方法
```javascript
computed: {
fn () {
return '' //必须要有返回值
}
}
- 里面存放对象
```javascript
computed: {
newName: {
get () {
return '' //get里面要有return
},
set ( val ) { //val就是修改后的值
}
}
}
```
- 注意: 上面的get,set我们统一起了个名字叫做: 存储器,别人也叫getter/setter
- get set 这两者, 对象中有,类里面也有
- **get set 是计算属性的 这个理解是错的**
computed
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: '',
},
computed: {
fullName () {
return this.firstName + this.lastName
}
}
})
</script>
watch vs computed
- watch是用来监听某一个数据的,当数据发生改变是,watch就会自动触发,然后我们可以进行一些任务
- computed是为了暴露一个全局变量,这个全局变量是经由一定逻辑产生的
- 什么时候选择 watch ? 什么是选择 computed ? 什么时候选择 methods?
- 数据量较大,并且有异步操作我们选择 watch 应用场景: 上拉加载,下拉刷新
- computd的使用满足两个就可以了
- 暴露一个类似全局变量的数据
- 可以进行逻辑的处理
- methods的使用: 事件程序程序 ( 用户交互 )
mixins
实际意义:将组件的选项抽离出去,单独管理,复用
-
有两种使用形式
-
局部混入
<body> <div id="app"> <button @click = "add"> add </button> <button @click = "aa"> aa </button> </div> </body> <script> var mixinObj = { methods: { add () { alert ( 'add' ) } } } new Vue({ el: '#app', data: {}, mixins: [ mixinObj ], //局部混入 methods: { aa () { alert( 'aa' ) }, add () { // 如果实例中方法名和mixins中的方法名相同,那么实例中的触发 console.log( '实例中add' ) } }, watch: {}, computed:{} }) </script>
-
全局混入(一般不使用)
<body> <div id="app"> <button @click = "add"> add </button> </div> </body> <script> /* 全局的混入 : Vue.mixin({}) 不建议使用 */ Vue.mixin({ methods: { add () { alert( 'add' ) } } }) new Vue({ el: '#app', data: {}, }) </script>
-
原理
- 数据驱动
当数据发生改变时,视图也会进行更新,这叫做数据驱动,也就是数据驱动视图 - 深入响应式原理
数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新 - 双向数据绑定原理
当我们使用 v-model 指令绑定了表单元素时,那么我们可以在视图直接获得数据,当视图发生改变时,数据也会进行更新
综上: 三者都是应用了同一个底层原理,这个底层原理由es5的 Object.defineProperty 属性来提供
- vue中底层原理的实现主要是依赖 存储器( getter/setter )
- 我们利用了数据劫持和事件的发布订阅来实现双向数据绑定,当我们在vue data选项中定义数据时,vue会通过观察者对象( observer )将data选项中的所有key,经过Object.defineProperty 的getter 和setter进行设置,当我们通过 v-model指令绑定元素是, 自动触发getter,getter会返回一个初始值,这样我们在视图中就可以看到数据了,当视图中内容改变时,会触发setter,setter会通知vue,视图已经进行了更新,vue会重新生成 虚拟DOM , 继而通过 新旧 虚拟DOM 对比, 生成patch对象,再将patch对应渲染到视图中
Vue.set/this.$set 的原理( 数组的下标和length不响应 )
原始js:Object.defineProperty()
<script>
/*
Object.defineProperty( obj, attr, options )
obj: 指的是要监听的对象
attr: 是这个对象身上的属性
options: 是对这个对象的属性的配置
核心:
是否可读
是否可遍历( 枚举 )
存储器
get
set
vue中国
*/
var box = document.querySelector( '.box' )
var btn = document.querySelector('button')
var input = document.querySelector('input')
var perple = {
name: '小王'
}
box.innerHTML = perple.name
Object.defineProperty( perple, 'name' , {
get () {
return '小红'
},
set ( val ) {
console.log( val ) //val是修改后的值
box.innerHTML = val
console.log( 'set' )
}
})
btn.onclick = function(){
perple.name = "小明"
}
// box.innerHTML = perple.name
// console.log( perple )
input.oninput = function() {
console.log( input.value )
}
</script>
底层:Object.assign
<script>
var obj1 = {
name1: '小明',
id: 1,
age: 18
}
var obj2 = {
name2: '123'
}
var obj3 = Object.assign( {},obj1,obj2 ) //进行对象合并的
console.log( obj3 )
console.log(Object.keys( obj1 ))
console.log(Object.values( obj1 ))
</script>