vue基础(七),同源策略以及跨域,vuex

摘要:
它采用集中式存储管理应用的所有组件的状态(数据),并以相应的规则保证状态以一种可预测的方式发生变化。这需要对短期和长期效益进行权衡。

跨域基础

跨域:
    1、是什么
        你的目标和你自己现在的位置一样还是不一样

        浏览器上的同源策略

        特点:
        1、跨域只存在于浏览器
        2、不在浏览器发请求是不会存在跨域问题的
        3、http请求分为两大类: 普通http请求(如百度请求)和ajax请求(跨域是出现在ajax请求)
          
    2、在什么地方    
        浏览器会跨域 服务器不会
 
    3、什么条件会跨域   
        同源(协议  ip  端口一致)不跨域  
        不同源就跨域(三个中间有一个不一样就跨域)
        
    
        http://localhost:8080/     -------  》 github    (有得是后台解决了允许跨域,前端如何解决跨域)

    4、解决跨域:前端可以解决、后端解决。一般后端解决比前端解决容易

1.如果端口9000的服务向端口8000的端口发送请求,这一定跨域了,此时我们需要在在webpack配置文件中devserer中配置Proxy代理

async searchAjax(q) {
      try {
        const result = await axios({
          url: "http://localhost:9000/api/users/info",
          method: "get"
        });
        console.log(result.data);
      } catch (error) {
        console.log(error);
      }

在webpack配置文件中devserer中配置Proxy代理

//3. 增加 devServer 配置
   devServer: {
    open: true,     // 自动打开浏览器
    compress: true, // 启动gzip压缩
    port: 9000,     // 端口号
    quiet:true,
    // proxy:{
    //   // 请求路径 http://localhost:9000/api/users/info
    //   //api会把http://localhost:9000覆盖掉
    //   // 代理转发路径 http://localhost:8000/api/users/info

    //   // "/api":{
    //   //   target :"http://localhost:8000",  //目标路径
    //   //   pathRewrite: {"^/api" : ""},  //代理会把身份标识去掉替换成空窜
    //   //   changeOrigin:true
    //   // },
    // }
  },

配置代理服务器的原理图

vue基础(七),同源策略以及跨域,vuex第1张

二, vuex的核心

1、状态管理是什么:
        Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,是一个插件。
        它采用集中式存储管理应用的所有组件的状态(数据),并以相应的规则保证状态以一种可预测的方式发生变化。
        我们也可以认为它也是一种组件间通信的方式,并且适用于任意组件

    2、理解:对vue应用中多个组件的共享状态进行集中式的管理(读/写)
        

    3、为什么要有这个(问题):
        1)多个视图依赖于同一状态
        2)来自不同视图的行为需要变更同一状态
        3)以前的解决办法
            a.将数据以及操作数据的行为都定义在父组件
            b.将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
        4)vuex就是用来解决这个问题的


    4、什么时候用:
      Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
        也就是说应用简单(组件比较少)就不需要使用(但是可以),如果应用复杂,使用就会带来很大的便捷
        
    

    5、Vuex核心:把所有的共享状态数据拿出来放在Vuex中进行集中式管理    

        1、安装vuex
        2、创建单独的模块使用vuex 它是一个插件,按照插件使用方式
        3、书写四个核心对象
        4、暴露模块
        5、在Vue配置项当中注册vuex对象,store
        6、在核心对象写代码


        优化:
            1、如果用户再操作的时候就是很简单的数据更改,那么可以不用分发给actions,直接提交给mutations去更改
            2、页面上如果数据不想写的太长,可以利用getters,去计算出来,然后在组件computed当中获取计算的这个数据
            3、mapActions等
            


        Vuex4个核心概念
        state          代表初始状态数据    是一个包含n个属性(不是方法)的对象
        getters           代表计算属性数据    是一个包含n个计算属性的方法的对象
        actions        代表用户行为数据    是一个包含n个用户行为回调方法的对象,(用来映射组件用户的行为回调函数)
        mutations      代表直接修改数据的数据  是一个包含n个直接修改状态数据方法的对象 (用来让action的行为调用)        
        注意:只能通过mutations的方法去直接修改,也就是说要想写state数据必须通过mutations
             actions里面是用户操作的行为回调函数,它的内部可以写异步和判断
             mutations里面是直接修改数据的函数数据,它的内部不可以写异步和判断

