• React(react18)中组件通信05——redux ➕ react-redux(含数据共享)


    1. 前言

    1.1 React中组件通信的其他方式

    1.2 介绍React-Redux

    1.2.1 简单介绍React-Redux

    • React-Redux是Redux 官方提供的 React 绑定库。 具有高效且灵活的特性。
      • react-redux 是一个专为 React 应用开发而设计的基于 Redux 的库,提供了一些特定于 React 的功能和组件。
      • 它提供了一系列的 API 和组件,方便在 React 组件中使用 Redux 进行状态管理。
    • React-Redux 在概念上非常简单。它订阅 Redux 存储,检查组件所需的数据是否已更改,并重新渲染组件
    • react-redux 提供了一些特定于 React 的功能,如 connect 函数和 Provider 组件,用于连接 Redux 的 store,并将状态传递给 React 组件。
      • React Redux 提供的 组件,这使得 Redux store 能够在应用的其他地方使用(即:store只需在入口文件传递一次,其他需要store的容器组件中都可以获取)。

    1.2.2 官网

    1.3 安装react-redux

    • 安装命令如下:
      # If you use npm:
      npm install react-redux
      
      # Or if you use Yarn:
      yarn add react-redux
      
      • 1
      • 2
      • 3
      • 4
      • 5

    2. 简单改写redux的例子

    2.1 提供store

    • 第一步我们需要使得 store 对于我们的应用是可见的。为了做到这个,我们使用 React Redux 提供的 API 去包裹我们的应用。:
      • 首先先给改写后的目录结构
        在这里插入图片描述
      • 然后再看app.js 和 index.js
        在这里插入图片描述

    2.2 连接 Components + UI组件修改

    2.2.1 连接 Components

    • 先看官网怎么讲解的
      在这里插入图片描述

    • 先简单写写实现效果,后续再优化,如下:
      在这里插入图片描述

      import CountNumRedux from "../components/CountNumRedux";
      import { connect } from "react-redux";
      import store from '../redux/store'
      
      //这里ownProps如果用不到的话,可以不传,可以只传state
      const mapStateToProps = (state, ownProps) => ({
            // ...依据 state 和 自定义 ownProps 生成 computed data
            /**
             * 即状态统一在容器组件中管理
             * UI组件使用的话直接通过props取就行了,这种方式也相当于通过props传递
             * 如果监听state的变化,一有变化就调用,并把state通过props传递给UI组件
             */
            count:state
          //   name:'麦兜'
        });
      
        const mapDispatchToProps = ()=>({
          // ... 通常是一个充满 action creators 的 object
             addNumber:(number)=>{
                 store.dispatch(
                     { type: 'INCREMENT', number:number }
                 )
             },
             reduceNumber:(number)=>{
                 store.dispatch(
                     { type: 'DECREMENT', number:number }
                 )
             }
       });
      
        
      //   // 1. `connect` 返回一个接收要包装的组件的新函数:
      //   const connectToStore = connect(mapStateToProps, mapDispatchToProps);
      
      //   // 2. 并且该函数返回连接的,包装的组件:
      //   const ConnectedComponent = connectToStore(Component);
        
        // 通常我们会将两者一步完成,像这样:
      const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
      
      export default CountNumContainer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41

    2.2.2 修改UI组件

    • 如下:
      在这里插入图片描述

      import {  createRef } from "react";
      // import store from '../redux/store'
      // import countAction from '../redux/countAction'
      
      function CountNumRedux(props){
          console.log(props);
      
          // const [count,setCount] = useState(0);
          const numberRef = createRef();
      
          function add(){
              let number = numberRef.current.value;
              // console.log(typeof number);  //string
              // store.dispatch(countAction.incrementNum(parseInt(number)));
              props.addNumber(parseInt(number));
          }
      
          function subtract(){
              let number = parseInt(numberRef.current.value);
              props.reduceNumber(number);
          }
      
          // useEffect(()=>{
          //     store.subscribe(()=>{
          //         console.log('订阅更新,打印2-----',store.getState());
          //         setCount(store.getState());
          //     });
          // });
      
          return(
              <div>
                  {/* 当前数字是:{count}        
                  当前数字是:{store.getState()}   */}
      
                  当前数值是:{props.count}
                  <br />
                  浮动数字:<input type="number" ref={numberRef}/>
      
                  <br /><br />
                  <button onClick={add}>点我 加数</button> <br /><br />
                  <button onClick={subtract}>点我 减数</button>
              </div>
          )
      }
      export default CountNumRedux;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45

    2.2.3 看效果

    • 如下:
      在这里插入图片描述

    2.3 连接 Components——优化(优化容器组件)

    • 主要优化 mapDispatchToProps,用封装好的action,如下:

      import CountNumRedux from "../components/CountNumRedux";
      import { connect } from "react-redux";
      // import store from '../redux/store'
      import {incrementNum,decrementNum} from "../redux/countAction";
      
      
      const mapStateToProps = (state) => ({
            count:state
        });
      
      
      //   const mapDispatchToProps = ()=>({
      //        addNumber:(number)=>{
      //            store.dispatch(
      //                { type: 'INCREMENT', number:number }
      //            )
      //        },
      //        reduceNumber:(number)=>{
      //            store.dispatch(
      //                { type: 'DECREMENT', number:number }
      //            )
      //        }
      //  });
      
      /**
       * 1. dispatch:react-redux 会将dispatch传入,所以不用引入store来调了
       * 2. 引入已经封装好的action:countAction
       */
       const mapDispatchToProps = (dispatch)=>({
          addNumber:(number)=>{
              dispatch( incrementNum(number) )
          },
          reduceNumber:(number)=>{
              dispatch( decrementNum(number) )
          }
      });
      
      const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
      
      export default CountNumContainer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40

    2.4 优化容器组件(可怕的精简)

    • mapDispatchToProps: 此参数可以是一个 function,或者一个 object。
      • 上面都是用function写的,接下来换成object之后,代码真的太少了!
      • 不妨再看一下官方强调的:
        在这里插入图片描述
    • 精简代码如下:
      /**
       * 优化2
       */
      const mapDispatchToProps = {
          //通常是一个充满 action creators 的 object
          addNumber: incrementNum,   //addNumber:是通过props传递给UI组件的方法, incrementNum:是封装好的action函数
          reduceNumber: decrementNum
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      对比一下:
      在这里插入图片描述

    2.5 附代码

    • 关于redux文件下的代码就不贴了,因为没改动,需要的直接上篇文章就行,其他如下:
      • CountNumContainer.jsx
        import CountNumRedux from "../components/CountNumRedux";
        import { connect } from "react-redux";
        import {incrementNum,decrementNum} from "../redux/countAction";
        
        const mapStateToProps = (state) => ({
              count:state
          });
        
        const mapDispatchToProps = {
            //通常是一个充满 action creators 的 object
            addNumber: incrementNum,   //addNumber:是通过props传递给UI组件的方法, incrementNum:是封装好的action函数
            reduceNumber: decrementNum
        }
        
        const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
        
        export default CountNumContainer;
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
      • CountNumRedux.jsx
        import {  createRef } from "react";
        
        function CountNumRedux(props){
            console.log(props);
            
            const numberRef = createRef();
        
            function add(){
                let number = numberRef.current.value;
                props.addNumber(parseInt(number));
            }
        
            function subtract(){
                let number = parseInt(numberRef.current.value);
                props.reduceNumber(number);
            }
        
            return(
                <div>
                    {/* 当前数字是:{count}        
                    当前数字是:{store.getState()}   */}
        
                    当前数值是:{props.count}
                    <br />
                    浮动数字:<input type="number" ref={numberRef}/>
        
                    <br /><br />
                    <button onClick={add}>点我 加数</button> <br /><br />
                    <button onClick={subtract}>点我 减数</button>
                </div>
            )
        }
        export default CountNumRedux;
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
      • App.js
        import CountNumContainer from './container/CountNumContainer.jsx'
        
        function App() {
          return (
            <div>
              {/*  */}
              <CountNumContainer/>
            </div>
          );
        }
        
        export default App;
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
      • index.js
        import React from 'react';
        import ReactDOM from 'react-dom/client';
        import App from './App';
        
        import store from './redux/store';
        import { Provider } from 'react-redux';
        
        
        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(
            <Provider store={store}>
                <App />
            </Provider>
        );
        
        export default root;
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16

    3. 多reducer实现数据共享

    3.1 介绍 combineReducers()函数

    • 随着应用变得越来越复杂,可以考虑将 reducer 函数 拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分。

      combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore 方法。

      合并后的 reducer 可以调用各个子 reducer,并把它们返回的结果合并成一个 state 对象。 由 combineReducers() 返回的 state 对象,会将传入的每个 reducer 返回的 state 按其传递给 combineReducers() 时对应的 key 进行命名
      示例:

      rootReducer = combineReducers({potato: potatoReducer, tomato: tomatoReducer})
      // 这将返回如下的 state 对象
      {
        potato: {
          // ... potatoes, 和一些其他由 potatoReducer 管理的 state 对象 ...
        },
        tomato: {
          // ... tomatoes, 和一些其他由 tomatoReducer 管理的 state 对象,比如说 sauce 属性 ...
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      在这里插入图片描述

    • 关于 combineReducers()函数 的介绍来源于官网,关于combineReducers()更多讲解,可去官网,如下:
      https://cn.redux.js.org/api/combinereducers.

    3.2 多reducer整合的例子

    3.2.1 想实现的效果

    • 先设计三个组件的渲染,如下:
      在这里插入图片描述
    • 这三个组件里的状态都是交给react- redux管理的,我们先实现这个无数据共享的,然后再实现怎么让组件之间可以数据共享。

    3.2.2 项目目录设计结构

    • 如下:
      在这里插入图片描述

    3.2.3 将3个reducer整合(或者说拆分reducer)

    • 关于reducer的拆分,可以去官网,上面介绍combineReducers()函数时也说了,这里就不多说了,也可以去官网看拆分reducer逻辑,地址如下:
      拆分 Reducer 逻辑.
    • 上面的cat、dog、pet分别对应1个reducer,但是创建store的时候只需要一个reducer,所以最终需要将这三个reducer函数合并成一个最终的reducer函数给创建store时使用。
    • 本项目中怎么使用 combineReducers() 的,你现在可以不用知道其他3个reducer长什么样,只要他们3个都暴露出了就行,所以我这里直接介绍合并,如下:
      在这里插入图片描述

    3.2.4 每个组件的三个核心文件

    3.2.4.1 简单介绍——以cat为例
    • 这里为了看着方便,没有抽出常量,把UI组件和容器组件整合在了一个文件里,所以上面看到的3个模块组件各对应3个核心文件:action、reducer、容器组件。
    • 下面以cat组件为例进行说明:
      • catAction + catReducer:
        猫这里只想更改“今日最受欢迎的猫品种“,所以这个相对来说是简单的,一个action函数就可以了,那么如果action设计好了,reducer也就可以完善了,如下:
        在这里插入图片描述
      • CatContainer 组件 ,如下:
        在这里插入图片描述
    3.2.4.2 关于dog 和 petPark 的
    • dog的,简单直接看吧,如下:
      • dogAction + dogReducer:
        在这里插入图片描述
      • DogContainer 组件 ,如下:
        在这里插入图片描述
    • petPark的如下:
      这个比较简单点,因为这个里没有设计状态的改变,所以没有对应的action,都是初试值,如下:
      在这里插入图片描述

    3.3 实现数据共享

    3.3.1 实现数据共享

    • 现在在上面效果的基础上,实现数据共享,就很简单了,加两行代码的事,跟取自己的一样,如下:
      • petPark访问其他两个组件的数据:
        在这里插入图片描述
      • cat访问petPark的数据,也是一样的,想怎么访问怎么访问,因为本来就不在组件内部管理,而是react-redux在管理,谁用谁取就是了:
        在这里插入图片描述

    3.4 附核心代码

    3.4.1 两个action

    • catAction 如下:

      
      function changeCatKindAction(newKind){
          return {
              type: 'CHANGE_CAT_KIND',
              kind: newKind
          }
      }
      
      export {changeCatKindAction}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • dogAction 如下:

      
      function addDogAction(dogObj){
          return {
              type:'ADD_DOG',
              dog:dogObj
          }
      }
      
      export {addDogAction}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    3.4.2 三个reducer + 一个整合reducer

    • 前三个如下:

      const catKindInit = '布偶';
      
      function catReducer(state=catKindInit, action){
          switch (action.type) {
              case 'CHANGE_CAT_KIND':
                  return action.kind;
              default:
                  return state;
          }
      }
      
      export default catReducer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      
      const dogInit = [];
      // const dogInit = [{dogName:'狗狗',dogAge:1}];
      
      function dogReducer(state = dogInit, action){
          const {type,dog} = action;
          switch (type) {
              case 'ADD_DOG':
                  return [...state,dog];
              default:
                  return state;
          }
      }
      
      export default dogReducer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      
      const adminInit = {parkAdmin:'素素',parkAdminPhone:'176XXXXX'};
      
      function PetParkReducer(state=adminInit, action){
          return state;  //没有action,初始state不需要修改,直接返回
      }
      
      export default PetParkReducer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 最终的如下:

      
      import catReducer from "./catsReducer";
      import dogReducer from "./dogReducer";
      import petsParkReducer from "./petsParkReducer";
      
      import { combineReducers } from "redux";
      
      /**
       * 1. 合并后的 reducer 可以调用各个子 reducer,并把它们返回的结果合并成一个 state 对象。 
       * 2. 由 combineReducers() 返回的 state 对象,
       *    会将传入的每个 reducer 返回的 state 按其传递给 combineReducers() 时对应的 key 进行命名。
       */
      const rootReducer = combineReducers({
          petParkState: petsParkReducer,
          dogState: dogReducer,
          catState: catReducer,
      });
      
      export default rootReducer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

    3.4.3 三个组件

    • CatContainer.jsx 如下:

      import { connect } from "react-redux";
      import { useRef } from "react";
      import {changeCatKindAction} from '../redux/actions/CatAction'
      
      //1. UI组件
      function CatUI(props){
          const catKindNode = useRef();
      
          function chagePopularKind(){
              const newKind = catKindNode.current.value;
              props.changKind(newKind);
          }
      
          return(
              <div>
                  <h1>我是cat组件</h1>
                  今日最受欢迎的小猫品种是:{props.popularCatKind} <br/><br/>
      
                  <input type="text" ref={catKindNode} placeholder="请输入今日最受欢迎的"/> &nbsp;
                  <button onClick={chagePopularKind}>修改最受欢迎的小猫品种</button>
      
                  <br />
                  今日管理员是:{props.guanliyuan}  <br/>
                  管理员:{props.guanliyuan2.parkAdmin} 
              </div>
          )
      }
      
      //2. 容器组件
      
      function mapStateToProps(state) {
          return {
              popularCatKind: state.catState,
      
              guanliyuan: state.petParkState.parkAdmin, //可以直接访问其中某个属性
              guanliyuan2: state.petParkState, //也可以直接访问整个对象
          }
      }
      
      const mapDispatchToProps = {
          changKind: changeCatKindAction
      }
      
      const CatContainer = connect(mapStateToProps,mapDispatchToProps)(CatUI);
      
      export default CatContainer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
    • DogContainer.jsx 如下:

      import { useRef } from "react";
      import { connect } from "react-redux"
      import { addDogAction } from "../redux/actions/DogAction";
      
      //1. 定义UI组件
      function DogUI(props){
          // console.log(props);
          const dogList = props.dogListState;//获取狗狗列表信息
      
          const dogNameRef = useRef();
          const dogAgeRef = useRef();
      
          function addParkDog(){
              const dogName = dogNameRef.current.value;
              const dogAge = dogAgeRef.current.value;
              const dogObj = {dogName:dogName,dogAge:dogAge}
              props.addOneDog(dogObj);
          }
      
          return(
              <div>
                  <h1>我是dog组件</h1> <br />
                  1. 狗狗园区地址:{props.dogParkAdress}    <br /><br />
                  2. 
                  狗狗姓名:<input type="text" ref={dogNameRef} />    <br /> &nbsp;&nbsp;&nbsp;
                  狗狗年龄:<input type="number" ref={dogAgeRef}/>  &nbsp;
                  <button onClick={addParkDog}>添加狗狗</button> <br /><br />
                  3. 狗狗列表信息:
                  <ul>
                      {
                          dogList.map((dog,index)=>(
                              <li key={index}>{dog.dogName}---{dog.dogAge}</li>)
                          )
                      }
                  </ul>
              </div>
              
          )
      }
      
      //2.容器组件 并导出容器组件
      
      const mapStateToProps = (state)=>{
          /**
           * 1. 返回的是一个对象(dog组件 管理自己组件的state)
           * 2. 语法问题:当返回的是一个对象时,用一对()括起来,否则语法报错
           */
          return(
              {
                  dogListState:state.dogState,
                  dogParkAdress:'北京海淀区'
              }
          )
      }
      
      const mapDispatchToProps = {
          addOneDog: addDogAction
      }
      
      const DogContainer = connect(mapStateToProps,mapDispatchToProps)(DogUI);
      
      export default DogContainer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
    • PetParkContainer.jsx 如下:

      import { connect } from "react-redux";
      import { useState } from "react";
      
      //1. UI组件
      function PetParkUI(props){
          console.log(props);
          const [closeFlag,setCloseFlag] = useState(false);
      
          console.log(closeFlag);
          return(
              <div>
                  <h1>我是PetPark组件</h1> 
                  1. 管理员:{props.parkAdminInfo.parkAdmin}  <br /> &nbsp;&nbsp;
                     管理员电话:{props.parkAdminInfo.parkAdminPhone}  <br />
                  2. 现有的宠物有:{JSON.stringify(props.petKinds)} <br />
                  3. 雨天是否闭园:{closeFlag ? '是' : '否'}  <br /><br />
      
                  今日猫猫种类王是:{props.catKindKing}  <br /><br />
                  今日dog园区有多少条狗狗:{props.dogsNum}
              </div>
          )
      }
      
      //2.容器组件
      const mapStateToProps = (state)=>({
          parkAdminInfo: state.petParkState,//这个交给react-redux管理的可以共享
          petKinds: ['猫猫','狗狗'] ,//这个如果是自身组件用的,可以用useState放自身组件上
      
          //下面是数据共享的
          catKindKing: state.catState,  //直接取cat组件里的状态
          dogsNum: state.dogState.length
      
      })
      
      //connect 的两个参数都是可选的,可传可不传
      const PetParkContainer = connect(mapStateToProps)(PetParkUI);
      
      export default PetParkContainer;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38

    4. 附项目

  • 相关阅读:
    电容笔品牌哪个牌子好?电容笔质量最好的品牌推荐
    SpringMVC的响应处理
    URL.createObjectURL()和URL.revokeObjectURL()
    Nacos介绍与使用
    Arduino程序设计(二) 按键控制LED灯
    华为HCIA(五)
    【Java 进阶篇】深入理解 SQL 聚合函数
    【0114】libpq连接句柄PGconn介绍
    Redis (持续更新…)
    IK分词器
  • 原文地址:https://blog.csdn.net/suixinfeixiangfei/article/details/133129625