Vuex学习

news2024/11/18 1:25:21

5.1.理解 Vuex

5.1.1.Vuex 是什么

  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信

  2. Vuex Github地址

    在这里插入图片描述在这里插入图片描述

5.1.2.什么时候使用 Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

5.1.3.Vuex 工作原理图

在这里插入图片描述

5.2.求和案例

5.2.1.使用纯 vue 编写

在这里插入图片描述

src/App.vue

<template> 
  <div> 
    <Count/> 
  </div> 
</template>

<script> 
  import Count from "./components/Count.vue"; 
  export default { 
    name: "App", 
    components: { 
      Count 
    } 
  }; 
</script>

src/components/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ sum }}</h2>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

<script>
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                sum: 0, // 当前的和
                n: 1,   // 用户选择的数字
            }
        },
        methods: {
            increment() {
                this.sum += this.n;
            },
            decrement() {
                this.sum -= this.n;
            },
            incrementOdd() {
                if (this.sum % 2) {
                    this.sum += this.n;
                }
            },
            incrementWait() {
                setTimeout(() => {
                    this.sum += this.n;
                    }, 500);
            }
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

5.2.2.搭建 Vuex 环境

  1. 下载安装vuex npm i vuex
  2. 创建src/store/index.js该文件用于创建Vuex中最为核心的store
    import Vue from 'vue';
    import Vuex from 'vuex'; // 引入Vuex
    
    Vue.use(Vuex) // 应用Vuex插件
    
    const actions = {} // 准备actions——用于响应组件中的动作 
    const mutations = {} // 准备mutations——用于操作数据(state) 
    const state = {} // 准备state——用于存储数据
    
    // 创建并暴露store
    export default new Vuex.Store({ 
      actions, 
      mutations, 
      state
    })
    
  3. src/main.js中创建vm时传入store配置项
    import Vue from 'vue';
    import App from './App.vue';
    import store from './store';  // 引入store,默认拿index文件
    
    Vue.config.productionTip = false;
    
    new Vue({
      el: '#app',
      render: h => h(App),
      store,              // 配置项添加store
      beforeCreate() {
        Vue.prototype.$bus = this; // 安装全局事件总线
      }
    })
    

5.2.3.使用 Vuex 编写

Vuex的基本使用

  1. 初始化数据state,配置actionsmutations,操作文件store.js
  2. 组件中读取vuex中的数据**$store.state.**数据
  3. 组件中修改vuex中的数据** s t o r e . d i s p a t c h ( ′ a c t i o n 中的方法 名 ′ , 数据 ) ∗ ∗ 或 ∗ ∗ store.dispatch('action中的方法名',数据)** 或 ** store.dispatch(action中的方法,数据)store.commit(‘mutations中的方法名’,数据)若没有网络请求或其他业务逻辑,组件中也可越过actions**,即不写dispatch,直接编写commit

src/store/index.js该文件用于创建Vuex中最为核心的store

// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue';
import Vuex from 'vuex'; // 引入Vuex

// 应用Vuex插件
Vue.use(Vuex);

// 准备actions —— 用于响应组件中的动作
const actions = {
    /*
     * jia(context,value) {
     *  console.log('actions中的jia被调用了');
     *  context.commit('JIA',value)
     * },
     *
     * jian(context,value) {
     *  console.log('actions中的jian被调用了');
     *  context.commit('JIAN',value)
     * },
     */
    jiaOdd(context,value) {
        // context 相当于精简版的 $store
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value) {
        console.log('actions中的jiaWait被调用了');
        setTimeout(() => {
            context.commit('JIA',value)
        },500);
    }
}

// 准备mutations —— 用于操作数据(state)
const mutations = {
    JIA(state,value) {
        console.log('mutations中的JIA被调用了');
        state.sum += value
    },
    JIAN(state,value) {
        console.log('mutations中的JIAN被调用了');
        state.sum -= value
    }
}

// 准备state —— 用于存储数据
const state = {
    sum:0 // 当前的和
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state
})

src/components/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ $store.state.sum }}</h2>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

