Vue3之Vuex

2023-11-07

1. Vuex的基本使用

vuex的安装:

npm i vuex

vuex的配置,@/store/index.js:

import {createStore} from 'vuex'//导入createStore构造函数
export default createStore({ 
    state:{ //Vuex的状态,实际上就是存数据的地方
        person:{
            name:'jack',
            age:200
        }
    },
    getters:{ //提供获取Vux状态的方式, 注意在组件中调用时getPerson是以属性的方式被访问
        getPerson(state){
            return state.person
        }
    },
    mutations:{ //提供直接操作Vuex的方法,注意mutations里的方法中不能有任何异步操做
        ageGrow(state, value){
            //第一个参数state为Vuex状态;第二个参数为commit函数传来的值
            state.person.age += value
        }
    },
    actions:{ //提供通过mutations方法来简介操作Vuex的方法
        ageGrow(context, value){ 
            //第一个参数context为上下文,提供一些方法;第二个参数为dispatch函数传来的值
            context.commit('ageGrow', value)
        }
    }, 
})

在@/main.js中引入:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')

在组件中使用Vuex:

<template>
    <h1>名字:{{person.name}}--年龄:{{person.age}}</h1>
    <input type="text" v-model="value">
    <button @click="ageGrow(value)">增加年龄</button>
    <!-- 在input框输入一个数字,点击按钮,可以看到年龄发生变化,说明Vuex正常工作 -->
</template>

<script>
    import {useStore} from 'vuex' 
    import {ref} from 'vue'
    export default {
        setup(){
            const store = useStore()    //获取store对象
            let person = store.getters.getPerson    //从组件中获取状态(数据)person 方式一
            // let person = store.state.person      //从组件中获取状态(数据)person 方式二
            let value = ref('输入年龄的增量')
            function ageGrow(ageGrowth){
                ageGrowth = parseInt(ageGrowth)
                if(isNaN(ageGrowth)){
                    ageGrowth = 0
                }
                store.dispatch('ageGrow', ageGrowth)
                //通过dispatch来调用actions里的'ageGrow'方法,参数为ageGrowth
               	//actions的方法又会通过commit来调用mutations里的方法,从而引起状态(数据)的变化
               	//也可以在组件里跳过dispatch actions,直接store.commit
            }
            return {
                person, 
                value,
                ageGrow
            }
        }
    }
</script>
<style></style>

把代码复制粘贴到脚手架中运行,可以看到直观的效果,有助于理解。

小结:安装完vuex之后,首先要用creatRouter构造函数创建一个router对象,并在main.js中引入这个对象。然后在组件中,通过userStore方法来获取这个router对象,进一步通过getter或者state可以得到Vuex状态(数据),通过dispatch->actions->mutations->state的数据传送方式可以操作和改变Vuex的状态(数据)

2. Module

Vuex官方原话:“由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。”

什么叫单一状态树呢,其实就是上文中的state对象。在Vuex的基本使用中,我们使用state对象来存储Vuex的状态,state对象里面可以嵌套其他的对象,它是一个树形的结构,而且这个state对象是唯一的,所有的状态都要存储在这一个对象里。因此,我们称之为单一状态树。
这种单一状态树的弊端是显而易见的,对于中大型项目来说,要托管给Vuex的状态有很多,把这些海量的数据如果都塞到一个文件里面的一个对象里面,未免显得过于臃肿,不管是开发起来还是维护起来都会有很多不变。
对此,官方给出了解决方案:

“为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割”

2.1 vuex中模块化的基本使用

vuex的模块化没什么难理解的,就是把store给拆开,一个对象拆成多个对象,一个文件拆成多个文件,并且彼此可以拥有独立的命名空间。
道理很简单,所以直接看样例:

文件结构

├──src
   ├── components
   │   └── Test.vue
   └── store
       ├── index.js
       └── modules
           ├── male.js
           └── female.js

index.js

import {createStore} from 'vuex'
import female from './modules/female'   //导入模块
import male from './modules/male'       //导入模块
export default createStore({ 
    modules:{   //使用模块
        female,
        male
    }
})

male.js

