vue中的状态管理

第1部分:引言

状态管理是应用中数据流动和变更的核心机制。在Vue应用中,状态管理不仅涉及到组件间的数据共享,还包括了数据的持久化、异步操作的处理等复杂场景。良好的状态管理策略可以提高应用的响应速度,降低组件间的耦合度,简化开发和维护工作。

第2部分:Vue状态管理简介

2.1 状态管理的基本概念

状态管理是前端应用开发中的一个核心概念,它涉及到应用中数据的存储、共享、更新和维护。在Vue中,状态管理是指对应用程序中共享状态的集中式管理,以确保状态的一致性和可预测性。

2.2 状态管理的必要性

在复杂的应用中,状态可能分布在多个组件中,这就需要一个统一的方式来管理这些状态,以避免数据不一致和组件间的复杂依赖。状态管理提供了一种机制,使得状态的更新可以被追踪和控制,从而简化了组件间的通信。

2.3 Vue的响应式系统

Vue的响应式系统是状态管理的基础。Vue通过数据劫持和依赖收集的方式,实现了对数据的响应式处理。当状态发生变化时,Vue能够自动更新依赖于这些状态的组件,从而保持视图和状态的同步。

2.4 响应式数据与状态管理

在Vue中,响应式数据通常指的是组件的data属性。然而,当应用规模扩大,仅仅依赖组件的data属性进行状态管理是不够的。这时,我们需要引入状态管理库,如Vuex,来处理跨组件的状态共享。

2.5 状态管理的挑战
  • 数据流的复杂性:在大型应用中,状态的流动可能会变得非常复杂,难以追踪。
  • 组件间的耦合:没有适当的状态管理,组件间的耦合度可能会增加,导致代码难以维护。
  • 性能问题:不合理的状态管理可能会导致不必要的渲染,影响应用性能。
2.6 状态管理的最佳实践
  • 集中式存储:将所有组件共享的状态放在一个地方管理。
  • 状态的不可变性:避免直接修改状态,而是通过提交mutation来触发状态变更。
  • 单一数据源:确保应用的状态有一个单一的来源,避免数据不一致。
2.7 示例:简单的计数器应用

让我们通过一个简单的计数器应用来展示Vue的响应式系统和状态管理的基本概念:

<template>
  <div>
    <h1>{{ count }}</h1>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>

在这个例子中,count是一个响应式数据,当它被修改时,视图会自动更新。

2.8 扩展到Vuex

对于更复杂的应用,我们可以使用Vuex来管理状态。以下是一个使用Vuex的计数器应用示例:

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
});

export default store;
<template>
  <div>
    <h1>{{ count }}</h1>
    <button @click="incrementAction">Increment with Vuex</button>
  </div>
</template>

<script>
import store from './store';

export default {
  computed: {
    count() {
      return store.state.count;
    }
  },
  methods: {
    incrementAction() {
      store.dispatch('increment');
    }
  }
};
</script>

在这个例子中,我们使用Vuex来管理计数器的状态。increment mutation用于修改状态,而incrementAction action则用于封装异步逻辑。

第3部分:Vue的响应式系统

3.1 响应式系统的工作原理

Vue的响应式系统是其核心特性之一,它允许开发者声明性地描述一个视图,而Vue则负责将数据状态映射到视图上。Vue通过使用Object.defineProperty来劫持数据对象的gettersetter,从而实现数据变化时自动更新视图。

3.2 响应式数据的创建

在Vue组件中,可以通过data函数返回一个对象来定义响应式数据。Vue将递归地遍历这个对象的所有属性,并将它们转换为getter和setter。

export default {
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
};
3.3 响应式数据的读取

在模板中,可以通过插值表达式或指令来读取响应式数据。

<template>
  <p>{{ message }}</p>
</template>
3.4 响应式数据的更新

当响应式数据发生变化时,视图会自动更新。开发者可以通过直接修改数据属性的值来更新数据。

this.message = 'Hello Reactive Vue!';
3.5 响应式系统的局限性

