Vue的网络请求、插槽、Vuex

2023-12-20 12:52:08

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);

文章来源:https://blog.csdn.net/pshdhx/article/details/135078781
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。