export default {
    namespaced:true,    //namespaced:true代表该模块带有独立命名空间
    state:{             //否则,默认是处于全局命名空间,就和非模块化一样
        personList:[
            {name:'张飞', id:'004'},
            {name:'武则天', id:'005'},
            {name:'秀吉', id:'006'},
        ]
    },
    mutations:{
        addMutation(state, value){      //往personList中添加一个人
            state.personList.push(value)
        },
        removeMutaion(state, value){    //往personList中删除一个人
            state.personList = state.personList.filter((el) => el.id != value.id)
        }
    },
    actions:{
        addAction(context, value){
            setTimeout(() => {
                context.commit('addMutation', value) // ->'male/addMutation'
            }, 1000);
        },
        removeAction(context, value){
            context.commit('removeMutaion', value)
        }
    },
    getters:{
        personList(state){
            return state.personList
        }
    }
}

female.js

export default {
    namespaced:true,    //namespaced:true代表该模块带有独立命名空间
    state:{             //否则,默认是处于全局命名空间,就和非模块化一样
        personList:[
            {name:'李白', id:'001'},
            {name:'孙尚香', id:'002'},
            {name:'大乔', id:'003'},
        ]
    },
    mutations:{
        addMutation(state, value){      //往personList中添加一个人
            state.personList.push(value)
        },
        removeMutaion(state, value){    //往personList中删除一个人
            state.personList = state.personList.filter((el) => el.id != value.id)
        }
    },
    actions:{
        addAction(context, value){
            setTimeout(() => {
                context.commit('addMutation', value) // ->'female/addMutation'
            }, 1000);
        },
        removeAction(context, value){
            context.commit('removeMutaion', value)
        }
    },
    getters:{
        personList(state){
            return state.personList
        }
    }
}

Test.vue

<template>
    <h1>女人:</h1>
    <li v-for="femalePerson in femalePersons" :key="femalePerson.id">
        {{femalePerson.name}}
        <button @click="addToMale(femalePerson)">添加到男人</button>
    </li>
    <h1>男人:</h1>
    <li v-for="malePerson in malePersons" :key="malePerson.id">
        {{malePerson.name}}
        <button @click="addToFemale(malePerson)">添加到女人</button>
    </li>
    <!-- 有两个列表,分布是男人和女人,通过点击按钮可以把列表中的某些项添加到另一个列表中 -->
    <!-- 建议粘贴复制并运行代码,这样更直观 -->
</template>

<script>
    import { computed } from '@vue/runtime-core';
    import {useStore} from 'vuex'
    export default {
        setup(){
            let store = useStore()
            let malePersons = computed(() => store.getters['male/personList']) //通过getter获取state
            let femalePersons = computed(() => store.state.female.personList)   //直接获取state
            function addToMale(person){
                store.dispatch('male/addAction', person)
                store.dispatch('female/removeAction', person)
                //如果模块中namespaced === true,那么要在方法名前面添加模块的逻辑路径
                //index.js里使用的模块为路径的起点。
                //比如index里面有一个moduleA,moduleA有一个子模块moduleB,module有一个action是actionx
                //那么调用方式为 store.dispatch('moduleA/moduleB/actionx', value)
            }
            function addToFemale(person){
                store.dispatch('female/addAction', person)
                store.dispatch('male/removeAction', person)
            }
            return {
                malePersons,
                femalePersons,
                addToMale,
                addToFemale
            }
        }
    }
</script>
<style></style>

2.2 在命名空间中访问全局内容

什么是全局内容?不在同一个模块中的内容就是全局内容。
比如,对于上文中的female模块来说,male模块中的getters state action mutations就是全局内容,接下来将会讲解如何在一个模块中访问到全局内容。
为了便于理解,我创造了一个新的样例:

├──src
   ├── components
   │   └── Test.vue
   └── store
       ├── index.js
       └── modules
           ├── moduleA.js
           └── moduleB.js

index是所有的模块的根,moduleA和moduleB是两个子模块,接下来要做的事情就是在index.js、moduleA.js、moduleB.js中写一些getters state action mutations,最终达成的效果是在index中访问moduleA的内容,在moduleA中访问moduleB的内容,在moduleB中访问index的内容。

index.js:

import {createStore} from 'vuex'
import moduleA from './modules/moduleA'   //导入模块
import moduleB from './modules/moduleB'       //导入模块
export default createStore({ 
    state:{info:{name:'root', num:100}},
    getters:{
        state: state => state,
        moduleAStateThroughRoot: (state, getters, rootState, rootGetters) => {
            //在getter中访问全局内容
            //rootState为根状态,rootGetters为根getters,这两个属性是访问全局内容的工具
            //通过模块A的来获得root的状态

            //因为这里本身就是模块的根,所以这里的state和rootState、getters和rootGetters是一个东西
            // console.log(state === rootState, getters === rootGetters); // true true

            return rootGetters['moduleA/state']
            // return rootState.moduleA
        }
    },
    actions:{addAction: (context, value) => {context.commit('moduleA/addMutation', value)}},
    mutations:{addMutation: (state, value) => {state.info.num += value}},
    modules:{   //使用模块
        moduleA,
        moduleB
    }
})