<script>
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                n: 1   // 用户选择的数字
            }
        },
        methods: {
            increment() {
                this.$store.commit('JIA', this.n);
            },
            decrement() {
                this.$store.commit('JIAN', this.n);
            },
            incrementOdd() {
                this.$store.dispatch('jiaOdd', this.n);
            },
            incrementWait() {
                this.$store.dispatch('jiaWait',this.n);
            }
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

5.3. getters 配置项

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工,相当于全局计算属性
  2. store.js中追加getters配置
    ......
    
    const getters = { 
      bigSum(state) { 
        return state.sum * 10 
      } 
    }
    
    // 创建并暴露store 
    export default new Vuex.Store({ 
      ...... getters 
    })
    
  3. 组件中读取数据**$store.getters.bigSum**
    在这里插入图片描述

src/store/index.js

// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue';
import Vuex from 'vuex'; // 引入Vuex

// 应用Vuex插件
Vue.use(Vuex);

// 准备actions —— 用于响应组件中的动作
const actions = {
    /*
     * jia(context,value) {
     *  console.log('actions中的jia被调用了');
     *  context.commit('JIA',value)
     * },
     *
     * jian(context,value) {
     *  console.log('actions中的jian被调用了');
     *  context.commit('JIAN',value)
     * },
     */
    jiaOdd(context,value) {
        // context 相当于精简版的 $store
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value) {
        console.log('actions中的jiaWait被调用了');
        setTimeout(() => {
            context.commit('JIA',value)
        },500);
    }
}

// 准备mutations —— 用于操作数据(state)
const mutations = {
    JIA(state,value) {
        console.log('mutations中的JIA被调用了');
        state.sum += value
    },
    JIAN(state,value) {
        console.log('mutations中的JIAN被调用了');
        state.sum -= value
    }
}

// 准备state —— 用于存储数据
const state = {
    sum:0 // 当前的和
}

// 准备getters对象——用于将state中的数据进行加工
const getters = {
    bigSum() {
        return state.sum * 10;
    }
}

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

src/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ $store.state.sum }}</h2>
        <h3>当前求和的10倍为:{{ $store.getters.bigSum }}</h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一等再加</button>
    </div>
</template>

<script>
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                n: 1   // 用户选择的数字
            }
        },
        methods: {
            increment() {
                this.$store.commit('JIA', this.n);
            },
            decrement() {
                this.$store.commit('JIAN', this.n);
            },
            incrementOdd() {
                this.$store.dispatch('jiaOdd', this.n);
            },
            incrementWait() {
                this.$store.dispatch('jiaWait',this.n);
            }
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

5.4.四个 map 方法的使用

  1. mapState方法:用于帮助映射state中的数据为计算属性
    computed: {
      // 借助mapState生成计算属性:sum、school、subject(对象写法一)
      ...mapState({sum:'sum',school:'school',subject:'subject'}),
      
      // 借助mapState生成计算属性:sum、school、subject(数组写法二)
      ...mapState(['sum','school','subject']),
    }
    
  2. mapGetters方法:用于帮助映射getters中的数据为计算属性
    computed: {
      // 借助mapGetters生成计算属性:bigSum(对象写法一)
      ...mapGetters({bigSum:'bigSum'}),
      
      // 借助mapGetters生成计算属性:bigSum(数组写法二)
      ...mapGetters(['bigSum'])
    }
    
  3. mapActions方法:用于帮助生成与actions对话的方法,即包含**$store.dispatch(xxx)**的函数
    methods:{
      // 靠mapActions生成:incrementOdd、incrementWait(对象形式)
      ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
      
      // 靠mapActions生成:incrementOdd、incrementWait(数组形式)
      ...mapActions(['jiaOdd','jiaWait'])
    }
    
  4. mapMutations方法:用于帮助生成与mutations对话的方法,即包含**$store.commit(xxx)**的函数
    methods:{
      // 靠mapActions生成:increment、decrement(对象形式)
      ...mapMutations({increment:'JIA',decrement:'JIAN'}),
      
      // 靠mapMutations生成:JIA、JIAN(对象形式)
      ...mapMutations(['JIA','JIAN']),
    }
    

注意mapActionsmapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象

src/components/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ sum }}</h2>
        <h3>当前求和的10倍为:{{ bigSum }}</h3>
        <h3>我在{{ school }},学习{{ subject }}</h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>
    </div>
</template>

