ES6 课程概述⑦

news2024/12/29 13:52:55

文章目录

  • Vuex_State
    • 安装
    • 使用
    • State
      • 在 Vue 组件中获得 Vuex 状态
      • mapState 辅助函数
  • Vuex_Getter
    • 通过属性访问
    • 通过方法访问
    • mapGetters 辅助函数
  • Vuex_Mutation
    • 在组件中提交 Mutation
    • 提交载荷(Payload)
    • 对象风格的提交方式
    • 使用常量替代 Mutation 事件类型
    • Mutation 需遵守 Vue 的响应规则
    • 表单处理
      • 双向绑定的计算属性
    • Mutation 必须是同步函数
    • 严格模式
      • 开发环境与发布环境
  • Vuex_Action
    • 分发 Action
    • 组合 Action
    • Vuex 管理模式
  • Vuex_Module
    • 命名空间
    • 模块的局部状态
    • VUE 中$refs 的基本用法
      • JSON.parse()
      • localStorage

Vuex_State

Vuex 是 vue 的状态管理工具,为了更方便的实现多个组件共享状态。

安装

npm install vuex --save

使用

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0,
  },
});

new Vue({
  store,
});

State

单一状态树,使用一个对象就包含了全部的应用层级状态。

在 Vue 组件中获得 Vuex 状态

Vuex 通过 store 选项,提供了一种机制将状态从跟组件“注入”到每一个子组件中(调用 Vue.use(Vuex))。

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问。

<div class="home">{{ $store.state.count }}</div>

mapState 辅助函数

当一个组件需要获取多个状态时,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性:

import { mapState } from 'vuex';

computed: {
  ...mapState(['count']),
},

使用不同的名字:

computed: {
  ...mapState({
    storeCount: state => state.count,
    // 简写
    storeCount: 'count', // 等同于 state => state.count
  }),
},

Vuex_Getter

store 的计算属性。getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

Getter 接收 state 作为其第一个参数、getters 作为其第二个参数。

getters: {
  doubleCount (state) {
    return state.count * 2;
  }
}

通过属性访问

Getter 会暴露为 store.getters 对象:this.$store.getters.doubleCount

通过方法访问

也可以让 getter 返回一个函数,来实现给 getter 传参

getters: {
  addCount: (state) => (num) => state.count + num;
}
this.$store.addCount(3);

mapGetters 辅助函数

import { mapsGetters } from "vuex";

export default {
  computed: {
    ...mapGetters(["doubleCount", "addCount"]),
  },
};

如果你想将一个 getter 属性另取一个名字,使用对象形式:

mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  storeDoubleCount: "doubleCount",
});

Vuex_Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

const store = new Vuex.Store({
  state: {
    count: 1,
  },
  mutations: {
    increment(state) {
      // 变更状态
      state.count++;
    },
  },
});

不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为increment的 mutation 时,调用次函数。”:

this.$store.commit("increment");

在组件中提交 Mutation

除了在组件中使用 this.$store.commit('xxx') 提交 mutation 之外,还可以使用 mapMutations 辅助函数:

import { mapMutations } from "vuex";