moduleA.js:

export default {
    namespaced :true,
    state:{info:{name:'moduleA', num:200}},
    getters:{
        state: state => state,
        moduleBStateThroughModuleA: (state, getters, rootState, rootGetters) => {
            //在getter中访问全局内容
            //rootState为根状态,rootGetters为根getters,这两个属性是访问全局内容的工具
            //通过模块B的来获得模块A的状态

            // return rootState.moduleB
            return rootGetters['moduleB/state']
        }
    },
    actions:{
        addAction: (context, value) => {context.commit('moduleB/addMutation', value, {root:true})},
        //context中包含dispatch, commit, getters, rootGetters
        //在action中调用全局mutation,只需要在commit函数中添加第三个参数{root:true},这样第一个参数就会被当作全局内容来解析。
        //在action中调用全局action,与上述同理。
        //同时,还可通过rootGetters访问全局getters
        
        globalAction:{
            root: true, //添加root:true属性,即可把globalAction注册为全局action,具体内容写在handler中
            handler: (context, value) => {      //虽然是全局action,但参数中的上下文context仍然是局部的
                alert(context.state.info.name)  //弹出应该是moduleA
            }
        }
    },
    mutations:{addMutation: (state, value) => {state.info.num += value}},
}

moduleB.js

export default {
    namespaced :true,
    state:{info:{name:'moduleB', num:300}},
    getters:{
        state: state => state ,
        rootStateThroughModuleB:(state, getters, rootState, rootGetters) => {
            //在getter中访问全局内容
            //rootState为根状态,rootGetters为根getters
            //通过root的来获得模块B的状态

            return rootGetters['state']
            // return rootState
        }
    },
    actions:{addAction: (context, value) => {context.commit('addMutation', value, {root:true})}},
    //context中包含dispatch, commit, getters, rootGetters
    //在action中调用全局mutation,只需要在commit函数中添加第三个参数{root:true},这样第一个参数就会被当作全局内容来解析。
    //在action中调用全局action,与上述同理。
    //同时,还可通过rootGetters访问全局getters
    mutations:{addMutation: (state, value) => {state.info.num += value}},
}

Test.vue:

<template>
    <li> {{rootModule.name}}---{{rootModule.num}} <button @click="rootClick">rootAction---A++</button> </li>
    <li> {{moduleA.name}}---{{moduleA.num}} <button @click="aClick">moduleAction---B++</button> </li>
    <li> {{moduleB.name}}---{{moduleB.num}} <button @click="bClick">moduleAction---root++</button> </li>
    <!-- 点击root,moduleA数字加一;点击moduleA,moduleB数字加一;点击moduleB,root数字加一 -->
    <button @click="store.dispatch('globalAction')">触发全局action</button>
</template>

<script>
    import {useStore} from 'vuex'
    export default {
        setup(){
            let store = useStore()
            console.log(store.getters);
            let rootModule = store.getters['moduleB/rootStateThroughModuleB'].info //通过moduleB的getters获得root的状态
            let moduleA = store.getters['moduleAStateThroughRoot'].info            //通过root的getters获得moduleA的状态
            let moduleB = store.getters['moduleA/moduleBStateThroughModuleA'].info //通过moduleA的getters获得moduleB的状态
            // let moduleB = store.state.moduleB.info
            // let moduleA = store.state.moduleA.info
            // let rootModule = store.state.info
            function rootClick(){store.dispatch('addAction', 1)}    //调用root中的action,改变的是moduleA的状态
            function aClick(){store.dispatch('moduleA/addAction', 1)}//调用moduleA中的action,改变的是moduleB的状态
            function bClick(){store.dispatch('moduleB/addAction', 1)}//调用moduleB中的action,改变的是root的状态
            return {rootModule,moduleA,moduleB,rootClick,aClick,bClick,store}
        }
    }
</script>
<style></style>

在模块中使用vuex

// import { State } from "@/type/test";
// import { useStore } from "vuex";
// const store = useStore()

/* 
    在模块中使用vuex时,上面的方式得到的store.state是undefined,下面这种方式才能正常得到state
    不知道是什么原因
*/


import store from '../store'
export function increase(){
    console.log(store.state)
}