<script>
    import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                n: 1   // 用户选择的数字
            }
        },
        computed: {
            // 借助mapState生成计算属性,从state中读取数据(对象写法)
            // ...mapState({sum:'sum', school:'school',subject:'subject'}),

            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapState(['sum','school','subject']),

            /*************************************************************************/

            // 借助mapState生成计算属性,从state中读取数据(对象写法)
            //  ...mapGetters({bigSum: 'bigSum'})

            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapGetters(['bigSum'])
        },
        methods: {
            // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            ...mapMutations({increment: 'JIA', decrement: 'JIAN'}),

            // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            // ...mapMutations(['JIA', 'JIAN']),

            /*************************************************************************/
            // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
            ...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'}),

            // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
            // ...mapActions(['jiaOdd', 'jiaWait']),
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

5.5.多组件共享数据案例

在这里插入图片描述


src/App.vue

<template>
    <div>
        <Count/>
        <Person/>
    </div>
</template> 

<script> 
    // 引入组件
    import Count from './components/Count.vue';
    import Person from "./components/Person.vue";

    export default {
        name:'App',
        components:{
            Count,
            Person
        }
    }
</script>

<style>
    .container,.foot {
        display: flex;justify-content: space-around;
    }
    h4{text-align: center;}
</style>

src/store/index.js

该文件用于创建Vuex中最为核心的store

// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue';
import Vuex from 'vuex'; // 引入Vuex

// 应用Vuex插件
Vue.use(Vuex);

// 准备actions —— 用于响应组件中的动作
const actions = {
    jiaOdd(context,value) {
        // context 相当于精简版的 $store
        console.log('actions中的jiaOdd被调用了');
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value) {
        console.log('actions中的jiaWait被调用了');
        setTimeout(() => {
            context.commit('JIA',value)
        },500);
    }
}

// 准备mutations —— 用于操作数据(state)
const mutations = {
    JIA(state,value) {
        console.log('mutations中的JIA被调用了');
        state.sum += value
    },
    JIAN(state,value) {
        console.log('mutations中的JIAN被调用了');
        state.sum -= value
    },
    ADD_PERSON(state,value){
        console.log('mutations中的ADD_PERSON被调用了');
        state.personList.unshift(value);
    }
}

// 准备state —— 用于存储数据
const state = {
    sum:0, // 当前的和
    school: '尚硅谷',
    subject: '前端',
    personList: []
}

// 准备getters对象——用于将state中的数据进行加工
const getters = {
    bigSum() {
        return state.sum * 10;
    }
}

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

src/components/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ sum }}</h2>
        <h3>当前求和的10倍为:{{ bigSum }}</h3>
        <h3>我在{{ school }},学习{{ subject }}</h3>
        <h3 style="color:red">Person组件的总人数是:{{ personList.length }}</h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>
    </div>
</template>

<script>
    import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                n: 1   // 用户选择的数字
            }
        },
        computed: {
            // 借助mapState生成计算属性,从state中读取数据(对象写法)
            // ...mapState({sum:'sum', school:'school',subject:'subject'}),

            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapState(['sum','school','subject', 'personList']),

            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapGetters(['bigSum'])
        },
        methods: {
            // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            ...mapMutations({increment: 'JIA', decrement: 'JIAN'}),

            // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            // ...mapMutations(['JIA', 'JIAN']),

            // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
            ...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'}),

            // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
            // ...mapActions(['jiaOdd', 'jiaWait']),
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

src/components/Person.vue

<template>
    <div>
        <h1>人员列表</h1>
        <h3 style="color:red">Count组件求和为:{{ sum }}</h3>
        <input type="text" placeholder="请输入名字" v-model="name">
        <button @click="add">添加</button>
        <ul>
            <li v-for="p in personList" :key="p.id">{{ p.name }}</li>
        </ul>
    </div>
</template>

<script>
    import {nanoid} from 'nanoid';

    export default {
        name: "Person",
        data() {
            return {
                name:''
            }
        },
        computed:{
            personList() {
                return this.$store.state.personList;
            },

            sum() {
                return this.$store.state.sum;
            }
        },
        methods: {
            add(){
                if (this.name === "") return;
                const personObj = {
                    id:nanoid(),
                    name:this.name
                };
                this.$store.commit('ADD_PERSON', personObj);
                this.name = '';
            }
        }
    }
</script>

<style scoped>

</style>

5.6.模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确
  2. 修改store.js,为了解决不同模块命名冲突的问题,将不同模块的namespaced: true,之后在不同页面中引入getter actions mutations时,需要加上所属的模块名
    const countAbout = {
      namespaced: true, // 开启命名空间
      state: {x:1},
      mutations: { ... }, 
      actions: { ... },
      getters: { 
        bigSum(state) { 
          return state.sum * 10 
        } 
      }
    }
    
    const personAbout = { 
      namespaced: true, // 开启命名空间 
      state: { ... }, 
      mutations: { ... }, 
      actions: { ... } 
    }
    
    const store = new Vuex.Store({ 
      modules: { 
      countAbout, 
      personAbout 
      } 
    })
    
  3. 开启命名空间后,组件中读取state数据
    // 方式一:自己直接读取 
    this.$store.state.personAbout.list 
    // 方式二:借助mapState读取: 
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 开启命名空间后,组件中读取getters数据
    //方式一:自己直接读取 
    this.$store.getters['personAbout/firstPersonName'] 
    //方式二:借助mapGetters读取: 
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用dispatch
    //方式一:自己直接dispatch 
    this.$store.dispatch('personAbout/addPersonWang',person) 
    //方式二:借助mapActions: 
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 开启命名空间后,组件中调用commit
    //方式一:自己直接commit 
    this.$store.commit('personAbout/ADD_PERSON',person) 
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

在这里插入图片描述

src/store/index.js

// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue';
import Vuex from 'vuex'; // 引入Vuex
import countOptions from './count'; // 引入count
import personOptions from './person'; // 引入person

// 应用Vuex插件
Vue.use(Vuex);

// 创建并暴露store
export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions,
    }
})