export default {
  // ...
  methods: {
    ...mapMutations([
      "increment", // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
    ]),
    ...mapMutations({
      add: "increment", // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    }),
  },
};

提交载荷(Payload)

你可以向 store.commit 传入额外的参数,即 mutation 的载荷(payload):

mutations: {
  increment (state, n) {
    state.count += n
  }
}
store.commit("increment", 10);

在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
store.commit("increment", {
  amount: 10,
});

对象风格的提交方式

提交 mutation 的另一种方式是直接使用包含 type 属性的对象:

store.commit({
  type: "increment",
  amount: 10,
});

当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变:

mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

使用常量替代 Mutation 事件类型

把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然:

// mutation-types.js
export const COUNT_INCREMENT = "COUNT_INCREMENT";
// store.js
import Vuex from 'vuex'
import { COUNT_INCREMENT } from './mutation-types'

const store = new Vuex.Store({
  state: { ... },
  mutations: {
    [COUNT_INCREMENT] (state) {
      // ...
    }
  }
})

用不用常量取决于自己,在需要多人协作的大型项目中,这会很有帮助。

Mutation 需遵守 Vue 的响应规则

既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新。这也意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:

  • 最好提前在你的 store 中初始化好所有所需属性。
  • 当需要在对象上添加新属性时,你应该
    • 使用 Vue.set(obj, ‘newProp’, 123), 或者
    • 以新对象替换老对象。例如,利用对象展开运算符我们可以这样写:
      state.obj = { ...state.obj, newProp: 123 };
      

表单处理

在 Vuex 的 state 上使用 v-model 时,由于会直接更改 state 的值,所以 Vue 会抛出错误。

如果想要使用双向数据的功能,就需要自己模拟一个 v-model: :value=“msg” @input=“updateMsg”。

双向绑定的计算属性

上面的做法,比 v-model 本身繁琐很多,所以我们还可以使用计算属性的 setter 来实现双向绑定:

<input v-model="msg" />
computed: {
  msg: {
    get () {
      return this.$store.state.obj.msg;
    },
    set (value) {
      this.$store.commit(UPDATE_MSG, { value });
    }
  }
}

Mutation 必须是同步函数

要记住 mutation 必须是同步函数。why?

mutations: {
  [COUNT_INCREMENT] (state) {
    setTimeout(() => {
      state.count ++;
    }, 1000)
  },
}

执行上端代码,我们会发现更改 state 的操作是在回调函数中执行的,这样会让我们的代码在 devtools 中变的不好调试:当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用,任何在回调函数中进行的状态的改变都是不可追踪的。

严格模式

开启严格模式,仅需在创建 store 的时候传入 strict: true:

const store = new Vuex.Store({
  // ...
  strict: true,
});

在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

开发环境与发布环境

不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更,要确保在发布环境下关闭严格模式,以避免性能损失。

const store = new Vuex.Store({
  // ...
  strict: process.env.NODE_ENV !== "production",
});

Vuex_Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters:

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

分发 Action

store.dispatch("increment");

虽然和 mutation 差不多,但是在 action 中,可以执行异步操作,但是 mutation 中不行!!!

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

组合 Action

Action 通常是异步的,那么如何知道 action 什么时候结束呢?

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}
store.dispatch("actionA").then(() => {
  // ...
});

Vuex 管理模式

Vuex_Module

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

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。

modules: {
  a, b;
}
  • 获取 state:this.$store.state.moduleName.xxx
  • 获取 getter:this.$store.getters.xxx
  • 提交 mutation:this.$store.commit(‘xxx’);
  • 分发 action:this.$store.dispatch(‘xxx’);
  • 可以通过 mapXXX 的方式拿到 getters、mutations、actions,但是不能拿到 state,如果想通过这种方式获得 state,需要加命名空间。

命名空间

可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。

  • 获取 state:this.$store.state.moduleName.xxx
  • 获取 getter:this.$store.[‘moduleName/getters’].xxx
  • 提交 mutation:this.$store.commit(‘moduleName/xxx’);
  • 分发 action:this.$store.dispatch(‘moduleName/xxx’);
  • 可以通过 mapXXX 的方式获取到 state、getters、mutations、actions。

模块的局部状态

对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。

同样,对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState。

对于模块内部的 getter,根节点状态会作为第三个参数暴露出来。

VUE 中$refs 的基本用法

ref 有三种用法:
1、ref 加在普通的元素上,用 this.$refs.(ref 值) 获取到的是 dom 元素

2、ref 加在子组件上,用 this. r e f s . ( r e f 值)获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接 t h i s . refs.(ref值) 获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this. refs.ref值)获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this.refs.(ref 值).方法() 就可以使用了。

