個(gè)人公眾號(hào)做網(wǎng)站網(wǎng)店推廣培訓(xùn)
一、腳手架配置代理
1.回顧常用的ajax發(fā)送方式:
(1)xhr
比較麻煩,不常用
(2)jQuery
核心是封裝dom操作,所以也不常用
(3)axios
優(yōu)勢(shì):體積小、是promise風(fēng)格的、支持請(qǐng)求攔截器和響應(yīng)攔截器
(4)fetch
2.3都是封裝xhr的,fetch跟xhr平級(jí),直接在window身上就能找到,而且也是promise風(fēng)格的,但是不兼容,ie肯定不能用;它會(huì)把你返回的數(shù)據(jù)包兩層,所以不如axios常用。
2.引出問題
點(diǎn)擊按鈕獲取學(xué)生信息,app.vue:
import axios from 'axios'
import { response } from 'express'
export default {
name:'App',
methods:{getStudent(){axios.get('http://localhost:5000/students'),then(response=>{console.log('請(qǐng)求成功了',response.data)//response是一個(gè)響應(yīng)對(duì)象。data里面的東西才是response想給你的},error=>{console.log('請(qǐng)求失敗了',error.message)//maeeage失敗的原因})}
}
}
點(diǎn)擊按鈕之后頁(yè)面報(bào)錯(cuò),出現(xiàn)、、、cors、、、Access-Control-Allow-Oringin說明跨域了,協(xié)議、域名、端口號(hào)出現(xiàn)不一樣的,我們所在的端口號(hào)是8080,向端口號(hào)5000的要數(shù)據(jù),5000給8080了,然后8080發(fā)現(xiàn)跨域了就沒有給你數(shù)據(jù),解決跨域的問題:
1.cors(寫服務(wù)器的人在服務(wù)器加幾個(gè)響應(yīng)頭)
5000返回的時(shí)候還攜帶幾個(gè)特殊的響應(yīng)頭,8000看見就給你了
2.jsonp(借助script 的src屬性)
src屬性在引入外部資源的時(shí)候不受同源限制,但是得前端后端一起配合,而且它只能解決get請(qǐng)求的問題,開發(fā)不常用但是面試經(jīng)常問,很巧妙的用法
3.配置一個(gè)代理服務(wù)器
代理服務(wù)器是一個(gè)中間人,但是它所處的位置跟我們一樣(8080),粉色那個(gè)跟我們肯定是同域的,那粉色跟藍(lán)色呢?他倆都是服務(wù)器,服務(wù)器和服務(wù)器之間傳輸局不用ajax,用的就是http傳就完事了。那粉色的8080服務(wù)器得怎么開啊?1.nginx,學(xué)習(xí)成本大偏后端? 2.vue-cli,借助vue腳手架。
然后我們就來配置一下代理服務(wù)器
(1)方式一:
在vue.config.js:
它的8080不用你管,你只需要告訴這個(gè)代理服務(wù)器一會(huì)要把請(qǐng)求轉(zhuǎn)發(fā)給誰(shuí)就ok,后面具體路徑不用寫,寫到端口號(hào)就行
//開啟服務(wù)代理
devServer:{proxy:'htp://localhost:5000'
}
app.vue
methods:{getStudent(){axios.get('http://localhost:8080/students').then(response=>{console.log('請(qǐng)求成功了',response.data)//response是一個(gè)響應(yīng)對(duì)象。data里面的東西才是response想給你的},error=>{console.log('請(qǐng)求失敗了',error.message)//maeeage失敗的原因})}
}
而且這個(gè)中間代理也不是什么時(shí)候都會(huì)轉(zhuǎn)發(fā)請(qǐng)求的,如果粉色的自己本身就有就不會(huì)往5000找了,public里面文件都算是8080有的。
1、優(yōu)點(diǎn):配置簡(jiǎn)單,請(qǐng)求資源時(shí)直接發(fā)給前端(8080)即可。
2、缺點(diǎn):不能配置多個(gè)代理,不能靈活的控制請(qǐng)求是否走代理。
3、工作方式:若按照上述配置代理,當(dāng)請(qǐng)求了前端不存在的資源時(shí),那么該請(qǐng)求會(huì)轉(zhuǎn)發(fā)給服務(wù)器 (優(yōu)先匹配前端資源)。
(2)方式二
vue.config.js:
devServer:{proxy:{'/ttt':{ //請(qǐng)求前綴,想走代理就在請(qǐng)求的前面加/???,就把東西轉(zhuǎn)發(fā)給targettarget:'http://localhost:5000',pathRewrite:{'^/ttt':''},//不加這個(gè)配置粉色找藍(lán)色的時(shí)候默認(rèn)找的/ttt/server1ws:true ,//用于支持websocketchangeOrigin:true//用于控制請(qǐng)求頭的host值//這個(gè)是告訴5000我也來自5000(是true就撒謊來自5000,false就是來自8080),防止5000用不了設(shè)置true比較好},'/hhh':{ target:'http://localhost:5001',pathRewrite:{'^/hhh':''},ws:true ,changeOrigin:true},}
}
app:
getStudent(){axios.get('http://localhost:8080/ttt/students').then(//前綴就加在端口號(hào)后面,后面正常寫response=>{console.log('請(qǐng)求成功了',response.data)//response是一個(gè)響應(yīng)對(duì)象。data里面的東西才是response想給你的},error=>{console.log('請(qǐng)求失敗了',error.message)//maeeage失敗的原因})},getCar(){axios.get('http://localhost:8080/hhh/cars').then(//前綴就加在端口號(hào)后面,后面正常寫response=>{console.log('請(qǐng)求成功了',response.data)//response是一個(gè)響應(yīng)對(duì)象。data里面的東西才是response想給你的},error=>{console.log('請(qǐng)求失敗了',error.message)//maeeage失敗的原因})}
如果我自己也有個(gè)students它也不會(huì)來拿我這個(gè)信息,因?yàn)榧恿?ttt就強(qiáng)制去5000那里拿數(shù)據(jù)了,所以這種就更靈活。
1、優(yōu)點(diǎn):可以配置多個(gè)代理,且可以靈活的控制請(qǐng)求是否走代理。
2、缺點(diǎn):配置略微繁瑣,請(qǐng)求資源時(shí)必須加前綴。
二、github案例
如果第三方庫(kù)你寫在assets里面了就得用import 引用,用import引用會(huì)很嚴(yán)重的檢查,有某些字體你沒有但是你引用了那就顯示不出來,但是link方法沒事,你沒有但是引用了就不顯示唄
所以像這種引入了外部資源的就不適合用assets/css/里面,那就放在public/css,然后在index.html中l(wèi)ink引用一下,他里面引用了app也能用
接口https雖然案例來說跨域了,但是人家的工程師用cors已經(jīng)解決了不用我們擔(dān)心
list首先展示歡迎,用戶搜索之后顯示 正在加載中 ,加載完畢顯示users,加載失敗顯示error
那怎么判斷該顯示啥呢?數(shù)據(jù)驅(qū)動(dòng)頁(yè)面展示
1.app.vue
<template><div class="container"><mySearch /><myList /></div>
</template><script>
import mySearch from "./components/mySearch.vue";
import myList from "./components/myList.vue";
export default {name: "App",components: { mySearch, myList },
};
</script><style>
</style>
2.myList.vue
<template><div class="row"><divv-show="info.users.length"class="card"v-for="user in info.users":key="user.login"><a :href="user.html_url" target="_blank"><img :src="user.avatar_url" style="width: 100px" /><!-- 頭像地址 --></a><p class="card-text">{{ user.login }}</p><!-- 用戶名 --></div><!-- 歡迎詞 --><h1 v-show="info.isFirst">歡迎!</h1><!-- 加載中 --><h1 v-show="info.isLoading">加載中······</h1><!-- 錯(cuò)誤信息 --><h1 v-show="info.errMsg">{{ info.errMsg }}</h1><!-- 都一樣就不一個(gè)一個(gè)寫了,但是這次也不用item,直接v-for --></div>
</template><script>
export default {name: "myList",data() {return {info: {isFirst: true, //是不是初次展示isLoading: false, //點(diǎn)擊按鈕之后才加載errMsg: "", //不能用布爾值了,得看看是網(wǎng)差還是別的原因呢導(dǎo)致的users: [],//這些東西都得聽search的,情況不同他們幾個(gè)值也變},};},mounted() {this.$bus.$on('updateListData', (dataObj) => {this.info={...this.dataObj,...dataObj}//es6規(guī)則,倆人都有的按后邊來,前面沒有的要后面的//這里不要this.data=dataObj,更不能this._data,賦值過去動(dòng)了原本配置的getter、setter});},
};
</script><style scoped>
.album {min-height: 50rem; /* Can be removed; just added for demo purposes */padding-top: 3rem;padding-bottom: 3rem;background-color: #f7f7f7;
}.card {float: left;width: 33.333%;padding: 0.75rem;margin-bottom: 2rem;border: 1px solid #efefef;text-align: center;
}.card > img {margin-bottom: 0.75rem;border-radius: 100px;
}.card-text {font-size: 85%;
}
</style>
3.mySearch.vue
<template><section class="jumbotron"><h3 class="jumbotron-heading">Search Github Users</h3><div><inputtype="text"placeholder="enter the name you search"v-model="keyword"/> <button @click="searchUsers">Search</button></div></section>
</template><script>
import axios from 'axios'
//import { response } from 'express';
export default {name:'mySearch',data(){return {keyword:''}},methods:{searchUsers(){//請(qǐng)求前更新list的數(shù)據(jù)this.$bus.$emit('updateListData',{isFirst:false,isLoading:true,errMsg:'',users:[]})axios.get(`https://api.github.com/search/users?q=${this.keyword}`).then(response=>{this.$bus.$emit('updateListData',{isLoading:false,errMsg:'',users:response.data.items})// 就最開始?xì)g迎一下,之后就不用了,但是直接不寫之后就少一個(gè)屬性,用es6語(yǔ)法解決console.log('請(qǐng)求成功',response.data.items)this.$bus.$emit('getUsers',response.data.items)},error=>{this.$bus.$emit('updateListData',{isLoading:false,errMsg:error.message,users:[]})console.log('請(qǐng)求失敗',error.message)})// 直接等于this.??他肯定不按js給你解析,模版字符串然后$}}
};
</script><style>
</style>
4.vue-resource
也是對(duì)xhr的封裝,安裝插件?:npm i vue-resource
就是把a(bǔ)xios替換成了this.$http,其他的都一樣
main.js引入插件:import vueResource from 'vue-resource'
使用插件:Vue.use(vueResource)
維護(hù)的不頻繁用的不多
三、插槽
1.默認(rèn)插槽
如果我想在最小的組件(重復(fù)的)的其中一個(gè)里面添加圖片,和其他組件都不一樣的話,我直接在<category> <img、、、></category>這樣寫出不來圖片,因?yàn)槿思医馕龅絠mg之后不知道來到category.vue里人家就不知道把img給你放哪兒了。
用一個(gè)特殊的標(biāo)簽slot,告訴人家識(shí)別完不知道放哪兒的標(biāo)簽放在哪個(gè)位置
(1)app.vue
<template><div class="container"><myCategory title="美食"><img src="http://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="" /></myCategory><myCategory title="游戲"><ul><li v-for="(g, index) in games" :key="index">{{ g }}</li></ul></myCategory><!-- 這三個(gè)的樣式都是解析完之后才塞到myCategory里面去的,所以script可以直接寫在app里 --><myCategory title="電影"><videocontrolssrc="http://clips.vorwaerts-gmbh.de/big_buck.bunny.mp4"></video></myCategory><!-- :foods=foods那得傳太多了,很麻煩 --></div>
</template><script>
import myCategory from "./components/myCategory.vue";
export default {name: "App",components: { myCategory },data() {return {foods: ["火鍋", "燒烤", "小龍蝦", "牛排"],games: ["戰(zhàn)神4", "極品飛車", "鬼泣", "超級(jí)瑪麗"],films: ["《教父》", "《復(fù)仇者聯(lián)盟》", "《綠皮書》", "《阿甘》"],};},
};
</script><style>
.container {display: flex;justify-content: space-around;
}
img {width: 100%;
}
video {width: 100%;
}
</style>
(2)myCategory.vue
<template><div class="category"><h3>{{ title }}</h3><slot>圖片加載不出來會(huì)看見這些文字</slot><!-- 挖坑等組件的使用者進(jìn)行填充 --></div>
</template><script>
export default {name: "myCategory",props: ["listData", "title"],
};
</script><style>
.category {background-color: aqua;width: 200px;height: 300px;
}
h3 {text-align: center;background-color: orange;
}
</style>
2.具名插槽
剛才那個(gè)只有一個(gè),直接用的slot,具名插槽就是具有名字的插槽
app:
<template><div class="container"><myCategory title="美食"><imgslot="center"src="http://s3.ax1x.com/2021/01/16/srJlq0.jpg"alt=""/><a slot="footer" href="">更多美食</a></myCategory><myCategory title="游戲"><ul slot="center"><li v-for="(g, index) in games" :key="index">{{ g }}</li></ul><div class="foot" slot="footer"><a href="">單機(jī)游戲</a><a href="">更多美食</a></div><!-- 這個(gè)可以追加 --></myCategory><!-- 這三個(gè)的樣式都是解析完之后才塞到myCategory里面去的,所以script可以直接寫在app里 --><myCategory title="電影"><videoslot="center"controlssrc="http://clips.vorwaerts-gmbh.de/big_buck.bunny.mp4"></video><template v-slot:footer><!-- 這樣slot寫一次就可以了 因?yàn)閠emplate slot就可以這樣寫了,只有它行--><div class="foot"><a href="">單機(jī)游戲</a><a href="">更多美食</a><a href="">更多美食</a></div><h4>歡迎前來觀影</h4></template></myCategory><!-- :foods=foods那得傳太多了,很麻煩 --></div>
</template>
mycategory:
<template><div class="category"><h3>{{ title }}</h3><slot name="center">圖片加載不出來會(huì)看見這些文字</slot><slot name="footer">圖片加載不出來會(huì)看見這些文字</slot><!-- 挖坑等組件的使用者進(jìn)行填充 --></div>
</template>
3.作用域插槽
現(xiàn)在我們只留下游戲重復(fù)三個(gè),然后設(shè)計(jì)第一個(gè)是無序列表,第二個(gè)有序,第三個(gè)每一個(gè)游戲都是h4標(biāo)題
我把數(shù)據(jù)交給了插槽的使用者,根據(jù)數(shù)據(jù)所生成的結(jié)構(gòu)由使用者來定
app:
<template><div class="container"><myCategory title="游戲"><template scope="atguigu"><!-- atguigu收過來的是一個(gè)對(duì)象 --><ul><li v-for="(g, index) in atguigu.games" :key="index">{{ g }}</li></ul></template></myCategory><myCategory title="游戲"><template scope="{games}"><!-- 結(jié)構(gòu)賦值 --><!-- atguigu收過來的是一個(gè)對(duì)象 --><ol><li v-for="(g, index) in games" :key="index">{{ g }}</li></ol></template></myCategory><myCategory title="游戲"><template slot-scope="{games}"><h4 v-for="(g, index) in games" :key="index">{{ g }}</h4></template></myCategory></div>
</template><script>
import myCategory from "./components/myCategory.vue";
export default {name: "App",components: { myCategory },
};
</script><style>
.container,
.foot {display: flex;justify-content: space-around;
}
img {width: 100%;
}
video {width: 100%;
}
h4 {text-align: center;
}
</style>
category:
<template><div class="category"><h3>{{ title }}</h3><slot :games="games">我是默認(rèn)內(nèi)容</slot><!-- 我在這里寫了一個(gè)games,那么它就把games傳給了插槽的使用者app里 --></div>
</template><script>
export default {name: "myCategory",props: ["listData", "title"],data() {return {games: ["戰(zhàn)神4", "極品飛車", "鬼泣", "超級(jí)瑪麗"],};},
};
</script><style>
.category {background-color: aqua;width: 200px;height: 300px;
}
h3 {text-align: center;background-color: orange;
}
</style>