3. vuex的typescript用法

vuex的typescript用法其实就是把state加上ts里的类型限制

3.1 不使用模块化

store文件

// store.ts
import { InjectionKey } from 'vue'
import { createStore, Store } from 'vuex'

// 为 store state 声明类型
export interface State {
  count: number
}

// 定义 injection key
export const key: InjectionKey<Store<State>> = Symbol()

export const store = createStore<State>({
  state: {
    count: 0
  }
})

在main.ts里引入

// main.ts
import { createApp } from 'vue'
import { store, key } from './store'

const app = createApp({ ... })

// 传入 injection key
app.use(store, key)

app.mount('#app')

在组件中使用useStore()获取store,将上述 injection key 传入 useStore 方法可以获取类型化的 store。

// vue 组件
import { useStore } from 'vuex'
import { key } from './store'

export default {
  setup () {
    const store = useStore(key)

    store.state.count // 类型为 number
  }
}

在每个组件中都导入key有些重复且麻烦,我们可以将useStore()封装成myUseStore()

// 在store.ts增加下面几行
import { useStore } from 'vuex'
export function myUseStore () {
  return useStore(key)
}

3.2 使用模块化

store/index.ts

import { createStore, Store  } from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'
import { InjectionKey } from 'vue'

//模块A state的类型
interface moduleAState {
	name:string,
	age:number
}

//模块B state的类型
interface moduleBState {
	id:string,
	adult:boolean
}

//vuex state类型
interface State{
	moduleA:moduleAState,
	moduleB:moduleBState 
}


//如果使用模块化的话,在createStore参数里面就不要写state了,否则会报错
export const key: InjectionKey<Store<State>> = Symbol()
export const store =  createStore<State>({
  // state:{}, //不可以加这一行,否则报错
  modules: {
    moduleA,
    moduleB
  }
})

在组件中访问:

// vue 组件
import { useStore } from 'vuex'
import { key } from './store'

export default {
  setup () {
    const store = useStore(key)

    store.state.moduleA// 类型为 moduleAState
    store.state.moduleB// 类型为 moduleBState
  }
}