3、如何利用 v-for 和 ref 获取一组数组或者 dom 节点

应注意的坑:
1、如果通过 v-for 遍历想加不同的 ref 时记得加 :号,即 :ref =某变量 ;
这点和其他属性一样,如果是固定值就不需要加 :号,如果是变量记得加 :号。(加冒号的,说明后面的是一个变量或者表达式;没加冒号的后面就是对应的字符串常量(String))

2、通过 :ref =某变量 添加 ref(即加了:号) ,如果想获取该 ref 时需要加 [0],如 this. r e f s [ r e f s A r r a y I t e m ] [ 0 ] ;如果不是 : r e f = 某变量的方式而是 r e f = 某字符串时则不需要加,如 t h i s . refs[refsArrayItem] [0];如果不是:ref =某变量的方式而是 ref =某字符串时则不需要加,如this. refs[refsArrayItem][0];如果不是:ref=某变量的方式而是ref=某字符串时则不需要加,如this.refs[refsArrayItem]。

1、ref 需要在 dom 渲染完成后才会有,在使用的时候确保 dom 已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。

2、如果 ref 是循环出来的,有多个重名,那么 ref 的值会是一个数组 ,此时要拿到单个的 ref 只需要循环就可以了。

例子 1:
添加 ref 属性

<div id="app">
  <h1 ref="h1Ele">这是H1</h1>
  <hello ref="ho"></hello>
  <button @click="getref">获取H1元素</button>
</div>
methods: { getref() { 表示从 $refs对象 中, 获取 ref 属性值为: h1ele
DOM元素或组件 console.log(this.$refs.h1Ele.innerText);
this.$refs.h1ele.style.color = 'red';// 修改html样式
console.log(this.$refs.ho.msg);// 获取组件数据
console.log(this.$refs.ho.test);// 获取组件的方法 } } 例子2: Vue代码:
<el-table
  @sort-change="sortChange"
  ref="multipleSelection"
  border
  :data="valueDryGoodTableData"
  style="width: 100%"
>
  <el-table-column
    align="left"
    prop="title"
    label="标题"
    min-width="80%"
    sortable="custom"
  >
    <template slot-scope="scope">
      <a
        target="_blank"
        :class="scope.row.titleClicked?'titleClicked':''"
        class="hoverHand bluetext"
        v-html="scope.row.title"
        @click="titleClick(scope.row.articleUrl,scope.$index)"
      >
      </a>
    </template>
  </el-table-column>
  <el-table-column
    align="left"
    prop="releaseTime"
    label="发布日期"
    min-width="11%"
    sortable="custom"
  ></el-table-column>
  <el-table-column align="center" label="操作" min-width="9%">
    <template slot-scope="scope">
      <span class="operatoryTools">
        <i
          title="取消收藏"
          v-if="scope.row.isFavour"
          @click="favoriteOperating(scope.row.id, scope.$index)"
          class="hoverHand iconStyle el-icon-star-on"
        ></i>
        <i
          title="收藏"
          v-else
          @click="favoriteOperating(scope.row.id, scope.$index)"
          class="hoverHand iconStyle el-icon-star-off"
        ></i>
        <i
          title="分享"
          @click.stop="showShareOperation(scope.$index)"
          class="shareTarg iconfont"
          >&#xe678;</i
        >
        <div class="share" v-if="scope.row.showShare">
          <img
            class="hoverHand shareItem"
            title="分享到微博"
            @click="shareItem('sina',$event);"
            src="@/images/WEIBO.png"
          />
          <img
            class="hoverHand shareItem"
            title="分享到微信"
            @click.stop="shareItem('wx',$event);"
            src="@/images/WEIXIN.png"
          />
          <img
            class="hoverHand shareItem"
            title="分享到QQ"
            @click="shareItem('qq',$event);"
            src="@/images/QQ.png"
          />
        </div>
        <div v-show="scope.row.erweimaShare" class="erweima_share"></div>
        <div v-show="scope.row.erweimaShare1" class="erweima_share1"></div>
      </span>
    </template>
  </el-table-column>
</el-table>
JS 代码: //点击清空条件,调用该方法 emptyAndSearch(){//清空条件方法
//清空树选中状态 this.clearTreeNodeCheck(['tree']); //清除排序
this.$refs.multipleSelection.clearSort(); //设置分页参数 this.queryParam = {
startRow : 1, pageSize : 20, condition:{ } } //分页查询调用
this.confirmSearch('statistics'); //设置清空条件为false
this.$store.commit('valueDryGoodDatas/SET_CLEAR_ALL',false); }
例子 3: Vue 代码:

<el-form-item
  ref="goodPicInfoFormpicUrl"
  :label="$t('许可证证照')"
  class="is-required"
  prop="picUrl"
>
  <el-upload
    :show-file-list="false"
    :http-request="uploadImg"
    :data="certImgform"
    action=""
    class="avatar-uploader"
  >
    <img v-if="queryFrom.picUrl" :src="queryFrom.picUrl" class="avatar" />
    <i v-else class="el-icon-plus avatar-uploader-icon" />
  </el-upload>
  <el-button
    type="primary"
    plain
    size="mini"
    @click="viewPcPic(queryFrom.picUrl)"
    >{{ $t('查看') }}</el-button
  >
</el-form-item>
JS 代码: //获取元素清除验证 this.$refs.goodPicInfoFormpicUrl.clearValidate()
一般来讲,想获取 INPUT 框,首先在获取 DOM 元素,需
document.querySelector(".input1")获取这个 dom 节点,然后在获取 input1 的值。
但是用 ref 绑定之后,我们就不需要在获取 dom 节点了,直接在上面的 input 上绑定
input1,然后$refs 里面调用就行。 然后在 javascript
里面这样调用:this.$refs.input1   这样就可以减少获取 dom 节点的消耗了

JSON.parse()

JSON.parse()
JSON 通常用于与服务端交换数据。

在接收服务器数据时一般是字符串。

我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。

语法
JSON.parse(text[, reviver])
参数说明:

text:必需, 一个有效的 JSON 字符串。
reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。

JSON 解析实例
例如我们从服务器接收了以下数据:

{ "name":"runoob", "alexa":10000, "site":"www.dc3688.com" }
我们使用 JSON.parse() 方法处理以上数据,将其转换为 JavaScript 对象:

var obj = JSON.parse('{ "name":"runoob", "alexa":10000, "site":"www.dc3688.com" }');

localStorage

HTML5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。我们这里以 localStorage 为例,简要介绍下 html5 的本地存储,并针对如遍历等常见问题作一些示例说明。 localStorage 是 Html5 本地存储的 API,使用键值对的方式进行存取数据,存取的数据只能是字符串。不同浏览器对该 API 支持情况有所差异,如使用方法、最大存储空间等。 

  存储方式:以键值对(Key-Value)的方式存储字符串。

  主要应用:购物车、客户登录、游戏存档。。。

  可储存的数据类型:数组,图片,json,样式,脚本。。。(只要是能序列化成字符串的内容都可以存储)

  储存地址:C:\Users\15014\AppData\Local\Google\Chrome\User Data\Default\Local Storage(不同电脑不一样,需要打开隐藏文件显示,但是在C盘搜索localStorage就能搜出这个文件夹。)

localStorage的优势

1、localStorage拓展了cookie的4K限制

2、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的

localStorage的局限

1、浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性

2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换

3、localStorage在浏览器的隐私模式下面是不可读取的

4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡

5、localStorage不能被爬虫抓取到

localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

这里我们以localStorage来分析

localStorage的使用

首先在使用localStorage的时候,我们需要判断浏览器是否支持localStorage这个属性