尽管Vue的响应式系统非常强大,但它也有局限性。例如,它不能检测以下类型的数据变化:

  • 直接设置一个属性值,例如:vm.someData = { a: 1 }
  • 通过索引设置数组项,例如:vm.items[indexOfItem] = newValue
  • 替换数组或对象
3.6 Vue 3中的响应式系统改进

Vue 3引入了Composition API,它提供了更灵活的方式来创建响应式数据。使用reactiveref可以创建响应式的数据结构。

import { reactive, ref } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0
    });

    const message = ref('Hello Reactive Vue 3!');

    function increment() {
      state.count++;
    }

    return { state, message, increment };
  }
};
3.7 示例:响应式数组和对象

Vue提供了Vue.set方法来处理数组索引和对象属性的响应性问题。

// 对象
Vue.set(vm.someData, 'b', 2);

// 数组
vm.items.splice(indexOfItem, 1, newValue);
3.8 响应式系统的底层实现

为了更深入地理解Vue的响应式系统,我们可以看一下它是如何在内部工作的。Vue使用了一个观察者模式,当数据发生变化时,它会通知所有依赖于这个数据的观察者(通常是组件的渲染函数)。

3.9 响应式系统的优化

Vue的响应式系统是高效的,但在某些情况下,我们可能需要手动优化性能。例如,使用计算属性来描述那些可以由其他数据派生出来的数据,而不是使用方法。

computed: {
  reversedMessage() {
    return this.message.split('').reverse().join('');
  }
}

第4部分:Vuex的安装与配置

4.1 Vuex简介

Vuex是Vue.js的官方状态管理库,专为Vue.js应用程序开发。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

4.2 安装Vuex

在Vue项目中安装Vuex通常非常简单。如果你使用的是npm或yarn作为包管理器,可以通过以下命令安装Vuex:

npm install vuex@next --save  # 对于Vue 3
# 或者
yarn add vuex@next  # 对于Vue 3
4.3 创建Vuex Store

安装Vuex之后,你需要创建一个Vuex Store来作为应用的中央仓库。Store由五个主要部分组成:state、getters、mutations、actions和modules。

// store.js
import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  getters: {
    doubleCount(state) {
      return state.count * 2;
    }
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit('increment');
    }
  }
});

export default store;
4.4 在Vue应用中使用Vuex Store

创建Store之后,你需要在Vue应用中使用它。如果你使用的是Vue 3,可以在main.js中这样配置:

// 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');
4.5 访问和修改状态

在组件中,你可以通过计算属性和方法来访问和修改状态。

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapActions(['increment'])
  }
};
</script>
4.6 Vuex的严格模式

Vuex提供了严格模式,这在开发过程中非常有用,因为它可以捕捉到状态的直接修改。

const store = createStore({
  // ...options
  strict: true
});
4.7 Vuex的插件

Vuex允许你使用插件来扩展其功能。例如,vuex-persistedstate插件可以用来持久化存储的状态。

import createPersistedState from 'vuex-persistedstate';

const store = createStore({
  // ...options
  plugins: [createPersistedState()]
});
4.8 Vuex的调试工具

Vuex Devtools是一个强大的浏览器扩展,它允许你监视和跟踪Vuex的状态变化。

4.9 示例:使用Vuex管理用户认证状态

让我们通过一个用户认证状态的例子来展示Vuex的实际应用:

// auth.js
export default {
  namespaced: true,
  state() {
    return {
      isLoggedIn: false,
      user: null
    };
  },
  mutations: {
    login(state, user) {
      state.isLoggedIn = true;
      state.user = user;
    },
    logout(state) {
      state.isLoggedIn = false;
      state.user = null;
    }
  },
  actions: {
    login({ commit }, user) {
      commit('login', user);
    },
    logout({ commit }) {
      commit('logout');
    }
  }
};
// store.js
import { createStore } from 'vuex';
import auth from './auth';

const store = createStore({
  modules: {
    auth
  }
  // ...其他配置
});