1.安装vuex, npm install vuex --save

2.新建文件夹vuex,文件store.js,

import Vue from 'vue'
import Vuex from 'vuex'
// 申明插件
Vue.use(Vuex)

3.在main.js引入import store from '@/vuex/store', 注册store

const vm = new Vue({
  el:'#root',
  render: h => h(App),
store   //如果我们声明使用(注册)store(vuex),那么每个组件对象都可以通过this.$store拿到我们的store对象
})

例子

1.入口文件main.js

import Vue from 'vue'
import App from '@/App'
import store from '@/vuex/store'


Vue.config.productionTip = false

const vm = new Vue({
  el:'#root',
  render: h => h(App),
  store   //如果我们声明使用(注册)store(vuex),那么每个组件对象都可以通过this.$store拿到我们的store对象
})

2.app组件

<template>
  <div>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementIfOdd">如果是奇数加{{count}}</button>
    <button @click="incrementAsync">异步加{{count}}</button>
  </div>
</template>

<script>
//从store中映射action和state,解构方式,供组件使用
import {mapActions,mapState} from 'vuex'export default{
  name: 'App'
  //数据定义到vuex(store)里面


  //methods:mapActions(['increment','decrement','incrementIfOdd','incrementAsync'])
methods:{
    //最原始的写法
    //increment(){
    ////this.$store.dispatch分发触发 store对象内部actions内部对应的方法
    //this.$store.dispatch('increment')
    //},
    //decrement(){
    //this.$store.dispatch('decrement')
    //},
    //incrementIfOdd(){
    //this.$store.dispatch('incrementIfOdd')
    //},
    //incrementAsync(){
    //this.$store.dispatch('incrementAsync')
    //}
      //使用mapActions简化methods的写法
      //1、如果methods方法名称和store对象actions内部的方法名称一致,可以使用下面这样的写法
      //...mapActions(['increment','decrement','incrementIfOdd','incrementAsync'])

      //2、如果methods方法的名称和store对象actions内部的方法名称不一致,那么就不能使用数组这样的写法
...mapActions(['decrement','incrementIfOdd','incrementAsync']),
      ...mapActions({'increment':'iincrement'})
  },

  computed:{
    //count(){
    //return this.$store.state.count
    //}
...mapState(['count'])


  }
  




  //之前的,数据是定义在组件内的
  //data(){
  //return {
  //count:0
  //}
  //},
  //methods:{
  //increment(){
  //this.count++
  //},
  //decrement(){
  //this.count--
  //},
  //incrementIfOdd(){
  //if(this.count % 2 === 1){
  //this.count++
  //}
  //},
  //incrementAsync(){
  //setTimeout(() => {
  //this.count++
  //}, 1000);
  //}
  //}
}
</script>

<style scoped>
</style>

store.js

import Vue from 'vue'
import Vuex from 'vuex'
// 申明插件
Vue.use(Vuex)

const state = {
//是专门用来存(状态)数据的地方,它是一个包含多个属性和属性值的对象
  count:0
}

const mutations = {
//专门用来更新数据的各种方法组成的对象
//这些个方法,必须是直接修改数据的方法, 不能在这些方法内部存在 判断  循环  异步
  INCREMENT(state){
    state.count++
  },
  DECREMENT(state){
    state.count--
  }
}

