Vue2(十二):Vuex环境搭建、Vuex工作原理、Vuex开发者工具、几个配置项、多组件共享数据、Vuex模块化

一、Vuex

1.概念

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

多组件比如a、b、c、d进行事件共享的时候,都想要a里的数据,而且他们互为兄弟,按以前的方法就得用全局事件总线,但是那样的话组件就太多了。Vuex就专门解决共享数据的问题。单独放在一块区域,大家都想得到的数据就放它里面,大家都可以读、写,a改完之后的x=4,那么b在拿到x也是4。

2.什么时候使用Vuex

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

3.求和案例:纯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>
     <!-- 这里除了最开始设置的数字1,其他都是字符串所以都加不了了 -->
     <!-- 所以加 :value,当成js表达式去解析 或者加.number强制转换-->
   </select>
   <button @click="increment">+</button>
   <button @click="decrement">-</button>
   <button @click="incrementOdd">当前求和为奇数再加</button>
   <button @click="incrementWait">等一等再加</button>
 </div>
</template>

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

4.Vuex的工作原理图

(1)构成

构成Vuex的三个对象由store管理,而且这三个对象数据类型都是obj,dispatch、commit函数就是store里的,所以我们得让任何vc都能看见store。

(2)流程

Vue Components是组件们,比如说我要加2,然后这个数据传给dispatch函数,传参过去:第一个参数:你要做的动作,第二个参数:数字。

然后你写的函数在Actions(数据类型是Object)就会有一个函数跟它对应,然后你自己再去调用commit函数(提交),到了mutations(数据类型也是Object),commit里的jia,mutations也会有一个jia跟它对应,同时它还会拿到两个参数:state状态和2。

mutate不用你调用,只需要在mutations里的jia写一句state.sum+=2,底层自动加2,sum就不是0是2了,然后Vuex帮你开始渲染render,页面上的sum就变化了。

这样看起来好像Actions有点没用,但是上面是后端接口,因为有的时候给dispatch传只传了动作没有值,就得去后端问一下数据(值得要发送ajax请求才能得到的时候,就需要用到Actions了)。

如果传过来就有值的话,可以直接调用commit。

二、Vuex环境搭建

1.安装Vuex

npm i vuex@3,Vue2对应vuex3版本,Vue3对应vuex4版本

2.引入并Use一下vuex

import Vuex from 'Vuex'
Vue.use(Vuex)

use了vuex然后就可以在vm中创建store对象了

3.创建store

新建一个store文件夹,在里面新建一个index.js

注意:所有的import都是先被提到代码最上方先执行然后再执行其他代码

在main.js引入插件并use vuex插件必须在import store之前,所以在main里面不管把use怎么移动都是先import store会报错,干脆把use代码写在index.js里,index里没有vue就引入vue

main.js:

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
import store from './store/index.js'
//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus=this
	},
	store
})

index.js:

//该文件用于创建Vuex中最核心的store
//actions——响应组件中的动作
//引入Vue
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions={

}
//mutations——用于操作数据
const mutations={

}
//state——用于存储数据
const state={

}
//创建store还得向外暴露
const store= new Vuex.Store({
actions,
mutations,
state
})

export default  store

4.求和案例:Vuex版本

(1)首先把sum放进vuex

//state——用于存储数据
const state = {
    sum: 0,
}

(2)插值语法

<h2>当前求和为:{{$store.state.sum}}</h2>

(3)在组件中的回调用dispatch发给actions

