Vue笔记8--状态管理

1、状态管理简易实现

Vuexpinia可以做状态管理,“状态”可以理解为数据,即在data中定义的参数。有一些公共的属性想要集中管理,方便数据获取。但是对于小项目来说Vuex反而会增加负担,可以自制仓库来集中管理公用数据。

1.1 provide/inject

provide(提供),通过跨级通信做状态管理,不借助Vuex的方式。

项目结构src下新建store(仓库)文件夹,新建index.js文件将公用的数据进行集中管理。

需求有2:

  • 数据实现响应式
    • ref定义字符串数值 reactive定义引用对象
    • reactive定义响应对象中存储着状态msg,age,counter
  • 如何在App组件中通过过provide提供

store文件夹下index.js

store(仓库) state(状态)

import {reactive} from 'vue'
const store={
    state:reactive({//定义状态
        msg:"helloworld"
    }),
    updateMsg:function(){
        this.state.msg="你好"
    }
}
export default store

App.vue

vue2写法<script>标签中引入+注册

import Home from './views/Home.vue';
import store from './store';
export default{
  provide:{
    store
  },
  components:{
    Home
  }
}

<emplate>标签中使用

<template><Home/></template>

Home.vue

<script>标签中ingect获取

export default {
    inject: ['store'],
    methods:{
        updateMsg:function(){
            this.store.updateMsg()
        }
    }
}
    <div>{{ store.state.msg }}</div>
    <button @click="updateMsg">改变msg</button>



1.2 数据交互

如何在Vue中获取数据,向后台发送请求。假设现有http://localhost:3001/banner后端轮播图数据,需要获取并显示。

fetch

是原生JS,是http数据请求的一种方式。默认使用get请求,参数为数据URL地址,返回值一个promise对象。

Home.vue

then处理回调成功或者失败的数据,res.json()将响应的body,解析成json的promise

export default {
    data(){
        return{
            bannersList:[]
        }
    },
    created(){
        fetch('http://localhost:3001/banner').then((res)=>{
            return res.json();
        }).then(res=>{
            this.bannersList=res.banners
        })
    },
}
    <ul>
        <li v-for="item in bannersList" :key="item.targetId">
            <img :src="item.imageUrl" alt=""/>
        </li>
    </ul>

轮播图的数据就获取成功了。同时如果其他页面也需要用到轮播图,我可以将获的数据放到store去。

stroe的index.js

const store={
    state:reactive({
        msg:"helloworld",
        bannersList:[]
    }),
    updateBannersList(value) {
        this.state.bannersList = value
    }
}

Home.vue

获取数据的同时也放如到仓库中

.then(res => {
            this.bannersList = res.banners
            this.store.state.bannersList = res.banners
        })

利用方法的形式替代上面两句更优雅

this.store.updateBannersList(res.banners)

同时渲染html的修改为从仓库拿数据

<li v-for="item in store.state.bannersList" :key="item.targetId">

axios

Axios 是对原生XHR的封装,axios包含ajax

Axios 是一个基于promiseHTTP(网络请求)库,作用于Nodejs和浏览器中。实际项目中一般使用这种

npm下载 npm install axios

Home.vue

<script>
import {axios} from 'axios'
export default {
    ...
    created() {
        axios.get('http://localhost:3001/banner').then((res)=>{
            console.log(res)
        })
    },
}
</script>

.get

fetch 默认使用get请求,axios需要自己使用。实际在项目中会对axios进行封装,以后再项目中细说。

axios.get('http://localhost:3001/banner').then((res)=>{
    console.log(res)
})

.post

.all

获取多个并发请求,只是提一嘴有印象具体用法见文档


1.3 跨域请求数据proxy

以获得猫眼的热映数据为例

  1. F12进入手机模式
  2. Network下找到hot.json
  3. 选择Headers找到GeneralRequest URL

如果直接使用

axios.get('https://i.maoyan.com/api/mmdb/movie/v3/list/hot.json?ct=%E5%B8%B8%E5%BE%B7&ci=268&channelId=4').then((res)=>{
            console.log(res)
        })

会报错找不到数据,提示被CORS策略阻止。是因为浏览器同源策略保护机制,域名不一样的跨域请求不行。

不通过浏览器,通过proxy代理。

vite.config.js

server:配置中转服务器,proxy:通过代理实现跨域,将替换域名取名为path属性有:

  • target:替换服务器地址
  • changeOrigin:开启代理允许跨域
  • rewrite:重写路径,用猫眼域名替换path
export default defineConfig({
  plugins: [vue()],
  server:{
    proxy:{
      //https://i.maoyan.com
      '/path':{
        target:'https://i.maoyan.com',
        changeOrigin:true,
        rewrite: path => path.replace(/^\/path/, '')
      }
    }
  }
})

Home.vue

axios.get('/path/api/mmdb/114514').then((res)=>{
    console.log(res)
})

这样get请求就会变成('https://i.maoyan.com/api/mmdb/114514')




2、Vuex

状态管理模式,集中管理状态。这个状态自管理应用包含以下几个部分:

  • 状态,驱动应用的数据源;
  • 视图,以声明方式将状态映射到视图;
  • 操作,响应在视图上的用户输入导致的状态变化。

但是由于博主很懒,还需要深入学习。

posted @ 2022-12-18 09:15  北溟有咸其名为鸽  阅读(90)  评论(0)    收藏  举报