src/store/count.js

export default {
    namespaced:true,
    actions:{
        jiaOdd(context,value) {
            console.log('actions中的jiaOdd被调用了');
            if(context.state.sum % 2){
                context.commit('JIA',value)
            }
        },
        jiaWait(context,value) {
            console.log('actions中的jiaWait被调用了');
            setTimeout(() => {
                context.commit('JIA',value)
            },500);
        }
    },
    mutations:{
        JIA(state,value) {
            console.log('mutations中的JIA被调用了');
            state.sum += value
        },
        JIAN(state,value) {
            console.log('mutations中的JIAN被调用了');
            state.sum -= value
        }
    },
    state:{
        sum:0,
        school: '尚硅谷',
        subject: '前端',
    },
    getters:{
        bigSum(state) {
            return state.sum * 10;
        }
    }
}

src/store/person.js

import axios from "axios";
import { nanoid } from "nanoid"

export default{
    namespaced:true,
    actions:{
        addPersonWang(context,value){
            if(value.name.indexOf('王') === 0) {
                context.commit('ADD_PERSON',value);
            } else {
                alert('添加的人必须姓王!');
            }
        },
        addPersonServer(context){
            axios.get('http://api.uixsj.cn/hitokoto/get?type=social').then(
                response => {
                    context.commit('ADD_PERSON',{id:nanoid(),name:response.data});
                },
                error => {
                    alert(error.message);
                }
            )
        }
    },
    mutations:{
        ADD_PERSON(state,value){
            console.log('mutations中的ADD_PERSON被调用了');
            state.personList.unshift(value);
        }
    },
    state:{
        personList:[{id:1, name:'liqb'}]
    },
    getters:{
        firstPersonName(state) {
            return state.personList[0].name;
        }
    }
}

src/components/Count.vue

<template>
    <div>
        <h2>当前求和为:{{ sum }}</h2>
        <h3>当前求和的10倍为:{{ bigSum }}</h3>
        <h3>我在{{ school }},学习{{ subject }}</h3>
        <h3 style="color:red">Person组件的总人数是:{{ personList.length }}</h3>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment(n)">+</button>
        <button @click="decrement(n)">-</button>
        <button @click="incrementOdd(n)">当前求和为奇数再加</button>
        <button @click="incrementWait(n)">等一等再加</button>
    </div>
</template>

<script>
    import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';
    export default {
        name: "Count",
        props:['title'],
        data() {
            return {
                n: 1   // 用户选择的数字
            }
        },
        computed: {
            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapState('countAbout', ['sum','school','subject']),
            ...mapState('personAbout', ['personList']),

            // 借助mapState生成计算属性,从state中读取数据(数组写法)
            ...mapGetters('countAbout', ['bigSum'])
        },
        methods: {
            // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
            ...mapMutations('countAbout', {increment: 'JIA', decrement: 'JIAN'}),

            // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
            ...mapActions('countAbout', {incrementOdd:'jiaOdd', incrementWait:'jiaWait'}),
        }
    }
</script>

<style scoped>
    button {
        margin-left: 5px;
    }
</style>

src/components/Person.vue

<template>
    <div>
        <h1>人员列表</h1>
        <h3 style="color:red">Count组件求和为:{{ sum }}</h3>
        <h3>列表中第一个人的名字是:{{ firstPersonName }}</h3>
        <input type="text" placeholder="请输入名字" v-model="name">
        <button @click="add">添加</button>
        <button @click="addWang">添加一个姓王的人</button>
        <button @click="addPerson">随机添加一个人</button>
        <ul>
            <li v-for="p in personList" :key="p.id">{{ p.name }}</li>
        </ul>
    </div>