if(!window.localStorage){
            alert("浏览器支持localstorage");
            return false;
        }else{
            //主逻辑业务
        }


localStorage官方提供了四个方法来辅助我们进行对本地存储做相关操作。

  (1)localStorage.setItem(键名,键值)在本地客户端存储一个字符串类型的数据,其中,第一个参数“键名”代表了该数据的标识符,而第二个参数“键值”为该数据本身。如:

        localStorage.setItem("name", "张三");      //存储键名为name和键值为"张三"的数据到本地
        localStorage.setItem("age", "28");        //存储键名为age和键值为"28"的数据到本地
  (2)localStorage.getItem(键名) 读取已存储在本地的数据,通过键名作为参数读取出对应键名的数据。如:

    var data = localStorage.getItem("name");
    alert(data);//张三
  (3)localStorage.removeItem(键名)移除已存储在本地的数据,通过键名作为参数删除对应键名的数据。如:

    var data2 = localStorage.removeItem("name");//从本地存储中移除键名为name的数据
    alert(data2); //undefined
  (4)localStorage.clear() 移除本地存储所有数据。如:

    localStorage.clear() 移除本地存储所有数据。如:
    localStorage.clear();      //保存着的"age/28"和"name/张三"的键/值对也被移除了,所有本地数据拜拜
   (5)另外,sessionStorage中的四个函数与以上localStorage类的函数用法基本一致,就不再详解。

下面是一个小实例:

<script type="text/javascript">

            localStorage.setItem("name", "张三");
            localStorage.setItem("age", "28");

            verify();   //验证本地存储
            localStorage.removeItem("name");
            verify();   //验证name是否存在
            localStorage.clear();
            verify();   //验证name和age是否存在

            //自定义验证函数,验证name和age的数据是否存在
            function verify(){
                var type = localStorage.getItem("name");
                var price = localStorage.getItem("age");
                type = type ? type : '不存在';
                price = price ? price : '不存在';

                alert( "name: " + type + "\n\n" + "age: " + price );
            }

        </script>
复制代码
其实

localStorage的写入和读取 有三种方法,这里就一一介绍一下

if(!window.localStorage){
            alert("浏览器支持localstorage");
        }else{
            var storage=window.localStorage;
            //写入a字段
            storage["a"]=1;
            //写入b字段
            storage.b=1;
            //写入c字段
            storage.setItem("c",3);
            console.log(typeof storage["a"]);
            console.log(typeof storage["b"]);
            console.log(typeof storage["c"]);
            //第一种方法读取
            var a=storage.a;
            console.log(a);
            //第二种方法读取
            var b=storage["b"];
            console.log(b);
            //第三种方法读取
            var c=storage.getItem("c");
            console.log(c);
        }
注意到,刚刚存储进去的是int类型,但是打印出来却是string类型,这个与localStorage本身的特点有关,localStorage只支持string类型的存储。

localStorage的删除

1、 将localStorage中的某个键值对删除

localStorage.setItem("c",3);
console.log(localStorage.getItem('c'));
localStorage.removeItem("c");
console.log(localStorage.getItem('c'));
2、 将localStorage的所有内容清除

storage.clear();


localStorage的键获取
var storage=window.localStorage;
            storage.a=1;
            storage.setItem("c",3);
            for(var i=0;i<storage.length;i++){
                var key=storage.key(i);
                console.log(key);
            }


localStorage其他注意事项

一般我们会将JSON存入localStorage中,但是在localStorage会自动将localStorage转换成为字符串形式

这个时候我们可以使用JSON.stringify()这个方法,来将JSON转换成为JSON字符串,

示例:
var data={
    name:'xiecanyong',
    sex:'man',
    hobby:'program'
};
var json_string=JSON.stringify(data);
localStorage.setItem("data",d);
console.log(localStorage.data);

