Vue
一、初识vue
1、什么是vue
Vue是一个轻量级框架
组件化
数据的双向绑定
Vue是一个MVVM框架,数据双向绑定。
指令
Vue.js与页面交互,通过指令完成
组件化
对某一个功能进行封装,可重复用的代码
路由
vue-router—>官方插件,进行页面跳转
状态管理
vuex进行存储
2、vue实例
vue引入
超链接
3、声明式渲染
1)显示
插值表达式:{{message}}
v-bind:title = “message” / :title = "message"
v-if=“seen”
v-for =“item in muster” {{item}}
v-on:click="click" / @click="click"
v-model='message' ==>双向绑定
2)添加数据
添加数据
todos.push() ==> 添加到末尾
删除末尾元素 ==> todos.pop()
todos.unshift() ==> 添加到开头
删除开头元素 ==> todos.shift()
3)数组截取数据
v-for='item in demoArray.slice(0,5)'
二、模板语法
1、文本
数据绑定最常见的方式就是使用‘’Mustache‘’语法(双大括号)的文本插值:
例:
<span>Message: {{ msg }}</span>
指令:v-once
含义:执行一次性的插值
通过使用v-once指令,你也能执行一次性的插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其他数据绑定:
例:
<span v-once>这个将不会改变:{{ msg }}</span>
2、原始 HTML
指令:v-HTML
含义:使style得以表达
例:
<span v-html="messagehtml"></span>
<script>
new Vue({
el:'#app',
data: {
message: '文本内容',
messagehtml: `
<span style="color: red">这段颜色是红色的</span>
`,
}
})
</script>
指令:v-text
含义: v-text结果和插值表达式 是一样的
例:
<span v-text="messagehtml"></span>
插值表达式支持JavaScript表达式的使用
<!-- 算数运算符 -->
<div>
number+1运算: {{number + 1}}
</div>
<!-- 三元运算符 -->
<div>
三元运算符:{{ ok ? "yes" : "no" }}
</div>
<!-- 函数运算 -->
<div>
<!-- 翻转 -->
{{message.split('').reverse().join('')}}
</div>
<!-- 绑定的都只能包含单个表达式 -->
<!-- {{ let a = 1}} -->
3、动态参数
指令: :[]=’’
举例:
<p :[name]='value'>测试动态参数</p><script> const app = new Vue({ el: '#app', data () { name = '李白', value = '嘿嘿~' } })</script>
4、条件渲染
1、v-if v-else-if v-else
不可见的元素包裹
key:用于管理可复用元素的
2、v-show
注意:不支持template,也不支持v-else
区别:
1. v-show 只是简单的控制元素的 display 属性,而 v-if 才是条件渲染(条件为真,元素将会被渲染,条件为假,元素会被销毁);2. v-show 有更高的初始渲染开销(频繁切换,建议使用 v-show),而 v-if 的首次渲染开销要小的多;3. v-if 有更高的切换开销,v-show 切换开销小;4. v-if 有配套的 v-else-if 和 v-else,而 v-show 没有5. v-if 可以搭配 template 使用,而 v-show 不行6. v-if 是惰性的,出事条件什么都不做,当第一次为真,才开始条件渲染7. v-show 不管出事条件是什么,元素一直被渲染,基于css进行切换,display注意: 不推荐v-if和v-for一起使用(v-for优先级高一点)
5、语法糖
v-on
===》@
<button @click='func(‘hello’, $event)>
v-bind
===》:
动态设置
<button @[event]='value'>
const app = new Vue({ el: '#app', data: { message: 'hello' }, methods: { func(message, event) { } }})访问原始dom事件
6、事件修饰符
1、stop 阻止冒泡事件
<div @click=''> <button @click.stop='func'>...</button></div>
2.prevent 阻止默认事件
<@click.prevent>3.Once 只允许点击一次
4、keyup
5、enter
6、delete
7.计算属性
{{reverse}}computed:{ reverse(){ return this.message。split('').reverse().join('') }}
计算和方法的区别:
计算属性是基于他们的响应式依赖进行缓存的,只有相关响应式依赖发生改变时,他们才会重新求值。
方法是多次执行的
//方法methods: { reversedMessage: function () { return this.message.split('').reverse().join('') }}//计算属性computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } }
8、侦听属性
用来侦听某个属性是不是变化的
const app = new Vue({ el: '#app', data: { message: 'hello' },methods: { reversedMessage: function () { return this.message.split('').reverse().join('') }}//计算属性computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } //侦听属性 watch: { message(val,oldval){ } list{ Handle(val,oldval){ }, deep:true } }})
9、class
v-bind:class=‘red’
对象语法
:class = “{key:value}”
数组语法
:class=’[key,value]’
数组语法可以用三元表达式
:class=’[‘isRed’?red : green]’
10、style
style优先级高于class
style 的普通使用
<h2 :style='colorRed'>hello world</h2>
style的对象语法
<h2 :style='{isRed: color}'></h2>color是data中的数据
style的数组语法
<h2 :style='[color,font]'></h2>data() { return { color: {color:red}, font: {fontSize:28px} }}
11、v-for
data: { array:[ {text:'aaaaa'}, {text:'bbbbb'}, ]}//顺序是固定的,名字可变this.array.foreach((item, index, data) ==> {})
v-for:数组、对象、数字
数组
<h2 v-for='item in array'></h2>
对象
data:{ object: { title:'标题', author:'作者' }}//注意不能保证拿到的值和数据源的顺序是一致的//value<p v-for='value in object'></p><p v-for='(value,key) in object'></p><p v-for='(value,key,index) in object'></p>
就地更新
当数据循序改变时,只是元素显示的索引正确,但并没有真正的更新到DOM中。
解决方案:绑定key属性,尽量使用字符串或数值类型
<p v-for='(value,key,index) in object' :key='index'></p>
数字
循环十次,number从1开始,index从0开始
<p v-for='number in 10'></p>
<p v-for='(number,index) in 10'></p>
v-for不能与v-if同时使用
v-for优先级高于v-if
解决办法:
先处理数据再v-for
computed:{}
12、表单输入
文本
<input v-model='message'></input>data: { message: ''}相当于两个指令的集合1. :value='message'2. @input='message=$event.target.value'
多行文本
<textarea v-model='message'> {{message}} //不起作用</textarea>
复选框
<input type='checkbox' id='chx' v-model='checked'></input><label>{{checked}}</label>data: { checked: false}
多个复选框
<input type='checkbox' id='chx' v-model='checked'></input>//for规定label与哪个表单元素进行绑定<label for='chx'>{{checked}}</label>data: { checked: []}
三、生命周期
1、创建阶段
beforCreate() {}
created(){}
beforMount(){}
mounted(){}
2、更新阶段
beforupdate(){}
update(){}
3、销毁阶段
beforDestory(){}
Destory(){}
// 第一个声明周期的钩子函数 beforeCreate() { console.log(this.show); this.show() }, created() { console.log(this.show); this.show() }, //第三个生命周期,模板已经渲染,但还没有挂载到页面上 beforeMount() { console.log(document.getElementById('hh').innerText); }, //内存中模板替换到页面中 mounted() { console.log(document.getElementById('hh').innerText); }, //mounted执行完毕之后,vue实例已经创建完成。 //beforupdate,页面没有更新,但是数据更新了 beforUpdate() { console.log(document.getElementById('hh').innerText); console.log(this.message); }, //页面和数据都已经更新了 update() { console.log(document.getElementById('hh').innerText); console.log( 'message' ,this.message); }, //销毁阶段 //第七个生命周期函数,所有的data和methods,指令、、、都处于可用,尚未销毁 beforeDestroy() { }, //一切都没了 Destroy() {}
四、组件
父子组件传值
父组件向子组件传值:props:{ ‘ list’ : Array}
子组件向父组件传值:
//不带参数
this.$emit(‘delete’)
this.$emit(‘delete’, index)
1、修饰符
.lazy 懒加载
.number 数字
. stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递)
. prevent:阻止默认事件的发生
. capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自 然顺序执行触发的事件。
. self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响
. once:设置事件只能触发一次,比如按钮的点击等。
. passive:该修饰符大概意思用于对DOM的默认事件进行性能优化,根据官网的例子比如超出最大范围的滚动条滚动的 方法,可以使用该修饰符进行加强,但是效果并没有感觉到。
2、全局组件:
<div id="app"> <com1></com1> <com2></com2> <com3></com3></div><template id="temp"> <div> <h2>com3子组件</h2> </div></template><script> //第一种组件的创建 Vue.component('com1',{ template: ` <div> <h2> com1子组件 </h2> </div> `, }) // 第二种,组件创建 extend let extend2 = Vue.extend({ template: ` <div> <h2> com1子组件 </h2> </div> `, }); Vue.component('com2',extend2) // 第三种 Vue.component('com3',{ template: '#temp' }) /*共同点Vue.component注册是全局 */ const app = new Vue({ el:'#app', data: { message:'你好啊!' } });</script>
3、局部组件:
<div id="app"> <local-tag/></div><script> // 1、创建局部组件 let LocalTag = { template: ` <div> <h2>吧唧吧唧吧唧</h2> <p>红红火火恍恍惚惚</p> </div>` }; const app = new Vue({ el:'#app', components: { // 'local-tag':LocalTag LocalTag } });
4、组件的命名方式:
大小写不敏感,若大写,大写变小写,中间加“-”,不建议使用驼峰式命名法
5、组件的切换:
1.v-if
2.v-show
3.component — is–是用来展示组件名称的
<component is=''></component>
6、prop单项数据流
只可父传子,子传父不改变父值
7、子组件之间的传值
/*全局注册bus $bus自定义*/Vue.prototype.$bus = new Vue()
mounted() { /*接收数据,event接收发送必须一致*/ this.$bus.$on('search',(val) => { if (val) { this.isShow = true; }else { this.isShow = false; } this.msg = [] // console.log(val) /*查找*/ /** *取出key search=['A','B'] * */ const array = Object.keys(this.cities) array.forEach(value => {/* 获取cities key 后面的value 根据key 获取value value 进行查找*/ const temp = this.cities[value].find(item => { return item.spell.indexOf(val) !== -1 }) // console.log(temp); if (temp) { this.msg.push(temp) } }) }) }
watch:{ /*侦听ipt是否有变化*/ ipt (val) { /*变化的数据发送到citysearch*/ // console.log(val); this.$bus.$emit('search', val) } },
五、弹性布局
flex初解
https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
任何一个容器都可以指定为flex布局
.box{ display: flex;}
行内元素也可以加载flex布局
.box{ display: inline-flex;}
Webkit 内核的浏览器,必须加上-webkit
前缀。
.box{ display: -webkit-flex; /* Safari */ display: flex;}
注意,设为 Flex 布局以后,子元素的float
、clear
和vertical-align
属性将失效。
flex项目属性
* flex-direction 决定主轴方向(row,colum)* flex-wrap 决定是否换行(wrap,nowrap)* flex-flow 对flex-direction和flex-wrap的缩写* justify-content 定义了项目在主轴上的对齐方式* align-items 定义了在交叉轴上的对齐方式* align-content 多根周线的对齐方式(一根不起作用)
flex-direction
flex-direction属性决定主轴的方向(即项目的排列方向)
flex-direction: row (默认值):主轴为水平方向,起点在左端。flex-direction: row-reverse 主轴为水平方向,起点在右端flex-direction: colum 主轴为垂直方向,起点在上沿flex-direction: colum-reverse 主轴为垂直方向,起点在下沿
flex-wrap
默认情况下,flex都排在一条线上,flex-wrap定义,若一条轴线放不下,应如何换换行
flex-wrap: nowrap (默认值):不换行flex-wrap: wrap 换行,第一行在上方flex-wrap: wrap-reverse 换行,第一行在下方
flex-flow
flex-flow是 flex-direction 和flex-wrap 的简写形式
flex-flow: flex-direction || flex-wrap
例:
flex-flow: row wrap 主轴水平,且正常换行
justify-content
justify-content定义了flex在主轴上的对齐方式
justify-content: flex-start (默认值) : 左对齐justify-content: center 居中justify-content: flex-end 右对齐justify-content: space-between 两端对齐,flex之间的间隔都相等justify-content: space-evenly 每个间隔均分空间justify-content: space-around 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items
align-items定义在交叉轴上如何对齐
align-items: flex-startalign-items: flex-endalign-items: centeralign-items: baseline 项目的第一行文字的基线对齐。align-items: stretch 默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content
align-content定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
flex-start:与交叉轴的起点对齐。flex-end:与交叉轴的终点对齐。center:与交叉轴的中点对齐。space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch(默认值):轴线占满整个交叉轴。
项目属性
order 负责控制子元素的顺序flex-grow 定义项目的放大比例,默认为`0`,即如果存在剩余空间,也不放大。flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。flex-basis 定义了在分配多余空间之前,项目占据的主轴空间(main size)flex `flex`属性是`flex-grow`, `flex-shrink` 和 `flex-basis`的简写,默认值为`0 1 auto`。后两个属性可选。align-self
order
order
属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item { order: <integer>;}
flex-grow
flex-grow
属性定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。
.item { flex-grow: <number>; /* default 0 */}
注意:如果所有项目的flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
flewx-shrink
定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item { flex-shrink: <number>; /* default 1 */}
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
flex-basis
定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。
.item { flex-basis: <length> | auto; /* default auto */}
flex
flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。
.item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]}
注意
该属性有两个快捷值:auto
(1 1 auto
) 和 none (0 0 auto
)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
align-self
align-self
属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;}
注意:该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
六、项目开发
git
Git 全局设置:
git config --global user.name "Hao_Delin"git config --global user.email "hao13869663325@163.com"
创建 git 仓库:
mkdir mall(仓库名)cd mall(仓库名)git inittouch README.mdgit add README.mdgit commit -m "first commit"git remote add origin https://gitee.com/hao-delin/mall.git(仓库名)git push -u origin master
已有仓库?
cd existing_git_repogit remote add origin https://gitee.com/hao-delin/mall.git(仓库名)git push -u origin master
git操作命令合集
1、查看并清理本地是否干净
git status
2、创建并切换子分支
git checkout -b login(子分支名)
3、查看本地分支
git branch
4、初始化当前目录为本地仓库
git init
5、添加本地代码指令
git add .
6、提交代码到云端仓库
git commit -m
7、创建本地xxx分支
git branch xxx
8、切换到本地xxx分支
git checkout xxx
9、合并当前本地分支和xxx分支
git merge xxx
参数传递
1、相当于a标签,to 路由跳转的地址
<router-link to='/about'>连接到about</router-link>
2、嵌套路由–占位符
<router-view></router-view>
3、参数的传递 to里边是对象,to动态绑定 :to
name:‘ ’, params:{}
数值的传递
<router-link to='/about/123/标题是title'>连接到about</router-link>
<router-link to='{name: 'about'. params: {name: '小苏', id: '123456'}}'>连接到about</router-link>
获取数据的传递 params !!!$route!!!
{{$route.params.name}} ---{{$route.params.id}}
4、url传递参数
{ path: '/about/:uid/:title'}
获取url上的参数
{{$route.params.uid}} ---{{$route.params.title}}
5、前进后退返回首页
goback() { /*number 前进或后退的步数*/ this.$router.go(-1) // 或者 this.$router.back()}go() { /*number 前进或后退的步数*/ this.$router.go(1)}gohome() { /*number 前进或后退的步数*/ this.$router.push('/login') /*或者*/ this.$router.push({ path: '/' })}
七、Axios的使用
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
安装
npm install --save axios vue-axios
使用
import axios from 'axios'import VueAxios from 'vue-axios'Vue.use(axios, VueAxios)
案例
1、执行 GET
请求
// 为给定 ID 的 user 创建请求axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });// 上面的请求也可以这样做axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
2、执行 POST
请求
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
3、执行多个并发请求
function getUserAccount() { return axios.get('/user/12345');}function getUserPermissions() { return axios.get('/user/12345/permissions');}axios.all([getUserAccount(), getUserPermissions()]) .then(axios.spread(function (acct, perms) { // 两个请求现在都执行完成 }));
Axios API
可以通过向 axios
传递相关配置来创建请求
axios(config)
// 发送 POST 请求axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' }});
// 获取远端图片axios({ method:'get', url:'http://bit.ly/2mTM3nY', responseType:'stream'}) .then(function(response) { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))});
axios(url[, config])
// 发送 GET 请求(默认的方法)axios('/user/12345');
axios请求方法的别名
为方便起见,为所有支持的请求方法提供了别名axios.request(config)axios.get(url[, config])axios.delete(url[, config])axios.head(url[, config])axios.options(url[, config])axios.post(url[, data[, config]])axios.put(url[, data[, config]])axios.patch(url[, data[, config]])注意在使用别名方法时, url、method、data 这些属性都不必在配置中指定。
并发
处理并发请求的助手函数
##### axios.all(iterable)##### axios.spread(callback)
创建实例
可以使用自定义配置新建一个 axios 实例
axios.create([config])
const instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'}});
1、实例方法
以下是可用的实例方法。指定的配置将与实例的配置合并。
axios#request(config)axios#get(url[, config])axios#delete(url[, config])axios#head(url[, config])axios#options(url[, config])axios#post(url[, data[, config]])axios#put(url[, data[, config]])axios#patch(url[, data[, config]])
2、请求配置
这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法。{ // `url` 是用于请求的服务器 URL url: '/user', // `method` 是创建请求时使用的方法 method: 'get', // default // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。 // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL baseURL: 'https://some-domain.com/api/', // `transformRequest` 允许在向服务器发送前,修改请求数据 // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法 // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream transformRequest: [function (data, headers) { // 对 data 进行任意转换处理 return data; }], // `transformResponse` 在传递给 then/catch 前,允许修改响应数据 transformResponse: [function (data) { // 对 data 进行任意转换处理 return data; }], // `headers` 是即将被发送的自定义请求头 headers: {'X-Requested-With': 'XMLHttpRequest'}, // `params` 是即将与请求一起发送的 URL 参数 // 必须是一个无格式对象(plain object)或 URLSearchParams 对象 params: { ID: 12345 }, // `paramsSerializer` 是一个负责 `params` 序列化的函数 // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/) paramsSerializer: function(params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // `data` 是作为请求主体被发送的数据 // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' // 在没有设置 `transformRequest` 时,必须是以下类型之一: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - 浏览器专属:FormData, File, Blob // - Node 专属: Stream data: { firstName: 'Fred' }, // `timeout` 指定请求超时的毫秒数(0 表示无超时时间) // 如果请求话费了超过 `timeout` 的时间,请求将被中断 timeout: 1000, // `withCredentials` 表示跨域请求时是否需要使用凭证 withCredentials: false, // default // `adapter` 允许自定义处理请求,以使测试更轻松 // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)). adapter: function (config) { /* ... */ }, // `auth` 表示应该使用 HTTP 基础验证,并提供凭据 // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头 auth: { username: 'janedoe', password: 's00pers3cret' }, // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' responseType: 'json', // default // `responseEncoding` indicates encoding to use for decoding responses // Note: Ignored for `responseType` of 'stream' or client-side requests responseEncoding: 'utf8', // default // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称 xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` is the name of the http header that carries the xsrf token value xsrfHeaderName: 'X-XSRF-TOKEN', // default // `onUploadProgress` 允许为上传处理进度事件 onUploadProgress: function (progressEvent) { // Do whatever you want with the native progress event }, // `onDownloadProgress` 允许为下载处理进度事件 onDownloadProgress: function (progressEvent) { // 对原生进度事件的处理 }, // `maxContentLength` 定义允许的响应内容的最大尺寸 maxContentLength: 2000, // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte validateStatus: function (status) { return status >= 200 && status < 300; // default }, // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目 // 如果设置为0,将不会 follow 任何重定向 maxRedirects: 5, // default // `socketPath` defines a UNIX Socket to be used in node.js. // e.g. '/var/run/docker.sock' to send requests to the docker daemon. // Only either `socketPath` or `proxy` can be specified. // If both are specified, `socketPath` is used. socketPath: null, // default // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项: // `keepAlive` 默认没有启用 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy' 定义代理服务器的主机名称和端口 // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据 // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。 proxy: { host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } }, // `cancelToken` 指定用于取消请求的 cancel token // (查看后面的 Cancellation 这节了解更多) cancelToken: new CancelToken(function (cancel) { })}
3、响应结构
某个请求的响应包含以下信息
{ // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 服务器响应的头 headers: {}, // `config` 是为请求提供的配置信息 config: {}, // 'request' // `request` is the request that generated this response // It is the last ClientRequest instance in node.js (in redirects) // and an XMLHttpRequest instance the browser request: {}}
使用 then
时,你将接收下面这样的响应 :
axios.get('/user/12345') .then(function(response) { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); 在使用 catch 时,或传递 rejection callback 作为 then 的第二个参数时,响应可以通过 error 对象可被使用
配置默认值
1、全局的 axios 默认值
axios.defaults.baseURL = 'https://api.example.com';axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
2、自定义实例默认值
// Set config defaults when creating the instanceconst instance = axios.create({ baseURL: 'https://api.example.com'});// Alter defaults after instance has been createdinstance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
3、配置的优先顺序
配置会以一个优先顺序进行合并。这个顺序是:在 lib/defaults.js
找到的库的默认值,然后是实例的 defaults
属性,最后是请求的 config
参数。后者将优先于前者。这里是一个例子:
// 使用由库提供的配置的默认值来创建实例// 此时超时配置的默认值是 `0`var instance = axios.create();// 覆写库的超时默认值// 现在,在超时前,所有请求都会等待 2.5 秒instance.defaults.timeout = 2500;// 为已知需要花费很长时间的请求覆写超时设置instance.get('/longRequest', { timeout: 5000});
拦截器
在请求或响应被 then
或 catch
处理前拦截它们。
// 添加请求拦截器axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); });// 添加响应拦截器axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });
如果你想在稍后移除拦截器,可以这样:
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});axios.interceptors.request.eject(myInterceptor);
可以为自定义 axios 实例添加拦截器
const instance = axios.create();instance.interceptors.request.use(function () {/*...*/});
错误处理
axios.get('/user/12345') .catch(function (error) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js console.log(error.request); } else { // Something happened in setting up the request that triggered an Error console.log('Error', error.message); } console.log(error.config); });
Y可以使用 validateStatus
配置选项定义一个自定义 HTTP 状态码的错误范围。
axios.get('/user/12345', { validateStatus: function (status) { return status < 500; // Reject only if the status code is greater than or equal to 500 }})
取消
使用 cancel token 取消请求
Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。
1、可以使用 CancelToken.source
工厂方法创建 cancel token,像这样:
const CancelToken = axios.CancelToken;const source = CancelToken.source();axios.get('/user/12345', { cancelToken: source.token}).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // 处理错误 }});axios.post('/user/12345', { name: 'new name'}, { cancelToken: source.token})// 取消请求(message 参数是可选的)source.cancel('Operation canceled by the user.');
2、还可以通过传递一个 executor 函数到 CancelToken
的构造函数来创建 cancel token:
const CancelToken = axios.CancelToken;let cancel;axios.get('/user/12345', { cancelToken: new CancelToken(function executor(c) { // executor 函数接收一个 cancel 函数作为参数 cancel = c; })});// cancel the requestcancel();注意: 可以使用同一个 cancel token 取消多个请求
八、Vuex

安装
npm install vuex --save
导入
import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)
方法解释
相当于datastate: { currentcity: { id:'1', name: '北京' }}同步。存放修改state中数据的方法mutation: { setcurrentcity(state,payload) { state.currentcity = payload }}异步。action:{}模块modules: {}
向vuex中传值
(推荐使用通过mapState传递)
import {mapState} from ‘vuex'modules: { handele() { /**第一个,方法名 第二个,数据 */ this.$store.commit('currentcity',item)}}
从vuex获取数值
(使用computed计算属性从vuex中拿取)
computed: { ...mapState{'currentcity'}}
九、小技巧
1、获取对象key值
cities: {}letters: []this.letters = Object.keys(this.cities)
2、动态绑定数值–cacl计算属性
:style="{ 'width' : 'calc(100%/'+ num +')'}"
3、对象循环遍历
cities: { [], []}v-for='(value,key,index)' in cities :key='index'// 若想获取对象里面集合的数据 v-for='item in value'
4、数组循环遍历
letter: []v-for= 'item in letter'
5、v-for遍历数组截取一部分
<div class="container-hd" v-for="item in iconList.slice(0,8)" :key="item.id" > <div class="item-img" :style="{'background-image':'url(' + item.imgUrl +')'}"></div> <span>{{ item.desc }}</span> </div>
6、让文本框自动获得焦点
$nextTick 方法的作用 就是当页面上元素被重新渲染之后才会执行回调函数中的代码
this.$nextTick(_ => { this.$refs.saveTagInput.$refs.input.focus() })
7、格式化时间处理全局定义
Vue.filter('dataFormat', function (originVal) { const dt = new Date(originVal) const y = dt.getFullYear() const m = (dt.getMonth() + 1 + ' ').padStart(2, '0') const d = (dt.getDate() + ' ').padStart(2, '0') const hh = (dt.getHours() + ' ').padStart(2, '0') const mm = (dt.getMinutes() + ' ').padStart(2, '0') const ss = (dt.getSeconds() + ' ').padStart(2, '0') return `${y}-${m}-${d} ${hh}:${mm}:${ss}`})
调用 <el-table-column label="创建时间" prop="add_time" width="140px"> <template slot-scope="scope"> {{scope.row.add_time | dataFormat}} </template> </el-table-column>
8、字符串变数组
res.data.forEach(*item* => { *item*.attr_vals = *item*.attr_vals.length === 0 ? [] : *item*.attr_vals.split('') })
9、深拷贝
https://www.lodashjs.com/
安装
npm i --save lodash
使用
<script>import _ from 'lodash'export default { data () {
// 深拷贝 lodash cloneDeep(obj) const form = _.cloneDeep(this.addForm) form.goods_cat = form.goods_cat.join(',')
10、富文本编辑器引入
vue-quill-editor
安装
npm install vue-quill-editor --save
全局使用
import Vue from 'vue'import VueQuillEditor from 'vue-quill-editor'// require stylesimport 'quill/dist/quill.core.css'import 'quill/dist/quill.snow.css'import 'quill/dist/quill.bubble.css'Vue.use(VueQuillEditor, /* { default global options } */)
文件调用
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
11、数组转字符串
form.goods_cat = form.goods_cat.join(',')
十、ES6、新特性总结
1. let const
let 表示申明变量。const 表示申明常量。
- 常量定义了就不能改了。对象除外,因为对象指向的地址没变。
- const在申明是必须被赋值。
- 两者都为块级作用域。
块级作用域与函数作用域。任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。函数作用域就好理解了,定义在函数中的参数和变量在函数外部是不可见的。
const a = 1a = 0 //报错
2. 模块字符串``
可以使用反引号````来进行字符拼接。${}
3. 解构
可以使用{}来对数组和对象进行解构。
4. 函数的参数默认值
函数传参可以有默认值
// ES6;function printText(text = 'default') { console.log(text);}
5. Spread / Rest 操作符...
Spread / Rest 操作符指的是 …,具体是 Spread 还是 Rest 需要看上下文语境。
- 当被用于迭代器中时,它是一个 Spread 操作符:迭代器 (Iterator)是按照一定的顺序对一个或多个容 器 中的元素行进遍历的一种机制
function foo(x,y,z) { console.log(x,y,z);} let arr = [1,2,3];foo(...arr); // 1 2 3
- 当被用于函数传参时,是一个 Rest 操作符:当被用于函数传参时,是一个 Rest 操作符:
function foo(...args) { console.log(args);}foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
6. 箭头函数
- 箭头函数中没有this
- 不需要 function 关键字来创建函数
- 省略 return 关键字
- this始终指向函数申明时所在作用域下的this值
//es5var fun = function() {}//es6var fn = () => {}
7. for of
- for of遍历的是键值对中的值
- for in遍历的是键值对中的键
8. class类
ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。
class Student { constructor() { console.log("I'm a student."); } study() { console.log('study!'); } static read() { console.log("Reading Now."); }} console.log(typeof Student); // functionlet stu = new Student(); // "I'm a student."stu.study(); // "study!"stu.read(); // "Reading Now."
9. 导入导出
- 导入improt
- 导出export default
10. promise
Promise 用于更优雅地处理异步请求。
<script> new Promise((resolve,reject) => { setTimeout(function() { resolve('成功了!') },1000) // reject("失败了,wuwu") }).then(data => { console.log(data) }).catch(err => { console.log(err) }) </script>
11. async/await
比promise更好的解决了回调地狱。
async function() { awiat fn()}
12. Symbol
新的基本类型
13. Set集合
存储任何类型的唯一值,即集合中所保存的元素是不重复的。类数组结构。
arr = [1,2,3,1]let arrNew = new Set(arr)arrNew = [1,2,3]
类数组不是数组,要转化为数组Array.form(arrNew)
这样arrNew才是数组了
十一、Js的宏任务和微任务
宏任务
(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个(macro)task执行结束后,在下一个(macro)task 执行开始前,对页面进行重新渲染,流程如下:
(macro)task->渲染->(macro)task->...
宏任务包含:
script(整体代码)setTimeoutsetIntervalI/OUI交互事件postMessageMessageChannelsetImmediate(Node.js 环境)
微任务
microtask,可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。
所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。
微任务包含:
Promise.thenObject.observeMutationObserverprocess.nextTick(Node.js 环境)
运行机制
在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:
执行一个宏任务(栈中没有就从事件队列中获取)执行过程中如果遇到微任务,就将它添加到微任务的任务队列中宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
同步与异步、宏任务和微任务分别是函数两个不同维度的描述。
异步任务:setTimeout和setInterval、ajax、事件绑定等
同步任务:除了异步任务外的所有任务
微任务:process.nextTick和 Promise后的theny语句和catch语句等
宏任务:除了微任务以外的所有任务
执行顺序判断方法
先同步再异步,在此基础上先宏任务再微任务