</template>

<script>
    import {nanoid} from 'nanoid';

    export default {
        name: "Person",
        data() {
            return {
                name:''
            }
        },
        computed:{
            personList() {
                return this.$store.state.personAbout.personList;
            },
            sum() {
                return this.$store.state.countAbout.sum;
            },
            firstPersonName(){
                return this.$store.getters['personAbout/firstPersonName'];
            }
        },
        methods: {
            add(){
                if (this.name === "") return;
                const personObj = {id: nanoid(), name: this.name};
                this.$store.commit('personAbout/ADD_PERSON', personObj);
                this.name = '';
            },
            addWang(){
                const personObj = {id:nanoid(),name:this.name};
                this.$store.dispatch('personAbout/addPersonWang', personObj);
                this.name = '';
            },
            addPerson(){
                this.$store.dispatch('personAbout/addPersonServer');
            }
        }
    }
</script>

<style scoped>

</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/687443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习05-CNN循环神经网络

概述 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种具有循环连接的神经网络结构&#xff0c;被广泛应用于自然语言处理、语音识别、时序数据分析等任务中。相较于传统神经网络&#xff0c;RNN的主要特点在于它可以处理序列数据&#xf…

超全汇总,性能测试常用指标大全(重要)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 两种性能指标 业…

Java又双叒叕“凉”了?

前几天&#xff0c;TIOBE的一份6月编程语言榜单公布&#xff1a;Java退出前三&#xff0c;位居第四。一波Java凉了的言论甚嚣尘上。其实不止Java&#xff0c;python、C、C&#xff0c;哪一个没被提过“凉”... 而现实是&#xff0c;Java的招聘需求依然很大&#xff1a; 不可否…

C++静态和动态链接库导出和使用

1、简介 代码开发过程中会遇到很多已有的函数库&#xff0c;这些函数库是现有的&#xff0c;成熟的&#xff0c;可以复用的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个人的代码都从零开始&#xff0c;因此库的存在意义非同寻常。 本质上来说库是一种…

便携式水质自动采样器助力毒情监测

便携式水质自动采样器可助力毒情监测&#xff1a; 污水涉毒采样检测工作是运用科技手段准确评估监测辖区内毒情形势的重要手段。期间&#xff0c;民警详细了解了生活和工业污水的处理、排放以及服务范围、人口数量等情况&#xff0c;并就污水涉毒采样检测工作达成共识。随后&am…

revit中用幕墙来绘制瓦片屋面和生成土钉墙

一、revit中用幕墙来绘制瓦片屋面 层层叠叠的瓦片在我们绘制时具有复杂性&#xff0c;瓦片既美观又满足一些建筑的需要&#xff0c;下面教大家一个用幕墙来绘制瓦片屋面。 新建一个族样板选择公制轮廓—竖挺&#xff0c;绘制我们的瓦片形状 简单的绘制一个瓦片的形状&#xff0…

JVM学习整理(一)

一、JVM的基本介绍 JVM 是 Java Virtual Machine 的缩写&#xff0c;它是一个虚构出来的计算机&#xff0c;一种规范。通过在实际的计算机上仿真模拟各类计算机功能实现 好&#xff0c;其实抛开这么专业的句子不说&#xff0c;就知道JVM其实就类似于一台小电脑运行在windows或…

ruoyi-vue前后端分离项目实现一体化打包(前后端合并打包)

场景 现在要对ruoyi-vue前后端分离项目&#xff0c;进行一体化打包&#xff0c;即 将前后端项目打在一个jar里面 一体化打包优点 不需要再使用nginx&#xff0c;直接将前端文件放到后端项目里面 改造ruoyi-vue项目 后端改造 1、引入依赖spring-boot-starter-thymeleaf &…

倒计时 1 天 | SphereEx 在 2023 亚马逊云科技中国峰会等你来打卡!

2023 年 6 月 27 - 28 日&#xff0c; “因构建而可见” 2023 亚马逊云科技中国峰会将在上海隆重举行&#xff0c;SphereEx 将携面向新一代数据架构的数据库增强引擎&#xff1a;SphereEx-DBPlusEngine 亮相亚马逊云科技中国峰会&#xff0c;展示分布式数据库、数据安全、信创替…