const actions = {
//专门用来和组件行为(用户行为)进行对接的各种方法组成的对象
//还有一个作用,用来对接成功后,告知相应的mutations中的对应方法去修改数据
// context有commit和state属性

  // increment(context){
  //   //接到用户的操作请求(用户分发)之后,提交给相关的修改数据的函数去修改
  //   //在这里可以去写 if  for   异步
  //   context.commit('INCREMENT')
  // }



//解构方式
  iincrement({commit}){
    //接到用户的操作请求(用户分发)之后,提交给相关的修改数据的函数去修改
    //在这里可以去写 if  for   异步
    commit('INCREMENT')
  },

  decrement({commit}){
    //接到用户的操作请求(用户分发)之后,提交给相关的修改数据的函数去修改
    //在这里可以去写 if  for   异步
    commit('DECREMENT')
  },

  incrementIfOdd({commit,state}){
    //action内部的方法可以if for 异步 但是mutations里面的不行
    if(state.count % 2 === 1){
      commit('INCREMENT')
    }
  },

  incrementAsync({commit}){
    setTimeout(() => {
      commit('INCREMENT')
    }, 1000);
  }
}

const getters = {
//一系列的方法,计算属性get方法,根据我们state内的数据计算出来用户要使用的数据
}

//暴露Store
export default new Vuex.Store({
  state,
  mutations,
  getters,
  actions
})

三,案例,在vuex中发送ajax请求,main组件获取vuex的数据

App组件

<template>
  <div class="container">
    <Header></Header>
    <Main></Main>
  </div>
</template>

<script>import Header from '@/components/Header'import Main from '@/components/Main'export default{
  name: '',
  components:{
    Header,
    Main
  }
}
</script>

<style scoped>

</style>

header组件

<template>
  <section class="jumbotron">
    <h3 class="jumbotron-heading">Search Github Users</h3>
    <div>
      <input type="text"placeholder="enter the name you search"v-model="searchName" />
      <button @click="search">Search</button>
    </div>
  </section>
</template>

<script>import {mapActions} from 'vuex'export default{
  name: "",
  data(){
    return{
      searchName:''}
  },
  
  methods:{
    //...mapActions(['search'])
search(){
      //和store里面的某个actions方法去对应
     //如果传递参数只有一个,可以直接传
      //如果传递多个,必须使用对象
      this.$store.dispatch('search',this.searchName)
    }
  }
};
</script>

<style scoped>
</style>

main组件

<template>
  <div>
    <h2 v-if="isFirst">欢迎光临,请输入关键字进行搜索</h2>
    <h2 v-else-if="isLoading">正在搜索中,请稍后</h2>
    <h2 v-else-if="errMsg">请求出错:{{errMsg}}</h2>
    <div v-else class="row">
      <div class="card"v-for="(user, index) in users":key="user.userName">
        <a :href="user.userUrl"target="_blank">
          <img :src="user.userImg"style=" 100px" />
        </a>
        <p class="card-text">{{user.userName}}</p>
      </div>
    </div>
  </div>
</template>

<script>import axios from 'axios'
//从store中映射出state,供组件使用数据
import {mapState} from 'vuex'

export default{
  name: "",
  //接收state里的数据,mapState()返回的是一个对象,解包对象
computed:{
  ...mapState(['isFirst','isLoading','errMsg','users'])
  }
  //data(){
  //return {
  //isFirst:true,
  //isLoading:false,
  //errMsg:'',
  //users:[]
  //}
  //},
  //mounted(){
  //this.$bus.$on('searchAjax',this.searchAjax)
  //},
  //methods:{
  //searchAjax(q){
  ////在发送ajax请求之前,让页面显示正在请求中
  //this.isFirst = false
  //this.isLoading = true
  ////就可以根据searchName去发送ajax请求
  //this.$http({
  //url:'https://api.github.com/search/us',
  //method:'get',
  //params:{
  //q
  //}
  //}).then(response => {
  //let userList = response.data.items.map(item => {
  //return {
  //userName:item.login,
  //userUrl:item.url,
  //userImg:item.avatar_url
  //}
  //})
  //this.users = userList
  //this.isLoading = false  //请求成功拿到数据,显示用户信息

  //}).catch(error => {
  //this.errMsg = error.statusText
  //this.isLoading = false //请求失败拿到错误信息,显示错误信息
  //})
  //}
  //}
};
</script>

<style scoped>.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>

store.js