export default store;

第5部分:状态(State)管理

5.1 状态(State)的概念

在Vuex中,状态(State)是应用数据的单一来源。它是响应式的,当状态发生变化时,所有依赖于该状态的组件都会自动更新。

5.2 状态的初始化

状态通常在Vuex Store的state函数中初始化。这个函数返回一个对象,其中包含了应用的所有状态。

const store = createStore({
  state() {
    return {
      items: [],
      currentItem: null,
      filter: ''
    };
  }
});
5.3 状态的读取

在组件中,可以通过计算属性来读取状态。

<script>
export default {
  computed: {
    filteredItems() {
      return this.$store.state.items.filter(item =>
        item.name.toLowerCase().includes(this.$store.state.filter)
      );
    }
  }
};
</script>
5.4 状态的更新

状态的更新应该通过提交Mutations来实现,以确保状态的变更是可追踪的。

<button @click="addItem">Add Item</button>

<script>
export default {
  methods: {
    addItem() {
      this.$store.commit('addItem', { name: 'New Item' });
    }
  }
};
</script>
5.5 状态的不可变性

Vuex强调状态的不可变性。这意味着你不应该直接修改状态,而是通过Mutations来更新状态。

// 错误的写法
store.state.items.push({ name: 'Direct Item' });

// 正确的写法
store.commit('addItem', { name: 'Mutation Item' });
5.6 使用Mutations更新状态

Mutations是同步函数,它们负责修改状态。Mutations必须在actions中被提交。

const store = createStore({
  mutations: {
    setFilter(state, filter) {
      state.filter = filter;
    }
  }
});
<input v-model="filter" @input="setFilter">

<script>
export default {
  data() {
    return {
      filter: ''
    };
  },
  methods: {
    setFilter() {
      this.$store.commit('setFilter', this.filter);
    }
  }
};
</script>
5.7 状态的模块化

当应用变得复杂时,状态也可以模块化。每个模块可以拥有自己的state、getters、mutations和actions。

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
};

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
};

const store = createStore({
  modules: {
    a: moduleA,
    b: moduleB
  }
});
5.8 状态的持久化

状态的持久化是指将状态保存在本地存储中,以便在页面刷新或应用重启时能够恢复状态。

import createPersistedState from 'vuex-persistedstate';

const store = createStore({
  plugins: [createPersistedState()]
});
5.9 状态的监控

使用Vuex Devtools可以监控状态的变化,这对于调试应用非常有用。

5.10 示例:购物车应用

让我们通过一个购物车应用的例子来展示状态管理的实际应用:

// store.js
const store = createStore({
  state() {
    return {
      cart: []
    };
  },
  mutations: {
    addToCart(state, product) {
      state.cart.push(product);
    },
    removeFromCart(state, product) {
      state.cart = state.cart.filter(p => p.id !== product.id);
    }
  },
  actions: {
    addToCart({ commit }, product) {
      commit('addToCart', product);
    },
    removeFromCart({ commit }, product) {
      commit('removeFromCart', product);
    }
  }
});
<template>
  <div>
    <ul>
      <li v-for="product in cart" :key="product.id">
        {{ product.name }} - {{ product.price }}
        <button @click="removeFromCart(product)">Remove</button>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  computed: {
    cart() {
      return this.$store.state.cart;
    }
  },
  methods: {
    removeFromCart(product) {
      this.$store.dispatch('removeFromCart', product);
    }
  }
};
</script>

第6部分:获取器(Getters)

6.1 Getters的基本概念

在Vuex中,Getters允许你从Store中获取数据。与状态(State)不同,Getters的返回值会根据它们的依赖被缓存,只有当依赖发生变化时,Getters才会重新计算。这使得Getters非常适合进行数据的派生和转换。

6.2 使用Getters

Getters在Vuex Store中定义,并且可以在组件中通过mapGetters辅助函数访问。