FFmpeg视频转码关键参数详解

1 固定码率因子crf&#xff08;Constant Rate Factor&#xff09; 固定码率因子&#xff08;CRF&#xff09;是 x264 和 x265 编码器的默认质量&#xff08;和码率控制&#xff09;设置。取值范围是 0 到 51&#xff0c;这其中越低的值&#xff0c;结果质量越好&#xff0c;同…

实力见证丨酷雷曼VR再获2项国家发明专利

近日&#xff0c;酷雷曼公司&#xff08;北京同创蓝天云科技有限公司&#xff09;再次喜获两项发明专利证书:“VR多端协同交互方法及相关设备”、“VR展示用户操作方法及相关设备” 。两项专利均基于酷雷曼3D VR系统发明&#xff0c;进一步优化了目前VR全景触控界面互动性及交互…

企业所得税高是怎么回事?该如何解决?

企业所得税高是怎么回事&#xff1f;该如何解决&#xff1f; 《税筹顾问》专注于园区招商、企业税务筹划&#xff0c;合理合规助力企业节税! 企业所得税高&#xff0c;一般企业都会运用一些税务筹划的方式来解决&#xff0c;那么事前的规划和搭建好业务框架就显得尤为重要。真…

FFmpeg初识

一、简介 它的官网为&#xff1a;https://ffmpeg.org/&#xff0c;由Fabrice Bellard&#xff08;法国著名程序员Born in 1972&#xff09;于2000年发起创建的开源项目。该人是个牛人&#xff0c;在很多领域都有很大的贡献。 FFmpeg是多媒体领域的万能工具。只要涉及音视频领域…

第43步 深度学习图像识别:InceptionResnetV2建模(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;InceptionResnetV2 InceptionResNetV2是一种由Google研究人员开发的深度学习模型&#xff0c;是一种混合了Inception和ResNet&#xff08;残差网络&#xff09;两种结构的卷积神经网络&#xff08;CNN&#…

通过cifar-10数据集理解numpy数组的长(H)、宽(W)、通道(C)

文章目录 1、CIFAR-10数据集介绍1.1 CIFAR-10数据集的构成1.2 batches.meta1.3 data_batch_n.py & test_batch.py 2、获取一张图片的data数据2.1 反序列化获得numpy数据2.2 清楚numpy中的H、W、C的含义2.3 清楚RGB图片在numpy中的表示 3、处理图片数据的代码 1、CIFAR-10数…

渗透测试实战-BurpSuite 使用入门

前言 近期笔者在学习 web 渗透测试的相关内容&#xff0c;主要是为了公司之后的安全产品服务。渗透测试本身在学习过程中还是很有意思的&#xff0c;有一种学习到了之前想学但是没学的黑客技术的感觉&#xff0c;并且对笔者已掌握的许多知识做了有益的补充。要学习渗透测试&…

ThinkPHP 对接美团大众点评团购券(门票)

一、功能简要介绍 1、根据需求&#xff0c;用户在美团大众点评中所购买的门票在自己的系统上可以核销&#xff0c;同时把核销信息存储到自己的系统里。2、美团点评API文档地址&#xff1a;[https://open.dianping.com/document/v2?rootDocId5000](https://open.dianping.com/…

PostgreSQL13.1

目录 1. PostgreSQL简介1.1 PostgreSQL是什么&#xff1f;1.2 PostgreSQL数据库的优缺点是什么&#xff1f;1.2.1 PostgreSQL的主要优点如下&#xff1a;1.2.2 PostgreSQL的应用劣势如下&#xff1a; 1.3 PostgreSQL不同大版本之间的特性比较1.4OpenGauss与PostgreSQL的对比1.4…

管理类联考——逻辑——知识篇——分析推理——三、分组——haimian

分组 题型特征 题干给出5-7个对象和2-5个限制条件&#xff0c;需根据题干要求分为2~3组。要注意题干中需分为几组&#xff0c;每组几个对象&#xff0c;对象有哪些限制因素&#xff0c;并灵活运用排除法、假设法、分析法、数字法、假言命题性质等方法解题。 思维导图 思路点…

技术管理第三板斧招聘与解聘-找到人

1.人才要自己去找、去抢 从团队的角度出发&#xff0c;Leader“主动出击、寻找合适人选”的观念符合逻辑&#xff0c;你既然是团队的一号位&#xff0c;自然最应该了解团队现状&#xff0c;以及团队需要的人选。与此同时&#xff0c;找到合适的人对你的影响最大而非 HR&#x…