//将JSON字符串转换成为JSON对象输出
var json_str=localStorage.getItem("data");
var jsonObj=JSON.parse(json_str);
console.log(typeof jsonObj);
读取之后要将JSON字符串转换成为JSON对象,使用JSON.parse()方法

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

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

相关文章

Spring Boot(五十六):基于Redis的搜索栏热搜功能

1 功能要求 使用SpringBoot和redis实现一个简单的热搜功能&#xff0c;具备以下功能&#xff1a; 搜索栏展示当前登陆的个人用户的搜索历史记录&#xff0c;删除个人历史记录用户在搜索栏输入某字符&#xff0c;则将该字符记录下来 以zset格式存储的redis中&#xff0c;记录该…

Flink DataSet API和DataStream API 对于WordCount的演示

文章目录准备工作Flink DataSet APIFlink DataStream API结论准备工作 pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-insta…

如何多人配音一个作品?这3招帮你快速实现

大家平时喜欢听书吗&#xff1f;听书是一种既能释放双眼&#xff0c;又能降低压力的放松方式。那么大家平时在听书的时候&#xff0c;有没有碰到过一些多人配音的小说&#xff1f;大家有好奇过这样的小说是怎么来的吗&#xff1f;今天&#xff0c;教大家多人配音怎么制作的&…

请问想考软考,零基础的话,哪个证书最好考呢

可以直接考中级&#xff0c;软考中级中也有适合零基础报考的&#xff0c;中级的含金量也比初级的高&#xff0c;初级的用途不太大&#xff0c;建议直接中级。 系统集成项目管理工程师&#xff0c;软考中级比较热门的一个科目&#xff0c;零基础的也适合相比较容易通过。 软考…

Fisher确切概率基本原理详解

Fisher确切概率 基本原理 比较两组有效率是否有差异。 在周边合计不变的情况下&#xff0c;计算实际频率变动时的Pi&#xff08;概率&#xff09;。然后计算累积概率&#xff0c;依据检验水平做推断。 累积概率的计算 以a从小到大的概率排序 左侧概率&#xff1a;现有样本…

【SpringCloud17】SpringCloud Alibaba入门简介

1.为什么会出现SpringCloud Alibaba Spring Cloud Netflix项目进入维护模式官网 1.1 什么是维护模式 将模块置于维护模式&#xff0c;意味着 Spring Cloud 团队将不会再向模块添加新功能。我们将修复 block 级别的 bug 以及安全问题&#xff0c;我们也会考虑并审查社区的小型 …

shell处理多盘跑fio(minimal)的结果脚本编写

作为一个专业测试storage的测试人员&#xff0c;除了对服务器&#xff0c;硬盘熟悉之外&#xff0c;还要对测试工具fio特别熟悉才行。如果在OEM或者专门的HDD&SSD厂家测试&#xff0c;会经常看到测试脚本里边&#xff0c;开发喜欢用fio minimal 模式&#xff0c;这样解析lo…

【GD32F427开发板试用】利用SPI驱动ADS8354

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;STY 前言 本文期望通过板载硬件SPI外加DMA传输的方式来实现对全差分同步采样模数转换器ADS8354的控制&#xff0c;并且将采集数据进行初步脉冲…

2.1、进程的定义、组成、组织方式、特征

整体框架 1、进程的定义 程序\color{red}程序程序&#xff1a;就是一个指令序列 早期的计算机&#xff08;只支持单道\color{red}单道单道程序&#xff09; 引入多道\color{red}多道多道程序之后&#xff1a; 为了方便操作操作系统管理&#xff0c;完成各个程序并发执行、 引…

Go map 实现原理

Go map 实现原理 go map 源码路径在&#xff1a; src/runtime/map.gogo 源码结构 |– AUTHORS — 文件&#xff0c;官方 Go语言作者列表 |– CONTRIBUTORS — 文件&#xff0c;第三方贡献者列表 |– LICENSE — 文件&#xff0c;Go语言发布授权协议 |– PATENTS — 文件&…

