axios
npm i axios
跨域问题,协议名+ip+端口号。
实际上,浏览器是收到数据的,但是没有交付给开发者。
解决跨域问题
创建代理服务器。代理服务器和前端端口是一样的,所以不存在跨域问题。代理服务器与后端服务器都是服务器,和浏览器没有关系,使用http协议传输数据,所以数据能正常交付给代理服务器。
1、如何创建代理服务器
nginx
2、借助vue-cli
配置参考 | Vue CLI
module.exports = {
devServer: {
proxy: 'http://localhost:4000'
}
}
public文件夹下边有的,都算是8080服务器有的。可以直接请求访问。如果public下边有,则不用访问后端服务器,可以直接去public下边有的。
3、配置多个代理服务器
module.exports = {
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
}
兄弟组件间通信
main.js注册全局总线
beforeCreate(){
Vue.prototype.$bus = this
}
List.vue 【收数据】
mounted(){
this.$bus.on('userList',(users)=>{
console.log('我是List组件,收到了数据',users)
})
}
Search.vue 【传递数据】
this.$bus.$emit('userList',response.data.items)
展示数据
<template>
<!-- 展示用户列表 -->
<div class="row" v-show="users.length">
<div class="card" v-for="user in 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>
</div>
</template>
users的四种展示
1、默认欢迎页面
2、loading页面
3、成功返回页面
4、失败返回页面
data(){
return{
isFirst:true,//是否初次展示
users:[],
isLoading:false,//是否加载中
errMsg:'',//错误信息
}
}
<h1 v-show="isFirst">欢迎使用!</h1>
<h1 v-show="isLoading">加载中!</h1>
<h1 v-show="errMsg">{{errMsg}}</h1>
Search.vue
searchUsers(){
this.$bus.$emit('userList',{isFirst:false,isLoading:true,errMsg:'',users:[]});
axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
response=>{
this.$bus.$emit('userList',{isLoading:false,errMsg:'',users:response.data.items})
},
error=>{
this.$bus.$emit('userList',{isLoading:false,errMsg:error.message,users:[]})
}
)
}
List.vue
mounted(){
this.$bus.on('userList',(userObj)=>{
console.log('我是List组件,收到了数据',userObj)
this.info = {...this.info,...userObj}
})
}
插槽
默认插槽
插槽:就是告诉vue,在双闭合标签内部,要插入的内容的位置。
category.vue
<template>
<div class="category">
<h3>{{title}}</h3>
<slot>我是一个默认值,当外围组件没有传递数据,我会出现</slot>
</div>
</template>
<script>
export default{
name:"Categroy",
props:['listData','title']
}
</script>
App.vue
<template>
<div class="container">
<Category title="美食" :listData="foods">
<img src="xxxxxxxxx" alt=""/>
</Category>
<!-- <Category title="游戏" :listData="games"> -->
<Category title="游戏">
<ur>
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
</Category>
<!--<Category title="电影" :listData="films"/>-->
<Category title="电影">
<video controls src="xxxxxxxxxxxxxx"></vedio>
</Category>
</div>
</template>
具名插槽
存放位置:
<slot name="header">我是一个默认值,当外围组件没有传递数据,我会出现</slot>
外围:
<img slot="header" src="xxxxxxxxx" alt=""/>
外围:
<template v-slot:footer>
<div class="xxx">
xxxxxxxxxxx
<div>
</template>
作用域插槽
数据在插槽里边,外围想要使用
<slot :games="games">我是一个默认值,当外围组件没有传递数据,我会出现</slot>
外围:
<Category title="游戏">
<template scope="getData"> <!-- template必须存在 -->
<ul>
<li v-for="(g,index) in getData.games" :key="index">{{g}}</li>
</ur>
</template>
</Category>
Vuex
npm i vuex@3
Vue.use(Vuex)
store
vc要看到store
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {}
const mutations = {}
const state = {
sum:0
}
export default new Vuex.Store({
actions,
mutations,
state
})
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store/index'
Vue.config.productionTip = false
const vm = new Vue({
render: h => h(App),
store:store,
beforeCreate(){
Vue.prototype.$bus = this
},
}).$mount('#app')
console.log('vm',vm);
methods:{
increment(){
this.$store.dispatch('jia',this.n)
}
}
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {
jia:function (context,value) {
context.commit('JIA',value)
}
}
const mutations = {
JIA(state,value){
state.sum += value
}
}
const state = {
sum:0
}
export default new Vuex.Store({
actions,
mutations,
state
})
action中的上下文中有什么
commit:流向Mutation
dispatch:继续再action里边处理事情 context.dispatch('demo1',value1) demo1方法处理完了之后,context.commit('xxx',value2);
getters
rootGetters
rootState
state:如果在上下文中直接修改state的值,那么vue-detTools就不能够捕获,vuex的数据流向了。
可以跳过dispatch
this.$store.commit('JIA',this.number)
getters的作用
用于将state中的 数据进行加工,方便所有VC使用。computed仅仅在一个组件中使用
const getters = {
bigSum(state){
return state.sum * 10
}
}
export {
getters,
}
this.$store.getters.bigSum
vuex代码优化
this.$store.state.xxx很麻烦,可以借助计算属性
computed:{
sum(){
return this.xxxxxxxxxx
}
}
这样写也很麻烦
优化点,引入vuex
import {mapState} from 'vuex'
mounted(){
const x = mapState({
he:'sum',
xuexiao:'school',
xueke:'sunbject'
});
console.log(x) 可以看出x是一个对象,将其对象通过...加入到computed里边
}
computed:{
...mapState({
xxxxxxxxxxxxx
})
...mapGetters(['xxx','xxxxx'])
...mapGetters("common", ["bbbbbbbbbb"]),
},
methods:{
...mapActions("common",['xxxxxxxxxxxx]),
...mapMutations("common",['aaaaaaaaaa']),
}
Vuex模块化
store/index.js
const countOptions = {
namespaced:true,
actions:{
}
}
const personOptions = {
namespaced:true,
actions:{
}
}
export default new Vuex.Store({
modules:{
countOptions,
personOptions,
}
})
...mapState('countOptions',['xxx','xxxxxxx'])
//或者是
this.$store.commit('personOptions/ADD_PERSON',personObj);