Vue基础(数据请求、组件、属性等)
axios&&fetch
-
目的:是在框架中使用数据请求
-
数据请求
-
使用原生js提供的fetch
-
使用第三方封装库:axios
- Vue中可以统一对axios进行挂载
Vue.prototype.$http = axios
-
fetch与axios
- axios 对已获得的数据进行了一层封装 XSRF
- axios底层自动对数据进行了格式化
- fetch并没有进行封装,拿到就是格式化后的数据
- fetch进行了多一层的格式化
- res.json()
- res.blob() 格式化二进制
- res.text()
- fetch进行了多一层的格式化
- axios 对已获得的数据进行了一层封装 XSRF
-
//Axios总结 npm i axios
//或者引入cdn
//统一设置axios post的请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
Vue.prototype.$http = axios //挂载axios
new Vue({
el: '#app',
data: {
list: []
},
methods: {
static () {//请求静态数据,不需要传入数据
/* 请求静态数据 【 模拟假数据 - mock数据 】
* 线上拷贝相似字段数据
* 使用第三方 mock.js 来生成json数据 【 用代码来生成数据 】
* esay mock线上网站*/
this.$http
.get('./data/list.json')
.then( res => {
console.log( res )
this.list = res.data.data.content
})
.catch( error => console.log( error ))
},
get () {//请求动态数据,get方法
axios({
url: 'http://localhost/get.php',
params: { //这是get请求的传参
a: 5,
b: 4
}
}).then( res => console.log( res ))
.catch( error => console.log( error ))
},
post () {//请求动态数据,post方法
/*
不能直接使用npmjs官方方法
方法:1. 先设置请求头
2. 实例化 URLSearchParams的构造器函数得到params对象
3. 使用params对象身上的append方法进行数据的传参
*/
let params = new URLSearchParams()
params.append('a',1)
params.append('b',2)
axios({
url: 'http://localhost/post.php',
method: 'post',
data: params, headers: { //单个请求设置请求头(与上方统一设请求头只需要一个)
'Content-Type': "application/x-www-form-urlencoded"
}
}).then( res => console.log( res ))
.catch( error => console.log( error ))
}
}
})
//fetch 总结
new Vue({
el: '#app',
data: {
list: []
},
methods: {
static () {//获取静态数据
fetch('./data/list.json')
.then( res => res.json() ) //将获得的json数据格式化
.then( data => {
this.list = data.data.content
})
.catch( error => console.log( error ))
},
get () {// 请求动态数据的get方法
fetch('http://localhost/get.php?a=1&b=2')//请求的参数写在url上
.then( res => res.text() )//数据格式化 res.json()/res.blob()
.then( data => console.log( data ))
.catch( error => console.log( error ))
},
post () {// 请求动态数据的post方法
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 ))
}
}
})
- axios与fetch请求返回的都是Promise对象,所以要用.then().catch(),但是fetch中需要写2个.then(),第一个用来格式化数据
- 历史
- Vue1.0
- Vue1.0数据请求我们使用的是一个第三方的封装库,这个封装库叫做 vue-resource
- vue-resource现在已经淘汰了,它的作者也推荐我们使用axios
- vue-resource使用形式和axios一样的
- this.$http.get
- this.$http.post
- this.$http({})
- vue-resource有jsonp方法,而axios是没有的
- vue-resource使用形式和axios一样的
- Vue2.0
- axios [ 可以说是目前最好的数据请求的封装库 ]
- fetch
- Vue1.0
- ajax与fetch的区别
- fetch是基于promise实现的,也可以结合async/await,使用比ajax更加简单。
- ajax是针对MVC的编程,不符合现在前端MVVM的浪潮。
- fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理。
- ajax只要当状态为200或者304时才会请求成功。
- Ajax的本质是使用XMLHttpRequest对象来请求数据
- fetch没有办法原生监测请求的进度,而XHR可以。
- fetch 是全局量 window 的一个方法。
计算属性(computed)
<div id="app">
<p> {{ msg }} </p>
<p> 计算属性: {{ newMsg }} </p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'I love qiao daima !!!'
},
computed: {
newMsg () {//实现反向
return this.msg.split('').reverse().join('')
}
}
})
</script>
-
使用:
- 在选项中定义一个computed 属性,属性值是一个对象,对象中存储都是方法,这些方法必须有返回值
- 在vm实例范围内,直接当做全局变量一样使用这个方法名称
- 注意,方法名后不加 ()
-
何时使用:有逻辑,实例中直接当做全局变量处理
侦听属性(watch)
-
watch是Vue中的一个选项,监听数据的变化,当数据改变时,执行一些操作。
new Vue({ el: '#app', data: { firstName: '', lastName: '', fullName: '', num: 0 }, watch: { firstName ( val ) { this.fullName = val + this.lastName }, lastName ( val ) { this.fullName = this.firstName + val }, num: { deep: true, // 深度监听 handler ( val ) { // 当num发生改变时,触发的方法 console.log( val ) } // 代表在wacth里声明了num这个方法之后立即先去执行handler方法 immediate: true } } })
-
总结: methods vs computed vs watch
-
项目中如何使用
-
- 事件处理程序: methods
-
-
watch
有大量数据交互和异步处理时进行
-
-
- computed
- 有逻辑处理
- V中像全局变量一样使用
- computed
-
混入(mixin)
- 混入的形式
- 全局混入 【 不推荐 】
- 局部混入
- 混入的作用:
- 将选项中某一个或是多个单独分离出去管理,让职能更加单一高效,符合模块化思想
<script src="./js/method.js"></script>
<script>
/*
全局混入
所有的组件都会加上去 选项内容
Vue.mixin({
methods: {
bb () {
alert('bb')
}
}
})
*/
new Vue({
el: '#app',
mixins: [ obj ]//局部混入
/*
局部混入
通过mixins选项来引入一个对象
*/
})
</script>
组件
-
先自行简单了解前端组件化发展历史
- 前后端耦合
- 前后端不分离项目
-
- 找后台搭建项目开发环境
-
- 寻找项目目录中的静态资源目录
- js
- img
- css
- 寻找项目目录中的静态资源目录
-
- 同步修改css
-
- 前后端不分离项目
- 前后端分离
- 前端团队合作项目的出现
- 组件化为了解决多人协作冲突问题
- 复用
- 前后端耦合
-
组件的概念
- 组件是一个html 、 css 、js 、img 等的一个聚合体
-
Vue中的组件属于扩展性功能
-
通过 Vue.extend() 来扩展的
ƒ Vue (options) {//Vue if (!(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword'); } this._init(options); } ƒ VueComponent (options) {//Vue.extend() this._init(options); }
-
VueComponet这个构造函数我们不进行new实例化,我们希望组件是以标签化的形式展示
<Hello/> --> <div></div> <Banner></Banner>
-
组件要想合法化,必须注册解析
-
组件的注册 【 创建 】
- 全局注册
- 局部注册
组件的注册
<body> <div id="app"> <Hello></Hello> <Hello/> </div> </body> <script> // 全局注册 // 组件的选项 var Hello = Vue.extend({ template: '<div> hello 组件 </div>' }) // 组件的注册 // Vue.component( 组件的名称, 组件选项 ) Vue.component('Hello',Hello); /* 与上面实现的效果一样 Vue.component('Hello',{ template: '<div> hello 组件 </div>' }) */ new Vue({ el: '#app' }) </script> <script> // 组件的注册 - 局部注册 new Vue({ el: '#app', components: { // 组件的名称: 组件的选项 'Hello': { template: '<div> hello </div>' } } }) </script>
-
-
组件的命名规范
Vue.component('Hello',{ //<Hello></Hello> template: '<div> hello </div>' }) Vue.component('HeaderTitle',{ // <header-title></header-title> template: '<div> HeaderTitle </div>' }) Vue.component('movie-list',{ // <movie-list></movie-list> template: '<div> 电影列表 </div>' })
-
组件的使用
-
在 html / h5中有一些标签, 它的父子级元素是规定的,这个时候如果我们使用组件,那么久打破了这个规则,就会出错
-
这类型标签有:
ul li
ol li
dl dt dd
table tr td
selcet option
-
解决方案:使用is属性来绑定一个组件
<body> <div id="app"> <table border="1"> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr is = "Hello"></tr> </table> </div> </body> <script> Vue.component('Hello',{ template: ` <tr> <td>4</td> <td>5</td> <td>6</td> </tr>` }) new Vue({ el: '#app' }) </script>
- 点击一个开关切换两个组件
<body> <div id="app"> <button @click = " comp = comp === 'UserLogin'? 'PhoneLogin':'UserLogin'"> 切换 </button> <keep-alive> <!-- 动态缓存组件 --> <component :is = "comp"></component> <!-- 动态组件 --> </keep-alive> </div> </body> <script> Vue.component('UserLogin',{ template: '<div> 用户名密码登录 </div>' }) Vue.component('PhoneLogin',{ template: '<div> 短信验证码登录 </div>' }) new Vue({ el: '#app', data: { comp: 'UserLogin' } }) </script>
- 模板template
-
- template标签是放在实例模板范围外的
- template标签外在外层时是不会被解析的,也就是会在dom结构中出现,如果放在实例范围内,会被解析,是不会出现在dom结构中
- template中直接子元素必须有且仅有一个
-
<body> <div id="app"> <Hello></Hello> <template> <!-- template标签放在实例内会不显示 --> <p> 模板template </p> </template> </div> <template id="hello-box"> <!-- template中直接子元素必须有且仅有一个 --> <div> 你好 </div> </template> </body> <script> Vue.component('Hello', { template: '#hello-box' }) new Vue({ el: '#app' }) </script>
- 组件嵌套
<body> <div id="app"> <Father></Father> </div> <template id="father"> <div> <h3> 这里是father组件 </h3> <Son></Son> <!-- 将子组件以标签的形式在父组件的模板使用 --> </div> </template> <template id="son"> <div> <h4> 这里是子组件 </h4> </div> </template> </body> <script> Vue.component('Father',{ template: '#father' }) Vue.component('Son',{ template: '#son' }) new Vue({ el: '#app', data: { comp: 'UserLogin' } }) </script>
- 组件嵌套-局部形式
//html部分同上面一样 new Vue({ el: '#app', data: { comp: 'UserLogin' }, components: { 'Father': { template: '#father', components: { 'Son': { template: '#son' } } } } })
-