如何解决Prometheus的数据回填问题

去年10月底的时候&#xff0c;我们的监控系统因为一个偶然的问题&#xff0c;出乎意料地发生了重大的故障&#xff0c;这次故障暴露了当前监控系统存在的一下重大隐患。故障背景及现象我们的监控系统基于Thanos构建&#xff0c;基本架构如下&#xff08;箭头表示数据流向&#…

Docker安装Mysql8.0主从复制

1使用portainer快速创建mysql 2.mysql-master version: 3.3 services:mysql-app:image: mysql:8.0container_name: mysqlrestart: alwaysports:- 3307:3306environment:MYSQL_ROOT_PASSWORD: 123456 # root用户的密码MYSQL_ROOT_HOST: % # 访问权限# MYSQL_USER: test …

[leetcode]刷题--关于位运算的几道题

&#xff08;1&#xff09;位运算的本质&#xff0c;其实是对二进制补码储存形式的修改。 位运算常见的运算符为 <<左移n个位置&#xff08;算数移位&#xff0c;符号位不变&#xff09; >>右移动n个位置&#xff08;采用直接丢弃末尾数字的方法&#xff0c;符号…

Android Raphael使用(专治native 内存泄漏)

1.前期准备 在项目根目录build.gradle中,添加仓库地址&#xff1a; allprojects {repositories {maven { url https://jitpack.io }} }2.案例实践 构建一个新的Library Module&#xff0c;其中build.gradle中添加依赖&#xff1a; dependencies {implementation com.github…

gitlab-runner搭建CI/CD

1. 背景 每次发布代码&#xff0c;需要连接服务器更新代码&#xff0c;进行部署&#xff0c;比较繁琐&#xff0c;浪费时间。方案有jenkins或gitlab-runner。由于代码仓库是gitlab并且只需要自动部署&#xff0c;不需要其他额外功能&#xff0c;这里选择使用gitlab-runner。 …

【React】三.React组件基础学习

目录 React组件介绍 React组件的两种创建方式 使用函数创建组件 函数组件 渲染函数组件 示例 使用类创建组件 抽离为独立的JS文件 步骤 问题记录 React事件处理 事件绑定 记录问题 事件对象 有状态组件和无状态组件 无状态组件&#xff08;木偶组件&#xff09;…

XSS(Cross Site Scripting)攻击简介

环境 Ubuntu 22.04IntelliJ IDEA 2022.1.3JDK 17.0.3.1Spring Boot 3.0.1Firefox 108.0.2 问题和分析 在IntelliJ IDEA中创建Spring Boot项目 test0116 &#xff0c;并选中 Spring Web 依赖。 在 src/main/java 下创建 MyController.java 如下&#xff1a; package com.ex…

Redis缓冲区不会还有人不知道吧?

1 简介 缓冲区&#xff0c;用一块内存空间暂时存放命令数据&#xff0c;以免因 数据和命令的处理速度&#xff1c;发送速度而导致数据丢失和性能问题。但缓冲区的内存空间有限&#xff0c;若持续&#xff1a; 往里写数据速度&#xff1e;从里读数据速度会导致缓冲区需越来越…

ATGM332D-5N卫星导航模块介绍

ATGM332D-5N卫星导航模块简介ATGM332D-5N系列模块是12X16 尺寸的高性能BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗GNSS SOC单芯片—AT6558&#xff0c;支持多种卫星导航系统&#xff0c;包括中国的BDS&#xff08;北斗卫星导航系统&…

BFS的入门与应用

目录 一、前言 二、BFS原理 二、BFS与最短路径 1、最短路径问题用BFS 2、迷宫&#xff08;2019年省赛&#xff0c;填空题&#xff0c;lanqiaoOJ题号602&#xff09; &#xff08;1&#xff09;字典序最小的最短路径 &#xff08;2&#xff09;输出路径的两种方法 三、B…