待更新

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue3之Vuex 的相关文章

  • 如何更改 vuetify v2 中 scss 中的断点?

    我正在使用 scss 文件 我想更改 vuetify v2 中 css 端的断点 我在 vuetify 升级指南中找不到任何参考 在 1 5 版本中我做了 style x styl grid breakpoints xs 0 sm 476p
  • 以编程方式将焦点设置在 Vuetify 中的按钮上

    我试图在每次打开 v 对话框时将操作按钮集中在 v 对话框中 我尝试使用自动对焦 但它只能工作一次 通常在 Vuetify 中 您可以通过添加引用然后调用 focus 函数来将焦点设置在元素上 如下所示
  • 查询 Firestore 中的特定日期

    我正在尝试查询 Firestore 中的指定日期 到目前为止我已经尝试过这段代码 let ref db collection schools doc DglhflywuybkOuCq7tGW let start new Date 2018
  • 如何在VueJS中将所有事件传递给父级

    传递道具 In VueJS如果你设置inheritAttrs to false并使用v bind attrs 您将组件中未声明的所有 props 传递给其子组件 是否有类似的方法将来自子级的所有事件传递给其父级VueJS 代码示例 Wrap
  • Vue - 如何附加组件?

    我正在尝试创建一个按钮 一旦按下该按钮 就会向我的组件添加一个子组件 我的代码可以工作 只是 HTML 被解析为字符串 这是父组件
  • bootstrap-vue 与 b 表中的复选框相关的问题

    我在使复选框正常工作时遇到问题 为 选定 槽中的每一行呈现的复选框未绑定到正确的行 当您单击该复选框时 它将顶行的复选框设置为真 假位置 问题 1 如何将行复选框的真 假状态绑定到其行项目 我试图将其绑定到 data item select
  • 使用 v-bind Vue.js 的多个变量

    我试图在以下代码中传递多个变量 div div 但我收到以下错误 Vue warn 无法生成渲染函数 SyntaxError 意外的标记 在 我尝试更换 with a 但我得到 Vue warn 无法生成渲染函数 SyntaxError I
  • Vue Cli 3 禁用代码分割 - 无法删除哈希文件

    我有一个vue config js设置效果很好 并取消了默认的代码分割 但它仍然输出一个 CSS 文件 其哈希值与具有好名称的 CSS 文件相同 我可以编写一个脚本来删除它 但我想知道是否有一种方法可以将文件设置为不输出带有哈希的CSS文件
  • Cypress Vue 组件测试从已挂载发出的事件

    我有一个 vue2 组件 它在其安装的生命周期挂钩中发出一个事件 该事件被发出 并且可以由使用该组件的页面处理 但是 我还想测试该事件是否在我的组件测试中发出 该测试使用赛普拉斯组件测试运行程序 这是一个精简版本 组件 TheCompone
  • 如何在vue中覆盖materializecss sass变量?

    我想改变物化中的变量 变量 scss https github com Dogfalo materialize blob master sass components variables scss e g primary color col
  • 运行 npmserve 时收到错误消息模块构建失败(来自 ./node_modules/sass-loader/dist/cjs.js)

    我现在从事 Vue Vuetify 项目已经有一段时间了 直到昨天一切都运转良好 我在使用时遇到问题
  • 在 docker 容器内运行 vite 开发服务器

    我有一个 Vue cli 应用程序 我正在尝试将其转换为 vite 我正在使用 Docker 来运行服务器 我看了几个教程 并让 vite 在开发模式下运行 没有错误 但是 浏览器无法访问该端口 也就是说 当我在 macbook 的命令行上
  • Vue.js 严格模式下不允许对一个属性进行多个定义

    再会 我们正在使用 Vuejs Vuex vue router 构建我们的应用程序https github com vuejs vue hackernews 2 0 https github com vuejs vue hackernews
  • 从vue中的api加载路由

    我正在尝试从我的 API 在 Vue 应用程序中加载路由 我尝试将数据推送到路由变量并使用 addRoutes 方法 但没有运气 我认为异步可能存在问题 但为什么 addRoutes 不起作用 这是我的代码 import Vue from
  • Webpack 不包括 ProvidePlugins

    我正在开发一个小型试用 Web 应用程序 它使用 vue webpack 模板 https github com vuejs templates webpack https github com vuejs templates webpac
  • 组件内调用 Mixin 的方法(Vuejs)

    我无法从组件调用 mixin 方法 出现此错误this hello is not a function 我可以打电话hello 来自 Vue 实例 但我无法在组件内调用它 有什么事吗 div div
  • 观察者不触发

    我正在使用带有选项 API 的 Vue 3 如下面发布的代码所示 在watch对象 我监视发生的变化isToggleBtnLabelDigitizePolygon 在方法中onDigitizePolygon我改变的值isToggleBtnL
  • 如何在外部 .js 文件中分离 .vue 组件的方法?

    我的组件留下了许多行代码 因此我决定将这些方法放在一个名为functions js 的单独文件中 我无法调用这些方法 我试过这个 函数 js function sendList function getLists function dele
  • 仅当内容超过两行时显示只读/隐藏按钮

    我正在创建一个评论部分 类似于 youtube 的东西 并且我希望能够在 content 有多行时显示阅读更多 隐藏按钮 这就是我到目前为止所做的 我的阅读更多 隐藏按钮可以工作 因为我添加了一个计算的线夹 使内容仅在存在多行时才显示两行
  • vue:转义并渲染 HTML 字符串?

    我正在尝试在模板中渲染一些 HTML 字符串 但我希望它们是字符串 我不想渲染 富文本 我开始于