import Vue from 'vue'
import Vuex from 'vuex'
// 引入axios
import axios from 'axios'
// 申明插件
Vue.use(Vuex)

const state = {
  isFirst:true,
  isLoading:false,
  errMsg:'',
  users:[]
}
const mutations = {
  REQUESTING(state){
    state.isFirst = false
    state.isLoading = true
  },
  REQUEST_SUCCESS(state,userList){
    state.users = userList
    state.isLoading = false  //请求成功拿到数据,显示用户信息
  },
  REQUEST_FAILD(state,error){
    state.errMsg = error.message
    state.isLoading = false //请求失败拿到错误信息,显示错误信息
  }
}
const actions = {
  //{commit}解构
  search(context,q){
    //在发送ajax请求之前,让页面显示正在请求中
    context.commit('REQUESTING')
    //就可以根据searchName去发送ajax请求
    axios({
      url:'https://api.github.com/search/users',
      method:'get',
      params:{
        q
      }
    }).then(response => {
      //返回一个新数组,数组中有个对象
      let userList = response.data.items.map(item => {
        return {
          userName:item.login,
          userUrl:item.url,
          userImg:item.avatar_url
        }
      })
       //请求成功后,提交给mutations,修改state的数据
      context.commit('REQUEST_SUCCESS',userList)
    }).catch(error => {
      //发送请求失败后,提交给mutations,修改state的数据,改变状态
      context.commit('REQUEST_FAILD',error)
    })
  }
}
const getters = {}
// 向外暴露store,给main.js
export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters
})

免责声明:文章转载自《vue基础(七),同源策略以及跨域,vuex》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Bootstrap入门学习(三)——简单项目RocketMQ(八)RocketMQ的Consumer负载均衡下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue-cli3.0和element-ui及axios的安装使用

一、利用vue-cli3快速搭建vue项目 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统。有三个组件: CLI:@vue/cli 全局安装的 npm 包,提供了终端里的vue命令(如:vue create 、vue serve 、vue ui 等命令) CLI 服务:@vue/cli-service是一个开发环境依赖。构建于 web...

mac-chrome下手动安装vue-devtools

原文链接:https://blog.csdn.net/weixin_44868003/article/details/89457089 废话就不多说,直接上安装步骤,一步一步来 => success 1.下载安装vue-devtools源文件 mkdir vuetools cd vuetools git clone https://...

基于node的前端项目编译时(react vue 打包)内存溢出问题

前段时间公司有个基于 vue 的项目在运行 npm run build 的时候会报内存溢出,今天在某个技术流交群也有位小伙伴基于 angular 的项目也出现了这个问题,所以查了一些相关的资料总结了一下,下面会详细说明前端三大框架编译时遇到这个问题具体怎么解决。首先看我模拟出的报错内容 具体截图如下 里面有句关键的话, CALL_AND_RETRY_LA...

我们是如何做好前端工程化和静态资源管理

随着互联网的发展,我们的业务也日益变得更加复杂且多样化起来,前端工程师也不再只是做简单的页面开发这么简单,我们需要面对的十分复杂的系统性问题,例如,业务愈来愈复杂,我们要如何清晰地梳理;团队人员愈来愈多,我们要如何更好地进行团队协作;功能愈来愈多,我们要如何保证页面的性能不至于下降,等等。所有的这些都可以归结为如何提升开发体验和性能问题。 提升开发体验...

vue中使用keepAlive(缓存页面&amp;amp;记忆上次浏览位置)及使用后生命周期的改变

以下部分内容转自博客(另外配有自己见解):https://www.cnblogs.com/nokelong/p/8116631.html 使用keepAlive缓存页面,一可以减少服务器请求次数,二则可以在用户返回上一页后记忆到上次浏览位置(ios端微信浏览器不适用,不兼容,需要另行配置:见例子(1)) keep-alive的介绍如下: 1,把切换出去的组...

vue 弹框

弹框展示: 代码: 1 <template> 2 <div> 3 <el-col :span="9" style="text-align: right;"> 4 <el-button @click="dialogVisible=true" 5...