Vuex 笔记

news/2024/4/29 17:00:45/文章来源:https://blog.csdn.net/ftell/article/details/128036184

文章目录

  • 1 Vuex 简介
  • 2 Vuex 用法
    • 2.1 安装 vuex
    • 2.2 修改 `main.js`,
    • 2.3 使用 mutation 改变 Store:
    • 2.4 带参数的 mutations:
    • 2.5 使用 `getters` 读取 store 数据
    • 2.6 使用 `actions` 执行异步代码
    • 2.7 总结
    • 2.8 使用 mapper 简化代码
    • 2.9 使用模块组织 store
    • 2.10 模块名字空间
      • 2.10.1 `getters` 对应修改如下:
      • 2.10.2 `mapGetters` 对应修改如下:
      • 2.10.3 `mapActions` 对应修改如下:
      • 2.10.4 `dispatch` 对应修改如下:
    • 2.11 设计 Vuex 代码与文件的结构
      • 2.11.1 将 store 相关代码放到一个单独的文件 `store.js` 中
      • 2.11.2 继续重构上述 `store.js` 文件

1 Vuex 简介

Vuex 是一个管理全局状态的库。
状态即数据,即 app 呈现的数据,或 app 需要的数据。
状态分为全局状态和局部状态。局部状态只影响一个组件,全局状态影响若干组件,或者影响整个 app,例如:用户认证数据,购物车等。
Vuex 用于管理全局状态,用于取代 provide, inject 方法。

provideinject 方法具有以下缺点:

  1. 容易出现“胖组件”,即某个组件具有庞大的逻辑与数据,
  2. 不可预测,数据以何种方式被修改并非一目了然。
  3. 容易出错,比如状态没有更新,或无意中被更新。

使用 Vuex,将状态管理代码从组件中提取出来。

2 Vuex 用法

2.1 安装 vuex

npm install vuex@next

2.2 修改 main.js,

原始代码:

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

增加 vuex:

import { createApp } from 'vue';
import { createStore } from 'vuex';import App from './App.vue';const store = createStore({state() {return {counter: 0,};},
});
const app = createApp(App);
app.use(store);app.mount('#app');

然后整个 App 的任意组件都能使用此 state 数据, 例如在 App.vue 中:

<template><base-container title="Vuex"><h3>{{ $store.state.counter }}</h3><button>Add 1</button></base-container>
</template><script>
import BaseContainer from './components/BaseContainer.vue';export default {components: {BaseContainer,},
};
</script>

$store 指向 Vuex store, 因此可以用 $store.state.counter 访问 counter

2.3 使用 mutation 改变 Store:

以下代码直接在某个组件中修改 store 数据,虽然可行,但不可取,过于灵活则容易出错:

<template><base-container title="Vuex"><the-counter></the-counter><button @click="addOne">Add 1</button></base-container>
</template><script>
import BaseContainer from './components/BaseContainer.vue';
import TheCounter from './components/TheCounter.vue';export default {components: {BaseContainer,TheCounter,},methods: {addOne() {// bad practice!!this.$store.state.counter++;},},
};
</script>

为了实现代码重用,避免代码混乱,应该将修改状态的代码统一放到 createStoremutations 属性中,
mutations 中的方法自动获得当前 state 为参数:

const store = createStore({state() {return {counter: 0,};},mutations: {increment(state) {state.counter = state.counter + 2;},},
});

在其他组件如何使用此 mutation:

<script>
export default {methods: {addOne() {// old way and bad practice// this.$store.state.counter = this.$store.state.counter += 2;this.$store.commit('increment');},},
};

2.4 带参数的 mutations:

这里的参数又称为 payload, 可以是任意数据类型,例如数字、字符串或对象等。

  mutations: {increment(state) {state.counter = state.counter += 2},increase(state, payload) {// 假定这里 payload 是一个具有 myValue 属性的对象:state.counter = state.counter + payload.myValue;}}

对应用法,传递参数给 mutation:

  methods: {addTen() {this.$store.commit('increase', { myValue: 10 });},},

上面的写法也可以改成:

  methods: {addTen() {// 一种写法// this.$store.commit('increase', { myValue: 10 });// 另一种等价的写法:this.$store.commit({type: "increase",myValue: 10,});},},

对于这种写法,不带 type 属性的对象将作为 payload 传递给 mutation,两种写法等价。

2.5 使用 getters 读取 store 数据

getters 相当于定义在 store 中的计算属性。
getters, mutations, state, 前后顺序任意。
getters 中的任何方法都自动获得两个参数:当前状态 state,以及其他 getters, 这一 getters 中的 getters,如果当前方法需要其他 getter 的结果就可以被用到。
getter 必须返回值。

const store = createStore({state() {...},mutations: {...},getters: {// finalCounter(state, getters)// state:当前状态,// getters: 必要时用于获取其他 getter 的结果finalCounter(state) {return state.counter * 2;},},
});

使用 getters

<script>
export default {computed: {counter() {// return this.$store.state.counter;// 仅指向,不能执行,finalCounter 后没有括号。return this.$store.getters.finalCounter;},},
};
</script>

多个 getters 之间可以互相依赖,例如, 下列代码中的 normalizedCounterfinalCounter 限定在 0 ~ 100 之间,不需要使用 state.counter * 3 重新计算一遍,因为使用 getters.finalCounter 就可以直接获取结果值:

getters: {finalCounter(state) {return state.counter * 3;},// state 参数不会用到,用 _ 代替,同 go 语法normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100} else {return finalCounter;}}},

2.6 使用 actions 执行异步代码

问题:mutations同步, 不允许包含异步代码。
组件应该先触发 actions,再由 actions commit mutations, actions 可以执行异步代码。
虽然组件可以直接 commit mutations, 但好的写法总是在组件与 mutations 之间使用 actions.

actions 中的方法名可以与 mutations 中的方法名相同, 可以不同,但一般使用相同名称.
actions 中的方法自动获得 context 参数:

 actions: {increment(context) {// 类似于组件中使用`commit`, 这里可以写成:context.commit("increment", some_payload);// 也可以写成 context.commit({type: "increment", someValue: something});context.commit("increment");}}

可以使用 context 参数访问其他 store 模块中的数据,例如:

actions: {addToCart(context, payload) {const prodId = payload.id;const products = context.rootGetters['prods/products'];const product = products.filter(prod => prod.id === prodId);context.commit('addProductToCart', product);
},

actions 中的代码可以改为异步,例如:

  actions: {increment(context) {setTimeout(() => {context.commit('increment');}, 3000);},// 自动获得参数 payloadincrease(context, payload) {// 在 commit 之前,payload 可以自行修改,不必完全相同。context.commit('increase', payload);},},

http 请求之类的异步代码可以放在 actions 中,使用 actions,通过 dispatch 调用, 用法举例:

methods: {addTen() {// 1. 一种传参数写法// this.$store.commit('increase', { myValue: 10 });// 2. 另一种等价的传参数写法// this.$store.commit({ type: 'increase', myValue: 10 });// 3. 改为调用 actions, commit 改为 dispatch, 二者调用语法基本相同this.$store.dispatch({ type: 'increase', myValue: 10 });},},

以及

 methods: {addTwo() {// this.$store.state.counter = this.$store.state.counter += 2;this.$store.dispatch('increment');},},

简单地说,总是使用 dispatch 调用 actions 中的方法就可以,mutations 的方法最好不要直接调用。

对于 actions 的方法中的 context 参数,如果调用 console.log(context):
在这里插入图片描述
可以在 action 中 dispatch 另一个 action,可以调用 getters.
不应在 actions 中直接修改 state,而应该总是通过 mutations 修改。

2.7 总结

Vuex 由 state, mutations, actions, getters 4 部分组成。
main.js sample code:

import { createApp } from 'vue';
import { createStore } from 'vuex';import App from './App.vue';const store = createStore({state() {return {counter: 0,};},mutations: {increment(state) {state.counter = state.counter += 2;},increase(state, payload) {// 假定这里 payload 是一个具有 myValue 属性的对象:state.counter = state.counter + payload.myValue;},},actions: {increment(context) {setTimeout(function () {context.commit('increment');}, 3000);},increase(context, payload) {context.commit('increase', payload);console.log(context);},},getters: {finalCounter(state) {return state.counter * 3;},// state 参数不会用到,用 _ 代替,同 go 语法normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100;} else {return finalCounter;}},},
});
const app = createApp(App);
app.use(store);app.mount('#app');

2.8 使用 mapper 简化代码

mapper 是一个 utility feature,使用此工具可以少写一些代码。
例如使用 getters 相关代码:

<template><h3>{{ counter }}</h3>
</template><script>
export default {computed: {counter() {return this.$store.getters.finalCounter;},},
};
</script>

改为使用 mapper:

<template><h3>{{ finalCounter }}</h3>
</template><script>
import { mapGetters } from 'vuex';
export default {computed: {// counter() {//   return this.$store.getters.finalCounter;// },...mapGetters(['finalCounter']),},
};
</script>

statemutations 在组件中不会直接访问,跳过,使用 actions的相关代码:

<template><button @click="addTwo">Add 2</button>
</template><script>
export default {methods: {addTwo() {this.$store.dispatch('increment');},},
};
</script>

改为使用 mapper,仅作为演示,多加了一个 increase,因此也多加了一个 button

<template><button @click="increment">Add 2</button><button @click="increase({ myValue: 10 })">Add 2</button>
</template><script>
import { mapActions } from 'vuex';
export default {methods: {// addTwo() {//   this.$store.dispatch('increment');// },// 类似于 mapGetters, 获得一个对象,与 methods 对象合并...mapActions(['increment', 'increase']),},
};
</script>

还可以将 methods 名称改为自己想要的名称:

...mapActions(['increment', 'increase']),

改为:

 ...mapActions({inc:'increment',increase: 'increase',})

完整代码段:

<template><button @click="inc">Add 2</button><button @click="increase({ myValue: 11 })">Add 11</button>
</template><script>
import { mapActions } from 'vuex';
export default {methods: {// addTwo() {//   this.$store.dispatch('increment');// },// 类似于 mapGetters, 获得一个对象,与 methods 对象合并// ...mapActions(['increment', 'increase']),...mapActions({inc:'increment',increase: 'increase',})},
};
</script>

这种使用对象修改名称的做法同样适用于 mapGetters,

2.9 使用模块组织 store

为了更好地管理代码,可以将 store 划分成多个模块,store 中数据分两部分,一部分和 counter 有关,一部分和用户认证有关,一开始的代码如下:

import { createApp } from 'vue';
import { createStore } from 'vuex';import App from './App.vue';const store = createStore({state() {return {counter: 0,isLoggedIn: false,};},mutations: {increment(state) {state.counter = state.counter += 2;},increase(state, payload) {// 假定这里 payload 是一个具有 myValue 属性的对象:state.counter = state.counter + payload.myValue;},setAuth(state, payload) {state.isLoggedIn = payload.isAuth;},},actions: {increment(context) {setTimeout(function () {context.commit('increment');}, 3000);},increase(context, payload) {context.commit('increase', payload);console.log(context);},login(context) {context.commit('setAuth', { isAuth: true });},logout(context) {context.commit('setAuth', { isAuth: false });},},getters: {finalCounter(state) {return state.counter * 3;},userIsAuthenticated(state) {return state.isLoggedIn;},// state 参数不会用到,用 _ 代替,同 go 语法normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100;} else {return finalCounter;}},},
});
const app = createApp(App);
app.use(store);app.mount('#app');

这个 store 混合了两部分内容,而实际中文件可能更大。现在将代码重构,将与 counter 相关代码移出来,放到一个常量 counterModule 中:

const counterModule = {state() {return {counter: 0,};},mutations: {increment(state) {state.counter = state.counter += 2;},increase(state, payload) {// 假定这里 payload 是一个具有 myValue 属性的对象:state.counter = state.counter + payload.myValue;},},actions: {increment(context) {setTimeout(function () {context.commit('increment');}, 3000);},increase(context, payload) {context.commit('increase', payload);console.log(context);},},getters: {finalCounter(state) {return state.counter * 3;},// state 参数不会用到,用 _ 代替,同 go 语法normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100;} else {return finalCounter;}},},
};

然后 createStore 中使用 modules 属性将 counterModule合并到 store 中:

import { createApp } from 'vue';
import { createStore } from 'vuex';import App from './App.vue';const counterModule = {state() {return {counter: 0,};},mutations: {increment(state) {state.counter = state.counter += 2;},increase(state, payload) {state.counter = state.counter + payload.myValue;},},actions: {increment(context) {setTimeout(function () {context.commit('increment');}, 3000);},increase(context, payload) {context.commit('increase', payload);console.log(context);},},getters: {finalCounter(state) {return state.counter * 3;},normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100;} else {return finalCounter;}},},
};const store = createStore({// 使用 modules 属性合并其他代码modules: {// 标识符:模块名numbers: counterModule,},state() {return {isLoggedIn: false,};},mutations: {setAuth(state, payload) {state.isLoggedIn = payload.isAuth;},},actions: {login(context) {context.commit('setAuth', { isAuth: true });},logout(context) {context.commit('setAuth', { isAuth: false });},},getters: {userIsAuthenticated(state) {return state.isLoggedIn;},},
});
const app = createApp(App);
app.use(store);
app.mount('#app');

使用 counterModule 模块中的 state 无法访问 isLoggedIn,
如果一定要访问 main store 中的数据,需要使用额外的参数 rootStaterootGetters

getters: {// testAuth(state, getters, rootState, rootGetters) {testAuth(_, _2_, rootState) {return rootState.isLoggedIn;}
}

2.10 模块名字空间

使用名字空间明确区分各个单独的模块,以避免命名冲突,例如,名称相同的 getters, actions 方法, 等等。
解决办法是增加 namespaced 属性:

const counterModule = {namespaced: true,state() {},
};

要访问此模块中的数据,就要使用名字空间,就是加到 main store 里的标识符:

const store = createStore({modules: {// numbers 将用作 counterModule 的名字空间,// 如果该模块的 namespaced 属性被设为 truenumbers: counterModule,},state() {},
});

如果使用名字空间,访问此模块数据的方式会发生改变,代码要进行对应修改。

2.10.1 getters 对应修改如下:

computed: {counter() {// 未使用名字空间// return this.$store.getters.normalizedCounter;// 使用名字空间return this.$store.getters["numbers/normalizedCounter"];},},

2.10.2 mapGetters 对应修改如下:

  computed: {// 未使用名字空间// ...mapGetters(['finalCounter']),// 使用名字空间...mapGetters('numbers', ['finalCounter']),},

2.10.3 mapActions 对应修改如下:

  // 未使用名字空间// ...mapActions({//     inc:'increment',//     increase: 'increase',//   });// 使用名字空间...mapActions('numbers', {inc:'increment',increase: 'increase',});

2.10.4 dispatch 对应修改如下:

  methods: {addTen() {// this.$store.commit('increase', { myValue: 10 });// 未使用名字空间// this.$store.dispatch({ type: 'increase', myValue: 10 });// 使用名字空间this.$store.dispatch({ type: 'numbers/increase', myValue: 10 });},},

2.11 设计 Vuex 代码与文件的结构

如果将 store 相关代码全部放在 main.js 中,将使 main.js 文件过于庞大.

2.11.1 将 store 相关代码放到一个单独的文件 store.js

main.js 代码:

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

store.js 代码:

import { createStore } from 'vuex';const counterModule = {namespaced: true,state() {return {counter: 0,};},mutations: {increment(state) {state.counter = state.counter += 2;},increase(state, payload) {console.log(state);state.counter = state.counter + payload.myValue;},},actions: {increment(context) {setTimeout(function () {context.commit('increment');}, 3000);},increase(context, payload) {context.commit('increase', payload);console.log(context);},},getters: {// testAuth(state, getters, rootState, rootGetters)testAuth(_, _2, rootState) {return rootState.isLoggedIn;},finalCounter(state) {return state.counter * 3;},// state 参数不会用到,用 _ 代替,同 go 语法normalizedCounter(_, getters) {const finalCounter = getters.finalCounter;if (finalCounter < 0) {return 0;} else if (finalCounter > 100) {return 100;} else {return finalCounter;}},},
};const store = createStore({modules: {numbers: counterModule,},state() {return {isLoggedIn: false,};},mutations: {setAuth(state, payload) {state.isLoggedIn = payload.isAuth;},},actions: {login(context) {context.commit('setAuth', { isAuth: true });},logout(context) {context.commit('setAuth', { isAuth: false });},},getters: {userIsAuthenticated(state) {return state.isLoggedIn;},},
});export default store;

2.11.2 继续重构上述 store.js 文件

新建以下文件夹及文件:

在这里插入图片描述

假定,project store 数据分3个部分: authentication, counter, products
可以将 authentiction 数据放到 store root 中,counterproducts 放到 modules 文件夹中。

store.js 代码全部移出,并删除此文件。

store/index.js 代码:

import { createStore } from 'vuex';
import rootMutations from './mutations.js';
import rootActions from './actions.js';
import rootGetters from './getters.js';
import counterModule from './modules/counter/index.js';const store = createStore({modules: {numbers: counterModule,},state() {return {isLoggedIn: false,};},mutations: rootMutations,actions: rootActions,getters: rootGetters,
});export default store;

store/actions.js 代码:

export default {login(context) {context.commit('setAuth', { isAuth: true });},logout(context) {context.commit('setAuth', { isAuth: false });},
};

store/modules/counter/index.js代码:

import counterMutations from './mutations.js';
import counterActions from './actions.js';
import counterGetters from './getters.js';// const counterModule = {
export default {namespaced: true,state() {return {counter: 0,};},mutations: counterMutations,actions: counterActions,getters: counterGetters,
};

其他文件写法依此类推。

代码:
https://github.com/alice201601/vuex-sample-code

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将草料二维码收集到的表单信息同步至腾讯文档

在进行工业巡检场景如消防栓检查时&#xff0c;需要到达巡检地点后&#xff0c;扫描草料二维码&#xff0c;然后填写巡检的结果。事后&#xff0c;还需要有一个工作人员将草料二维码中的信息手动复制粘贴至腾讯文档中。那么能不能将我们信息填写后&#xff0c;自动就汇总至腾讯…

微客云升级会员制度

会员制度 会员制度是一种人与人或组织与组织之间进行沟通的媒介&#xff0c;它是由某个组织发起并在该组织的管理运作下&#xff0c;吸引客户自愿加入&#xff0c;目的是定期与会员联系&#xff0c;为他们提供具有较高感知价值的利益包。 Part 1 会员制度 建立长期稳定的客…

CameraMetadata 知识学习整理

一、涉及的相关代码路径 system/media/camera/src/camera_metadata.c // metadata的核心内容&#xff0c;包含metadata内存分配&#xff0c;扩容规则&#xff0c;update, find等 system/media/camera/src/camera_metadata_tag_info.c // 所有android原生tag的在内存里面sect…

GitHub 下载量过百万,阿里 P8 秘密分享的「亿级并发系统设计」

随着互联网的不断发展&#xff0c;CPU 硬件的核心数也在不断进步&#xff0c;并发编程越来越普及&#xff0c;但是并发编程并不像其他业务那样直接了当。在编写并发程序时&#xff0c;我们常常都会出现各种漏洞&#xff0c;这些问题往往都突然出现&#xff0c;然后又迅速消失&a…

龙格-库塔法(Runge-Kutta methods)

非线性的常微分方程通常是难以求出解析解的&#xff0c;只能通过多次迭代求近似的数值解。 龙格&#xff0d;库塔法&#xff08;Runge-Kutta methods&#xff09;是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。简写做RK法。 对于任意的Yf(X),假设某点(Xi,Yi)的斜…

阿里云安装软件:jdk11

命令下载 1. 安装准备 检查系统jdk版本 java -version检查jdk自带安装包 rpm -qa | grep java卸载jdk yum -y remove tzdata-java.noarch如果有就卸载&#xff0c;卸载的包名通过&#xff08;rpm -qa | grep java&#xff09;获取&#xff0c;包名要全部输入 rpm -e --nodeps …

计算机网络——TCP连接管理

本文将会介绍如何建立和拆除一条TCP连接&#xff0c;TCP的连接会显著的增加人们感受到的时延&#xff08;尤其是在Web冲浪时&#xff09;。同时一些常见的网络攻击SYN洪范攻击利用了TCP连接管理的弱点。 假定运行一台主机&#xff08;客户&#xff09;上的一个进程想和另一台主…

流程编排、如此简单-通用流程编排组件JDEasyFlow介绍

作者&#xff1a;李玉亮 JDEasyFlow是企业金融研发部自研的通用流程编排技术组件&#xff0c;适用于服务编排、工作流、审批流等场景&#xff0c;该组件已开源(https://github.com/JDEasyFlow/jd-easyflow)&#xff0c;目前在部门的内部业务系统和科技输出系统中广泛应用&…

通过PreparedStatement预防SQL注入

通过PreparedStatement预防SQL注入 简介&#xff1a;本文只讲PreparedStatement预防SQL注入的写法&#xff0c;大家学会就好。 推荐学习路线&#xff1a;JDBC数据库的连接->Connection&#xff08;数据库连接对象&#xff09;->Statement->ResultSet->通过Prepare…

Spring Boot 简介及快速搭建

Spring Boot 简介及快速搭建 springboot的优点&#xff1a; –快速构建一个独立的 Spring 应用程序 &#xff1b; –嵌入的 Tomcat 、 Jetty 或者 Undertow&#xff0c;无须部署 WAR 文件&#xff1b; –提供starter POMs来简化Maven配置和减少版本冲突所带来的问题&#xff1…

【云原生 | Kubernetes 系列】--Gitops持续交付 Argo Rollouts Analysis

1. Argo Rollouts 由一个控制器和一组CRD组成,可为K8s提供高级部署功能 - blue-green - canary - canary analysis 结合外部指标系统金丝雀 - experimentation 实验性的结果 - progressive delivery 渐进式交付,精准管控外部流量策略,不用关心后端部署机制支持Ingress Contro…

深度学习 Day 20——优化器对比实验

深度学习 Day 20——优化器对比实验 文章目录深度学习 Day 20——优化器对比实验一、前言二、我的环境三、前期工作1、设置GPU2、导入数据3、配置数据集4、数据可视化三、构建模型四、训练模型五、模型评估1、Accuracy与Loss图2、评估模型六、最后我想说一、前言 &#x1f368;…

2022 谷歌出海创业加速器展示日: 见证入营企业成长收获

经历三个月的沉淀&#xff0c;迎来了展示日的大放异彩。10 家入营企业的路演分享&#xff0c;带来诸多启发 ——企业出海有什么挑战和难点&#xff1f;加入谷歌出海创业加速器&#xff0c;团队有哪些收获&#xff1f;三个月的培训和交流&#xff0c;带来了怎样的感受&#xff1…

【车间调度】遗传算法求解车间调度问题(含甘特图)【含Matlab源码 2216期】

⛄一、车间调度简介 1 车间调度定义 车间调度是指根据产品制造的合理需求分配加工车间顺序&#xff0c;从而达到合理利用产品制造资源、提高企业经济效益的目的。车间调度问题从数学上可以描述为有n个待加工的零件要在m台机器上加工。问题需要满足的条件包括每个零件的各道工序…

arduino 复习题

名词解释 中断 计算机运行过程中&#xff0c;出现某些意外情况需主机干预时&#xff0c;机器能自动停止正在运行的程序并转入处理新情况的程序&#xff0c;处理完毕后又返回原被暂停的程序继续运行 中断服务程序 用于 CPU 处理中断的程序 中断源 引起中断的原因&#xff0c;或…

柯桥成人英语培训机构哪家好,新陈代谢到底是什么?

新陈代谢到底是什么? Metabolism is a combination of biochemical processes that your body uses to convert food into energy. These metabolic processes include breathing, eating and digesting food, the delivery of nutrients to your cells through the blood, th…

软件被人后台篡改了收款码属于入侵吗?

最近很多做平台的小伙伴&#xff0c;碰到了同样的问题&#xff0c;就是软件程序后台被恶意篡改收款二维码 这个问题出现在平台主身上无疑是雪上加霜&#xff0c;第一时间找到了小蚁君&#xff0c;分析了一下当时的情况&#xff0c;先安装了小蚁的入侵检测系统&#xff0c;显示…

华为机试 - TLV解析Ⅰ

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 TLV编码是按[Tag Length Value]格式进行编码的&#xff0c;一段码流中的信元用Tag标识&#xff0c;Tag在码流中唯一不重复&#xff0c;Length表示信元Value的长度&#xff0c;Value表示信元的值。 码…

3d-face-reconstruction比较

摘要&#xff1a;比较近3年&#xff0c;6篇顶会3d-face-reconstruction重建效果。 1:Deep3D **发表时间:**2020 成就&#xff1a; 1&#xff09;在REALY和REALY (side-view)两个Benchmark上取得 State-of-the-art。 2&#xff09;官方github上成绩&#xff1a; 3DMM&#xf…

计算机硬件和软件

文章目录一 计算机硬件1&#xff09;主板2&#xff09;显示器3&#xff09;键盘4&#xff09;鼠标二 计算机软件&#xff08;一&#xff09;系统软件&#xff08;1&#xff09;操作系统&#xff08;2&#xff09;BIOS&#xff08;3&#xff09;设备驱动程序&#xff08;二&…