随机推荐

  • SpringBoot2对接线程池

    SpringBoot2对接线程池 1 配置线程池Bean package com itennishy test config import java util concurrent ThreadPoolExecutor import org
  • Qt中extern全局变量的使用

    参考网址 https blog csdn net Soar dream article details 101025153 https blog csdn net weixin 45571586 article details 118109
  • C语言位操作

    C语言位操作 1 位与 按照二进制位一一对应 只有全1才为真 否则为假 特定位置置0用位与 2 位或 按照二进制 有真则真 全假才假 特定位置置1用位或 3 位取反 按照二进制位 1变为0 0变为1 逻辑取反 数当成整体 不变二进制 不是0
  • 错误 Angular2 Can't bind to 'routerLink' since it isn't a known property of 'a'

    Can t bind to routerLink since it isn t a known property of a 解决办法 检查是否没有 import RouterModule import RouterModule from a
  • 阿里java编程规范之异常处理、安全规约、MySql数据库

    注 本文内容整理自 阿里java编码规范 除 编程规约 外的其它规则 异常处理 强制 1 Java类库中可以通过预检查方式规避的 RuntimeException不应该通过catch的方式来处理 如 IndexOutOfBoundsExce
  • LruCache基本使用和原理分析

    最近在研究时区问题时 时区的底层实现涉及到BasicLruCache集合的使用 故而对LruCache做了部分的了解 BasicLruCache 是 Android 提供的一个简单的 LRU 缓存实现 但在标准的 Java 类库中并不存在
  • 基于SpringBoot的校园志愿者管理系统

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SpringBoot 前端 HTML Vue 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse
  • windows 安装 minio

    windows 安装 minio 1 通过powershell 安装 Invoke WebRequest Uri https dl min io server minio release windows amd64 minio exe Ou
  • 小试一下Google App Engine

    这两天关心了一下云 所以也看到google app engine了 今天小小试了一下 做下记录 主页 登录http code google com intl zh CN appengine 下载 App Engine SDK GoogleA
  • 使用StarRocks导入大数据:详细教程及示例代码

    使用StarRocks导入大数据 详细教程及示例代码 StarRocks是一个快速 可扩展的大数据分析引擎 它提供了高性能的数据导入功能 在本文中 我们将介绍如何使用StarRocks导入大数据 并提供相应的示例代码 步骤1 准备工作 在开
  • 云计算平台常用命令

    云计算IAAS篇 mysql篇 mysql uroot p000000 使用root账号登录mysql use mysql 切换到mysql层 show tables 查询mysql数据库列表 select from mysq
  • linux高性能服务器开发之TCP/IP协议族(1)

    TCP IP协议族体系结构以及主要协议 每层协议完成不一样的功能 上层协议得借助下层协议提供的服务 计网 数据链物层 数据链物层实现网卡接口的网络驱动程序 网络驱动程序隐藏一些 物理层不同电气特性 为上层提供一个统一的接口 常用的协议ARR
  • 【中兴ZXV10 B860A1.1】

    这里写自定义目录标题 开启adb 开启adb 部分盒子的ADB调试位置 在设置页面中可以有开启开发者选项 地区界面不同 位置不同有的在设置里 如果找不到 直接按住遥控器 返回 不放 5秒后 快速不停按 左键 点击 打开ADB调试 这时侯让你
  • 2021-08-04 读书笔记:Python 学习手册(2)

    读书笔记 Python 学习手册 2 结于2021 08 04 OREILY的书籍 可读性很强 入门类 而且这本书很厚 第三部分 语句和语法 第四部分 函数 第三部分 语句和语法 第10章 Python语句简介 Python是面向过程的 基
  • 程序或-内存区域分配(五个段)--终于搞明白了

    一 在学习之前我们先看看ELF文件 ELF分为三种类型 o 可重定位文件 relocalble file 可执行文件以及共享库 shared library 三种格式基本上从结构上是一样的 只是具体到每一个结构不同 下面我们就从整体上看看这
  • DC系列漏洞靶场-渗透测试学习复现(DC-1)

    最近闲着冲浪玩发现了DC系列漏洞靶场 下载了8个靶场 DC 1到DC 8 从信息收集到最后拿到超级管理员权限 可以说几乎贯穿了渗透测试的每一步 寻找一个个flag 通过flag中的指引内容 帮助我们拿到最后的root身份 过程还是挺有趣的
  • Jvm之垃圾回收机制

    判断一个对象是否可被回收 1 引用计数算法 给对象添加一个引用计数器 当对象增加一个引用时计数器加 1 引用失效时计数器减 1 引用计数为 0 的对象可被回收 两个对象出现循环引用的情况下 此时引用计数器永远不为 0 导致无法对它们进行回收
  • vue中使用闭包(例如防抖和节流)失效问题(直接调用)

    文章目录 1 出现问题 2 问题原因 3 解决办法 4 防抖节流函数 1 出现问题 防抖 节流使用无效 例如防抖 按钮点击多次依旧执行多次 gt 查看是闭包无效 定义的局部变量依旧为初值 gt 没有相应清除定时器
  • Ubuntu安装MonoDevelop

    安装步骤 在ubuntu终端执行下面步骤代码 第一步 安装源 根据自己的版本在Ubuntu上安装Mono 运行下面代码授权注册repo源并更新软件列表 Ubuntu 18 04 sudo apt install apt transport
  • Vue3之Vuex

    1 Vuex的基本使用 2 Module 2 1 vuex中模块化的基本使用 2 2 在命名空间中访问全局内容 3 vuex的typescript用法 3 1 不使用模块化 3 2 使用模块化 1 Vuex的基本使用 vuex的安装 npm