// store.js
const store = createStore({
  state() {
    return {
      todos: [
        { id: 1, text: 'Learn Vuex', done: false },
        { id: 2, text: 'Build something with Vuex', done: true }
      ]
    };
  },
  getters: {
    doneTodos: (state) => state.todos.filter(todo => todo.done),
    allTodosCount: (state) => state.todos.length
  }
});
6.3 在组件中访问Getters

使用mapGetters辅助函数可以轻松地将Getters映射到组件的计算属性中。

<template>
  <div>
    <p>Done todos count: {{ doneTodosCount }}</p>
    <ul>
      <li v-for="todo in doneTodos" :key="todo.id">
        {{ todo.text }}
      </li>
    </ul>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  computed: {
    ...mapGetters([
      'doneTodos',
      'allTodosCount'
    ])
  }
};
</script>
6.4 Getters的参数

Getters可以接收state作为第一个参数,也可以接收其他getter作为参数。

getters: {
  doneTodosCount: (state, getters) => getters.doneTodos.length
}
6.5 Getters的命名空间

在模块化Store中,Getters也可以使用命名空间。当使用mapGetters时,需要指定模块的名称。

// 使用命名空间的模块
const moduleA = {
  namespaced: true,
  state: () => ({ ... }),
  getters: {
    someGetter(state) { /* ... */ }
  }
};

// 在组件中访问命名空间的getter
computed: {
  ...mapGetters('moduleA', ['someGetter'])
}
6.6 Getters与组件方法的区别

Getters与组件方法不同,Getters是响应式的,并且它们的依赖会被缓存。而组件方法每次调用时都会执行。

6.7 Getters的高级用法

Getters可以用于复杂的逻辑,例如,根据当前用户的角色过滤菜单项。

getters: {
  filteredMenuItems: (state, getters, rootState) => {
    return state.menuItems.filter(item => {
      return item.roles.includes(rootState.user.role);
    });
  }
}
6.8 示例:购物车总价计算

Getters可以用于计算购物车中所有商品的总价。

getters: {
  cartTotal(state) {
    return state.cart.reduce((total, item) => {
      return total + item.price * item.quantity;
    }, 0);
  }
}
6.9 使用计算属性还是Getters

选择使用计算属性还是Getters取决于数据是否需要跨组件共享。如果数据只在单个组件内部使用,计算属性可能是更好的选择。

第7部分:更改状态:Mutations

7.1 Mutations 的基本概念

Mutations 是 Vuex 中用来提交更改状态的操作。与直接修改状态不同,Mutations 是同步的事务性操作,Vuex 确保每次状态变更都是可追踪和记录的。

7.2 Mutations 的定义

在 Vuex Store 中,Mutations 通过一个对象定义,每个属性是一个 Mutation 的函数,函数名就是 Mutation 的类型。

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state, payload) {
      state.count += payload.amount;
    }
  }
});
7.3 提交 Mutations

在组件中,你可以通过 commit 方法提交 Mutations。

<template>
  <button @click="increment">Increment</button>
</template>

<script>
export default {
  methods: {
    increment() {
      this.$store.commit('increment', { amount: 1 });
    }
  }
};
</script>
7.4 Mutations 的参数

Mutations 可以接收 state 作为第一个参数,还可以接收额外的参数(payload)。

mutations: {
  setCount(state, payload) {
    state.count = payload.value;
  }
}
7.5 Mutations 的命名空间

在模块化 Store 中,Mutations 也可以使用命名空间。调用时需要指定模块名和 Mutation 名。

// 模块化 Mutations
const moduleA = {
  namespaced: true,
  state: { ... },
  mutations: {
    someMutation(state, payload) { /* ... */ }
  }
};

// 提交模块化 Mutations
this.$store.commit('moduleA/someMutation', payload);
7.6 使用常量定义 Mutation 类型

为了防止在调用 Mutations 时出现拼写错误,可以使用常量来定义 Mutation 类型。

const MutationTypes = {
  INCREMENT: 'INCREMENT'
};