methods:{
    increment(){
      this.$store.dispatch('jia',this.n)
      // $store是在vc身上的
    },

(4)actions来接数据,再调用commit函数

const actions = {
    jia(context,value) {
        context.commit('JIA',value)
        //context就是一个mini版的store
        // 调用commit函数,传过去方法和值
    }
}

(5)mutations来接数据

我们不是说actions里的东西要想用就得保证mutations里面也得有吗,所以写完actions里的东西之后在mutations里也加上,为了区分mutations里面都用大写

//mutations——用于操作数据
const mutations = {
    JIA(state,value) {
        state.sum+=value
    }
}

我们写的state里面只有一个sum=0,但是如果输出一下就能发现实际上还有getter和setter之类的,是vue给我们封装的,类似data

基础版index:
const actions = {
    // jia(context,value) {
    //     context.commit('JIA',value)
    //     //context就是一个mini版的store
    //     // 调用commit函数,传过去方法和值
    // },
    // jian(context,value) {
    //     context.commit('JIAN',value)
    // },

    //这两个都没必要绕弯再去找mutations,直接去找
    jiaOdd(context,value) {
        if(context.state.sum%2)
        {
            context.commit('JIA',value)
            //这儿不用写JIAODD因为调用的都是jia,然后下面也就不用加JIAODD了
        }
    },
    jiaWait(context,value) {
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//mutations——用于操作数据
const mutations = {
    JIA(state,value) {
        state.sum+=value
    },
    JIAN(state,value) {
        state.sum-=value
    }
}
基础版myCount:
methods: {
    increment() {
      //this.$store.dispatch("jia", this.n);
      this.$store.commit("JIA", this.n);
      // $store是在vc身上的
    },
    decrement() {
      //this.$store.dispatch("jian", this.n);
      this.$store.commit("JIAN", this.n);
      //直接去找mutations
    },
    incrementOdd() {
      this.$store.dispatch("jiaOdd", this.n);
    },
    incrementWait() {
      this.$store.dispatch("jiaWait", this.n);
    },
  },
};

注意点:1.JIAODD、JIAWAIT里的方法都是JIA不用再单独写一个

2.JIA、JIAN都可以省略找Actions,直接去找Mutations

3.如果在actions直接写context.state.num+=value也能奏效,不用再找Mutations,但是!!这样开发者工具就失效了,所以还是得按照标准写。

4.业务逻辑写在组件里不写在action行不行?拿发票报销举例子,在组件里写就是调用第一个地儿然后传单号,然后调用第、、、个地儿再传单号很麻烦,直接告诉actions我要报销然后传单号,剩下的事让actions去解决。

三、Vuex开发者工具

跟vue位置一样,像表一样的图案就是Vuex的开发者工具,每一栏操作的后面有三个按钮,第一个按钮下载一样的是点击哪个,这个和它所有之前的都合并作为基底

第二个按钮是取消某一层,而且取消之后它后面的那些层也就都没了,就像盖楼一样,三层塌了上面的都得没

第三个按钮是时光穿梭到某个时候,展示那个时候的数据

哪条最绿说明页面正在呈现哪层

展示栏的右上角是导出和导入操作步骤

四、配置项

1.getters配置项

1、概念:当state中的数据需要经过加工后再使用时,可以使用getters加工,类似Vue中的计算属性computed与data。
2、类似于计算属性,但是好多组件都可以用,computer属性只能当前属性用(逻辑复杂或者逻辑还想复用的时候就用getters,得写返回值

//用于将state的数据进行加工
const getters={
    bigSum(state){
        return state.sum*10
    }
}

配置完记得暴露,调用一下:

<h2>当前和乘十为:{{ $store.getters.bigSum }}</h2>

2.mapstate与mapGetters

(1)mapstate

当我用插值语法用index中state中的数据的时候,都还得写$store.state、、、,写多了很麻烦,vuex为我们准备了一个方法:

首先先引入:

import {mapState} from 'vuex'
computed: {
    ...mapState({ sum: "sum", school: "school", subject: "subject" }),
  },

...是es6语法,因为mapState也是一个对象,不能{  }里面再直接套一个对象{},又不是插值语法,...最后再加逗号,里面第一个是上面div要用的,第二个是index里的命名,自动就给你补齐$store.state了,然后在div里直接用:

 <h2>我在{{ school }}里学习{{ subject }}</h2>

a:a才能简写为a,但是num:‘num’不能简写(对象写法不能简写)

但是数组方法可以简写:注意:这是前后两个名字相同的情况下!!

一个名字两个用途,既可以用在index,也可以用在myCount组件

...mapState(['sum','school', 'subject' ]),

(2)mapGetters

用法一样

...mapGetters(['bigSum ' ]),
//...mapGetters({bigSum='bigSum'}),

3.mapActions与mapMutations

(1)mapMutations

借助mapMutations生成对应的方法,方法中会调用commit去联系Mutations

methods: {
    // increment() {
    //   //this.$store.dispatch("jia", this.n);
    //   this.$store.commit("JIA", this.n);
    //   // $store是在vc身上的
    // },
    // decrement() {
    //   //this.$store.dispatch("jian", this.n);
    //   this.$store.commit("JIAN", this.n);
    //   //直接去找mutations
    // },
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),

但是这么写还有点问题,确实被调用了,但是没有告诉人家n是多少,人家就默认传过去的value是鼠标点击事件,所以调用函数的时候得把n传过去

    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>

(2)mapActions

借助mapActions生成对应的方法,方法中会调用dispatch去联系Actions

 // incrementOdd() {
    //   this.$store.dispatch("jiaOdd", this.n);
    // },
    // incrementWait() {
    //   this.$store.dispatch("jiaWait", this.n);
    // },
    ...mapActions({ incrementOdd: "jiaOdd", incrementWait: "jiaWait" }),

五、多组件共享数据

mapstate引入state里其他组件的数据,然后直接插值语法用就行

computed: {
      ...mapState(['personList','sum'])
  },
<h2>上方组件的求和为:{{sum}}</h2>

六、Vuex模块化+命名空间

目的

让代码更好维护,让多种数据分类更加明确。

(1)Count组件

我们的action、mutations、state包含了两个组件的内容,如果内容很多的话,写一块就很乱,可以把他们分开写

//求和相关的配置
const countOptions={
    actions:{
        jiaOdd(context,value) {
            if(context.state.sum%2)
            {
                context.commit('JIA',value)
                //这儿不用写JIAODD因为调用的都是jia,然后下面也就不用加JIAODD了
            }
        },
        jiaWait(context,value) {
            setTimeout(()=>{
                context.commit('JIA',value)
            },500)
        },
    },
    mutations:{
        JIA(state,value) {
            state.sum+=value
        },
        JIAN(state,value) {
            state.sum-=value
        },
    },
    state:{
        sum: 0,
        school:'bj',
        subject:'qd',
    },
    getters:{
        bigSum(state){
            return state.sum*10
        }
    },
}
//人员相关的配置
const personOptions={
    actions:{},
    mutations:{
        ADD_PERSON(state,value){
            //value就是人的对象obj 
            state.personList.unshift(value)
            //往前放
        }
    },
    state:{
        personList:[
            {id:'001',name:'tt'}
        ]
    },
    getters:{},
}
const store = new Vuex.Store({
    modules:{
        a:countOptions,
        b:personOptions
        //此时store里面就剩a、b了,mapState下的sum根本找不着了
    }
})

再想在组件里用可不能直接写num、school啥的了,因为store里只有a和b,就得带着a、b引用

computed: {
    //...mapState({ sum: "sum", school: "school", subject: "subject" }),
    ...mapState(['a', 'b']),
<h2>当前求和为:{{ a.sum }}</h2>
    <h2>当前和乘十为:{{ bigSum }}</h2>
    <h2>我在{{ a.school }}里学习{{ a.subject }}</h2>
    <h3>下方组件的总人数是:{{b.personList.length}}</h3>

哪儿都带着a、b调用吧又很麻烦,可以直接在computed里面给这些东西加a. b.

computed: {
    ...mapState('a',['sum','school','subject']), 
    ...mapState('b',['personList']), 

但是这个用法得配合开启命名空间namespaced:true,用,否则不生效,自己定义的配置后面都得写

const personOptions={
    namespaced:true,

包括方法啥的也得改是谁谁下的,后面是数组是对象都行

methods: {
    ...mapMutations('a',{ increment: "JIA", decrement: "JIAN" }),
    ...mapActions('a',{ incrementOdd: "jiaOdd", incrementWait: "jiaWait" }),
  },

(2)person组件

前面提到的要改正的不再多说,person要想调用ADD_PERSON方法,在前面加???/

this.$store.commit('b/ADD_PERSON',personObj)

又添加了一些功能并且把两个js分出去单独写了

index.js
//该文件用于创建Vuex中最核心的store
//actions——响应组件中的动作
//引入Vue
import Vue from 'vue'
import Vuex from 'vuex'
import personOptions from './myPerson'
import countOptions from './myCount'
Vue.use(Vuex)

 
//创建store还得向外暴露
const store = new Vuex.Store({
    modules:{
        a:countOptions,
        b:personOptions
        //此时store里面就剩a、b了,mapState下的sum根本找不着了
    }
})

export default store
myPerson.vue
<template>
  <div>
    <h1>人员列表</h1>
    <h3>我想返回的列表的第一个人的名字是:{{ firstPersonName }}</h3>
    <h2>上方组件的求和为:{{ a.sum }}</h2>
    <input type="text" placeholder="请输入姓名" v-model="name" />
    <button @click="add">添加</button>
    <button @click="addWang">添加一个姓王的人</button>
    <button @click="addPersonServer">添加一个人</button>
    <ul>
      <li v-for="p in b.personList" :key="p.id">{{ p.name }}</li>
    </ul>
  </div>
</template>

<script>
import { mapState } from "vuex";
import { nanoid } from "nanoid";
export default {
  name: "myPerson",
  data() {
    return {
      name: "",
    };
  },
  computed: {
    ...mapState(["a", "b"]),
    firstPersonName() {
      return this.$store.getters["b/firstPersonName"];
      //有.就不能有/,可以用[]代替.
    },
  },
  methods: {
    add() {
      const personObj = { id: nanoid(), name: this.name };
      this.$store.commit("b/ADD_PERSON", personObj);
      this.name = "";
      //输完之后框清除
    },
    addWang() {
      const personObj = { id: nanoid(), name: this.name };
      this.$store.dispatch('b/addPersonWang', personObj);
      this.name = "";
    },
    addPersonServer(){
      this.$store.dispatch('b/addPersonServer')
    }
  },
};
</script>

<style>
</style>
myCount.vue
<template>
  <div>
    <h2>当前求和为:{{ sum }}</h2>
    <h2>当前和乘十为:{{ bigSum }}</h2>
    <h2>我在{{ school }}里学习{{ subject }}</h2>
    <h3>下方组件的总人数是:{{personList.length}}</h3>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <!-- 这里除了最开始设置的数字1,其他都是字符串所以都加不了了 -->
      <!-- 所以加 :value,当成js表达式去解析 或者加.number强制转换-->
    </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: "myCount",
  data() {
    return {
      n: 1, //用户选择的数字
    };
  },
  computed: {
    ...mapState('a',['sum','school','subject']), 
    ...mapState('b',['personList']), 
    //sum: "sum", school: "school", subject: "subject" }),
    //...mapState('a',['a', 'b']),
   ...mapGetters('a',['bigSum']),
  },
  methods: {
    ...mapMutations('a',{ increment: "JIA", decrement: "JIAN" }),
    ...mapActions('a',{ incrementOdd: "jiaOdd", incrementWait: "jiaWait" }),
  },
};
</script>

<style>
button {
  margin-left: 5px;
}
</style>
myCount.js
//求和相关的配置
const countOptions={
    namespaced:true,
    actions:{
        jiaOdd(context,value) {
            if(context.state.sum%2)
            {
                context.commit('JIA',value)
                //这儿不用写JIAODD因为调用的都是jia,然后下面也就不用加JIAODD了
            }
        },
        jiaWait(context,value) {
            setTimeout(()=>{
                context.commit('JIA',value)
            },500)
        },
    },
    mutations:{
        JIA(state,value) {
            state.sum+=value
        },
        JIAN(state,value) {
            state.sum-=value
        },
    },
    state:{
        sum: 0,
        school:'bj',
        subject:'qd',
    },
    getters:{
        bigSum(state){
            return state.sum*10
        }
    },
}
export default countOptions
myPerson.js
import axios from "axios"
//import { response } from "express"
import { nanoid } from "nanoid"


//人员相关的配置
const personOptions={
    namespaced:true,
    actions:{
        addPersonWang(context,value){
            if(value.name.indexOf('王')==0)
            {
                context.commit('ADD_PERSONSE',value)
                //如果包括王而且位置还是第一个
            }else{
                alert ('添加的人得姓王!')
            }
        },
        addPersonServer(context){
            axios.get('http://api.uixsj.cn/hitokoto/get?type=social').then(
                response=>{
                    context.commit('ADD_PERSONSE',{id:nanoid(),anme:response.data})
                },
                error=>{
                    alert(error.message)
                }
            ) 
        }
    },
    mutations:{
        ADD_PERSONSE(state,value){
            //value就是人的对象obj 
            state.personList.unshift(value)
            //往前放
        }
    },
    state:{
        personList:[
            {id:'001',name:'tt'}
        ]
    },
    getters:{
        firstPersonName(state){
            return state.personList[0].name
            //这里的state是局部的
        }
    },
}
export default personOptions

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

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

相关文章

阿里云优惠券领取方法大公开,省钱不再是难事

阿里云作为国内领先的云计算服务提供商&#xff0c;为广大用户提供了丰富的云产品和解决方案。为了吸引用户上云&#xff0c;阿里云经常推出各种优惠活动&#xff0c;其中最受用户欢迎的就是阿里云优惠券。那么&#xff0c;阿里云优惠券究竟是什么呢&#xff1f;我们又该如何领…

代码随想录第25天|216.组合总和III 17.电话号码的字母组合

216.组合总和III 216. 组合总和 III - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 和组合问题有啥区别&#xff1f;回溯算法如何剪枝&#xff1f;| LeetCode&#xff1a;216.组合总和III_哔哩哔哩_bilibili 找出所有相加之和为 n 的 k 个数的组…

基于自动编码器的预训练模型方法模型预训练方法RetroMAE和RetroMAE-2

文章目录 RetroMAERetroMAE详情编码解码增强解码 RetroMAE-2RetroMAE-2详情编码[CLS]解码OT解码和训练目标向量表征 总结参考资料 RetroMAE RetroMAE 出自论文《RetroMAE: Pre-Training Retrieval-oriented Language Models Via Masked Auto-Encoder》&#xff0c;是一种针对于…

「MySQL」索引事务

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;数据库 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 索引&事务 &#x1f349;索引&#x1f34c;特点&#x1f34c;通过 SQL 操作索引&#x1f34c;底层数据结构 &#x1f349;事务&…

网络编程的学习1

网络编程 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行数据传输。 三要素 ip&#xff1a;设备在网络中的地址&#xff0c;是唯一的标识。 ipv4:采取32位地址长度&#xff0c;分成4组。 ipv6&#xff1a;采用128位地址长度&#xff0c;分成8组。 …

安卓SharedPreferences使用

目录 一、简介二、使用2.1 getSharedPreferences2.2 增加数据2.3 读取数据2.4 删除数据2.5 修改数据2.6 清除数据2.7 提交数据 一、简介 SharedPreferences是Android平台上一个轻量级的存储类&#xff0c;主要是保存一些常用的配置比如窗口状态&#xff0c;一般在Activity、重…

12.Python文件读写

文件是数据的载体&#xff0c;程序可以从文件中读取数据&#xff0c;也可以将数据写 入文件中&#xff0c;本章重点介绍如何在Python中进行文件读写。 1 打开文件 我们在使用文件之前要先将文件打开&#xff0c;这通过open&#xff08;&#xff09;函数实现。 open&#xff0…

JJJ:linux系统中第一个进程

以linux4.19内核linux系统中第一个进程。 执行shell指令 ps -ef 结果如下&#xff1a; xxxxxx-virtual-machine:~$ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 20:55 ? 00:00:02 /sbin/init splash root …

【Web应用技术基础】CSS(4)——背景样式

第1题&#xff1a;背景颜色 .html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Hello World</title><link rel"stylesheet" href"step1/CSS/style.css"> </head><body>&…

词令蚂蚁庄园今日答案正确答案怎么获取查看蚂蚁庄园今天问题的正确答案?

词令蚂蚁庄园今日答案正确答案怎么获取查看蚂蚁庄园今天问题的正确答案&#xff1f; 1、打开「词令」关键词口令直达工具&#xff1b; 2、输入词令关键词直达口令「今日答案999」&#xff1b; 3、搜索直达词令蚂蚁庄园今日问题的正确答案&#xff1b; *注&#xff1a;词令蚂蚁…

【PythonGIS】Python实现批量导出面矢量要素(单个多面矢量->多个单面矢量)

可怜的我周六还在工作&#xff0c;已经很久没更新过博客了&#xff0c;今天正好有空就和大家分享一下。今天给大家带来的是使用Python将包含多个面要素/线要素的矢量批量导出单个要素的矢量&#xff0c;即一个要素一个矢量文件。之前写过多个矢量文件合并成一个矢量文件的博文&…

西南交大swjtu算法实验3.3|穷举法

1.实验目的 通过具体例子学习排列这种典型的穷举算法的求解过程以及程序框架&#xff0c;分析其算法的求解过程&#xff0c;以及如何设计穷举法解决实际问题。通过本实验&#xff0c;理解穷举法的特点以及实际应用中的局限性。 2.实验任务 有n (n>1&#xff09;个任务需要…

Visual Studio 2022 中VLD库如何安装

GitHub链接 Release v2.5.1 KindDragon/vld 点击可执行程序进行下载 点击可执行程序进行安装 双击打开 一直点击next即可完成安装&#xff08;不用在意安装路径&#xff0c;总共不到2MB&#xff09; 如果GitHub无法打开&#xff0c;可以私信我发你安装包直接安装

fpga_awb

色温: sesor原始图像中的白色如果不经AWB处理&#xff0c;在高色温(如阴天)下偏蓝&#xff0c;在低色温下偏黄。 引入白平衡算法 而AWB的核心就是调整图像色温&#xff0c;使得摄像头采集的图像更加真实&#xff0c;达到人眼观察的效果。 白平衡一般通过调节传感器输出图像RGB…

【aws】架构图工具推荐

碎碎念 以前以为日本冰箱论是个梗&#xff0c;结果居然是真的。用光盘传真其实还能理解&#xff08;毕竟我也喜欢电子古董2333&#xff09;&#xff0c;但是画架构图居然用的是excel&#xff0b;截图&#xff01;啊苍天呐&#xff0c;然后看到隔壁工位用excel画web原型又感觉释…

svg实现环形进度条

实现效果图&#xff1a; svg相关知识 这里只介绍本次用到的元素&#xff0c;更多详情&#xff1a;SVG&#xff1a;可缩放矢量图形 defs&#xff1a;定义需要重复利用的图形元素linearGradient&#xff1a;定义线性渐变&#xff0c;用来图形元素的填充或描边使用stop&#x…

hcip综合实验2

目录 实验拓扑&#xff1a; 实验要求&#xff1a; 实验思路&#xff1a; 实验步骤&#xff1a; 1.配置设备接口IP 2.通过配置缺省路由让公网互通 3.配置ppp 1.R1和R5间的ppp的PAP认证&#xff1b; 2.R2与R5之间的ppp的CHAP认证; 3. R3与R5之间的HDLC封装; 4.构建R1、…

动态规划之子序列(三)

583. 两个字符串的删除操作 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: “sea”, “eat” 输出: 2 解释: 第一步将"sea"变为"ea"…

c实现猜数游戏(猜不对可是要自动帮你电脑关机)

接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言 猜数字游戏作为一个基础的C程序小项目&#xff0c;实现简单&#xff0c;可以帮助我们巩固很多知识&#xff0c;作为扩展接下来我们实现一个自定猜数次数&#xff0c;用完次数电脑自动…

keepalived+LVS高可用部署

目录 一.两台设备&#xff08;2.130和2.133&#xff09;作为调度器&#xff0c;前主后备 1.部署keepalived 2.修改配置文件准备启动 3.配置keepalived的系统日志并启动 二.模拟调度器掉点和web服务进程丢失 1.调度器掉点 2.当类似于httpd这种网站服务掉点 三.以三种健康…