mutations: {
  [MutationTypes.INCREMENT](state, payload) {
    state.count += payload.amount;
  }
}
7.7 为什么使用 Mutations

Mutations 提供了一种集中式的方式来修改状态,并且可以确保状态的变更是可预测和同步的。

7.8 示例:用户认证状态的更新

Mutations 可以用来更新用户认证状态。

mutations: {
  login(state, user) {
    state.user = user;
  },
  logout(state) {
    state.user = null;
  }
}
7.9 使用 Mutations 处理复杂逻辑

虽然 Mutations 应该是简单的同步操作,但有时也可以使用辅助函数来处理更复杂的逻辑。

mutations: {
  updateItems(state, items) {
    items.forEach(item => {
      // 假设 updateItem 是一个复杂的同步操作
      state.items = updateItem(state.items, item);
    });
  }
}
7.10 Mutations 与响应式系统的交互

Mutations 触发 Vuex 的响应式系统,导致依赖状态的组件重新渲染。

第8部分:异步操作:Actions

8.1 Actions 的基本概念

在 Vuex 中,Actions 类似于 Mutations,但它可以包含异步操作。Actions 负责响应外部事件,如用户输入,然后提交 Mutations 来改变状态。

8.2 Actions 的定义

Actions 通过一个对象定义,每个属性是一个 Action 的函数。

const store = createStore({
  state: {
    posts: []
  },
  actions: {
    fetchPosts({ commit }) {
      axios.get('https://api.example.com/posts')
        .then(response => {
          commit('receivePosts', response.data);
        })
        .catch(error => {
          console.error('Fetching posts failed:', error);
        });
    }
  }
});
8.3 分发 Actions

在组件中,你可以使用 dispatch 方法来分发 Actions。

<template>
  <button @click="fetchData">Load Posts</button>
</template>

<script>
export default {
  methods: {
    fetchData() {
      this.$store.dispatch('fetchPosts');
    }
  }
};
</script>
8.4 Actions 的参数

Actions 可以接收一个与 Mutations 相同的 context 对象作为第一个参数,它包含 state, commit, getters, dispatchrootState

actions: {
  asyncAction({ commit, state, rootState }) {
    // 可以访问 state, commit, getters 等
  }
}
8.5 在 Actions 中提交 Mutations

Actions 可以提交 Mutations 来改变状态。

actions: {
  incrementAsync({ commit }) {
    setTimeout(() => {
      commit('increment');
    }, 1000);
  }
}
8.6 Actions 的命名空间

在模块化 Store 中,Actions 也可以使用命名空间。

const moduleA = {
  namespaced: true,
  actions: {
    someAction({ commit }) {
      commit('someMutation');
    }
  }
};

// 分发模块化 Action
this.$store.dispatch('moduleA/someAction');
8.7 使用 Promise 处理异步 Actions

你可以将 Actions 设计为返回 Promise,以便在组件中处理异步结果。

actions: {
  fetchPosts({ commit }) {
    return axios.get('https://api.example.com/posts')
      .then(response => commit('receivePosts', response.data))
      .catch(error => console.error(error));
  }
}
8.8 示例:用户登录流程

Actions 可以处理复杂的异步流程,如用户登录。

actions: {
  login({ commit }, credentials) {
    return new Promise((resolve, reject) => {
      axios.post('/api/login', credentials)
        .then(() => {
          commit('loginSuccess');
          resolve();
        })
        .catch(error => {
          commit('loginFailure', error);
          reject(error);
        });
    });
  }
}
8.9 使用辅助函数简化 Actions

Vuex 提供了 mapActions 辅助函数,可以简化在组件中分发 Actions 的代码。

<script>
import { mapActions } from 'vuex';

export default {
  methods: {
    ...mapActions([
      'login',
      'logout'
    ])
  }
};
</script>
8.10 Actions 与组件方法的区别

Actions 与组件方法的主要区别在于,Actions 可以包含异步操作,并且可以跨组件共享。

看到这,欢迎友友们关注我的公众号

在这里插入图片描述

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

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

相关文章

交互式知识库问答:一种结合大型语言模型的多轮交互方法

在当今信息爆炸的时代&#xff0c;人们每天都要处理海量的数据和信息。在这样的背景下&#xff0c;基于知识库的问答系统&#xff08;KBQA&#xff09;成为了一个重要的研究领域&#xff0c;它旨在使计算机能够理解自然语言提出的问题&#xff0c;并从结构化的知识库中检索出准…

通信系统网络架构_1.局域网网络架构

当今&#xff0c;通信网络从大的方面主要包括局域网、广域网、移动通信网等网络形式。不同的网络会采用不同的技术进行网络构建。以下针对不同的网络给出各自的网络架构以及所采用的技术。 1.概述 局域网&#xff0c;即计算机局部区域网络&#xff0c;是一种为单一机构所拥有的…

四边形不等式优化

四边形不等式优化 应用于类似以下dp转移方程。 f i min ⁡ 1 ≤ j ≤ i ( w i , j , f i ) f_{i}\min_{1\le j\le i}(w_{i,j},f_{i}) fi​1≤j≤imin​(wi,j​,fi​) 假设 w i , j w_{i,j} wi,j​ 可以在 O ( 1 ) O(1) O(1) 的时间内进行计算。 在正常情况下&#xff0c;…

如何验证Rust中的字符串变量在超出作用域时自动释放内存?

讲动人的故事,写懂人的代码 在公司内部的Rust培训课上,讲师贾克强比较了 Rust、Java 和 C++ 三种编程语言在变量越过作用域时自动释放堆内存的不同特性。 Rust 通过所有权系统和借用检查,实现了内存安全和自动管理,从而避免了大部分内存泄漏。Rust 自动管理标准库中数据类…

本科生大厂算法岗实习经验复盘:从投递到面试的底层思维!

目录 投递渠道boss直聘官网邮箱内推 面试准备leetcode八股深挖项目自我介绍mock面试技巧答不出来怎么办coding反问 复盘技术交流群用通俗易懂方式讲解系列 节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面…

30 - 每位经理的下属员工数量(高频 SQL 50 题基础版)

30 - 每位经理的下属员工数量 -- 根据reports_to &#xff0c;获取employee_id,即分组用e1.reports_to&#xff0c;查询用e2.employee_id,e2.nameselect e2.employee_id,e2.name ,count(e1.reports_to) reports_count,round(avg(e1.age),0) average_age from Employees e1 left…

Springboot应用的信创适配-补充

Springboot应用的信创适配-CSDN博客 因为篇幅限制&#xff0c;这里补全Spring信创适配、数据库信创适配、Redis信创适配、消息队列信创适配等四个章节。 Springboot应用的信创适配 Springboot应用的信创适配&#xff0c;如上图所示需要适配的很多&#xff0c;从硬件、操作系统、…

【Linux基础IO】深入理解缓冲区

缓冲区在文件操作的过程中是比较重要的&#xff0c;理解缓冲区向文件刷新内容的原理可以更好的帮助我们更深层的理解操作系统内核对文件的操作。 FILE 因为IO相关函数与系统调用接口对应&#xff0c;并且库函数封装系统调用&#xff0c;所以本质上&#xff0c;访问文件都是通过…

国内外大模型生态发展报告!

很多同学只知类似Check GPT或者说对国内的一些比较了解&#xff0c;对国外的不太了解&#xff0c;所以在这总结。 1 大模型的发展 左表 名称参数特点发布时间GPT-215亿英文底模&#xff0c;开源2019年Google T5110亿多任务微调, 开源2019年GPT-3.51750亿人工反馈微调2022年M…

Django 循环模板标签

1&#xff0c;循环模板标签 Django 模板系统中提供了多种循环模板标签来迭代数据并显示列表、字典或其他可迭代对象。 1.2 {% for %} 标签 用于迭代列表或可迭代对象&#xff0c;并为每个元素提供上下文变量。 {% for item in items %}{{ item }} <!-- 渲染当前迭代项 -…

第二次IAG

IAG in NanJing City 我与南京奥体的初次相遇&#xff0c;也可能是最后一次&#xff01; 对我来说,IAG 演唱会圆满结束啦! 做了两场充满爱[em]e400624[/em]的美梦 3.30号合肥站&#xff0c;6.21号南京站[em]e400947[/em] 其实&#xff0c;没想到昨天回去看呀!(lack of money […

docker简单快速使用上手

1.Docker是什么&#xff1f; Docker 是一个开源的容器化平台&#xff0c;主要用于开发、运输和运行应用程序。它通过提供轻量级的虚拟化机制&#xff0c;使得开发者可以在一个隔离的环境中运行和管理应用程序及其依赖项。Docker 的核心组件包括镜像&#xff08;Image&#xff…

数据库浅识及MySQL的二进制安装

数据库基础概念与MySQL二进制安装与初始化 使用数据库的必要性 数据库可以结构化储存大量数据信息&#xff0c;方便用户进行有效的检索访问 有效的保持数据信息的一致性&#xff0c;完整性&#xff0c;降低数据冗余 可以满足应用的共享和安全方面的要求 数据库基本概念 数据…

Redis学习|Redis 是什么、Redis 能干嘛、Window安装Redis、Linux下安装Redis、Redis测试性能

Redis 是什么? Redis(Remote Dictionary Server)&#xff0c;即远程字典服务! 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API. redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记…

C++:STL容器-map

C:STL容器-map 1. map构造和赋值2. map大小和交换3. map插入和删除4. map查找和统计5. map容器排序 map中所有元素都是pair&#xff08;对组&#xff09; pair中第一个元素为key&#xff08;键&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素为value&#xff08;实…

揭秘古代手术工具与技术:从中国起源的医疗奇迹

在人类历史的长河中&#xff0c;医学的发展一直是推动社会进步的重要力量。而手术作为医学的一个重要分支&#xff0c;其发展历程同样充满了传奇色彩。今天&#xff0c;我们将带您走进古代手术的世界&#xff0c;揭秘那些令人惊叹的手术工具和技术。 这把手术刀出土于河北西村遗…

红队内网攻防渗透:内网渗透之内网对抗:横向移动篇入口切换SMB共享WMI管道DCOM组件Impacket套件CS插件

红队内网攻防渗透 1. 内网横向移动1.1 WMI进行横向移动1.1.1 利用条件:1.1.1 利用详情1.1.1.1 wmic1.1.1.1.1 正向shell上线1.1.1.1.2 反向shell上线1.1.1.2 cscript(不建议使用)1.1.1.3 wmiexec-impacket1.1.1.4 cs插件1.2 SMB横向移动1.2.1 利用条件:1.2.2 利用详情1.2.2…

java中Object和json相互转换的方式

1.org中jackson转换json,springboot中内置jackson ObjectMapper onew ObjectMapper(); List<>listnew ArrayList(); String jonso.writeAsValueString(list); 2.alibaba中fastjson转换成json GetMapping("/test")public TbUser testHttpClient(){String url…

BFS:解决最短路问题

文章目录 什么是最短路问题&#xff1f;1.迷宫中离入口最近的出口2.最小基因变化3.单词接龙4.为高尔夫比赛砍树总结 什么是最短路问题&#xff1f; 最短路问题是图论中的经典问题&#xff0c;旨在寻找图中两个节点之间的最短路径。常见的最短路算法有多种&#xff0c;这次我们…

计算机组成原理 | 硬件电路整理

计算机组成原理 | 硬件电路整理 桶形移位器原理图 全加器逻辑框图 多位可控加减法电路逻辑框图 可级联的4位先行进位电路 4位快速加法器 16位组内并行、组间并行加法器 实现原码一位乘法的逻辑框图 补码一位乘法的逻辑框图 无符号数阵列乘法器 原码不恢复余数法硬件逻辑框图 基…