Taro组件通信方式总结(最后一个是亮点)

taro组件通信方式大总结

别问为啥学 taro 问就是入坑了

在taro中常见的页面通信方式有六种 都用的不多不如使用Redux 但是技多不压身

以下六种方式除了方式一和方式二都其余四种都支持在组件间进行数据传递
组件间数据传递我们还可以使用props

注意:在下面的代码中需要使用到getCurrentInstance我们最好获取一次不要多此获取,
最好使用useref进行包裹一下 --因为在useRef中保存的对象在整个组件中都能保持同一个对象
const $instance=useRef(Taro.getCurrentInstance())
如果需要获取就从他身上去拿。
演示
以下演示均基于Hooks演示
class我会标注不同点
方式一:url查询字符串
正向传递数据:

传递参数:?name=wangfeng&age=19

接收参数:

类组件:onLoad

函数组件:useLoad

还可以用Taro.getCurrentInstance().router.parmas中获取参数

传递数据:

注意这里跳转最好用相对路径要不然小程序报错⛈

  function handeldetaile01Click() {
    Taro.navigateTo({
      url: "/pages/detaile01/index?name=wangfeng&age=19",
    });
  }

接收数据1:

 useLoad((opsetion) => {
    console.log('Page loaded.',opsetion)
  })

接收数据2:

  useDidShow(() => {
    // 这个是可以拿到当前的app实例 page实例 和router
    const instance = Taro.getCurrentInstance();
    console.log(instance.router.params)
  });
方式二:EventChannel(仅支持微信小程序)

注意:需要加上环境判断

正向传递数据:
  function handeldetaile01Click() {
    Taro.navigateTo({
      url: "/pages/detaile01/index",
        
      success: function (res) {
        if (process.env.TARO_ENV === "weapp") {
          // 通过eventChannel向被打开页面传送数据---只兼容微信小程序端
          res.eventChannel.emit("acceptDataFromHomePage", {
            data: "我是Home页面传递的数据",
          });
        }
      },
    });
  }

接收数据:

  useLoad(() => {
    // 拿到eventChannel传递的数据
    if (process.env.TARO_ENV === "weapp") {
      const instance = Taro.getCurrentInstance();
      const eventChannel = instance.page.getOpenerEventChannel();
      eventChannel.on("acceptDataFromHomePage",function(data){
        console.log("只兼容小程序的数据来了",data)
      })
    }
  });
逆向传递数据:

接收数据:

  function handeldetaile02Click() {
    Taro.navigateTo({
      url: "/pages/detaile02/index",
      events: {
        // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
        acceptDataFromOpenedPage: function (data) {
          console.log(data);
        },
      },
    });
  }

传递数据:

 function handelGoback() {
    Taro.navigateBack({
      data: 1,
    });
    if (process.env.TARO_ENV === "weapp") {
      const instance = Taro.getCurrentInstance();
      const eventChannel = instance.page.getOpenerEventChannel();
      eventChannel.emit("acceptDataFromOpenedPage", {
        data: "我是从detaile02页面传递到首页的数据",
      });
    }
  }
方式三:Taro.eventCenter全局事件总线

这种方式一般应用于逆向传递而且多端兼容

为什么应用于逆向传递?

因为这种事件需要先监听后触发;所以我们必须在触发前监听 所以不适用于主页面传递副页面

逆向传递数据的方式:

 function handelGoback() {
    Taro.navigateBack({
      data: 1,
    });
    Taro.eventCenter.trigger("acceptDataFromdetaile03", {
      data: "将detaile03的数据传递到home页面",
    });
  }

逆向接收数据的方式:

  useLoad(() => {
    console.log("Page loaded.");
    Taro.eventCenter.on("acceptDataFromdetaile03", acceptDataFromdetaile03);
  });
  useUnload(() => {
    Taro.eventCenter.off("acceptDataFromdetaile03", acceptDataFromdetaile03);
  });
  function acceptDataFromdetaile03(data) {
    console.log(data);
  }
方式四:taroGloabalData全局数据

不多赘述

方式五:Taro.setStorageSync(key,data)本地数据存储

不多赘述

方式六:Redux状态管理库💯

如果使用react作为技术栈redux是我们必选的数据共享方式 很好用

createStore已经过时了

在redux中我们一般会把文件分为四个文件夹:constants、action、reducer、index。上面的这种方式过于繁琐,所以reduxToolkit(RTK)的诞生也就是为了解决这种代码的编排方式

概念:

redux分为父对象和子切片 我们在index中先创建一个store对象 然后在每个模块中创建不同的slice切片

第一步安装依赖 – npm i @reduxjs/toolkit react-redux

第二步在模块中创建多个切片 调用

import { createSlice } from "@reduxjs/toolkit";
// 1.创建一个slice reducer
const homeSlice = createSlice({
  name: "home", //唯一性
  initialState: {
    //初始化数据
    counter: 666,
  },
  reducers: {
    increment(state, action) {
        //结构出你需要的数据
      const { payload } = action;
      state.counter += payload;
      console.log(state, action);
    },
    decrement(state, action) {
      const { payload } = action;
      state.counter -= payload;
    },
  },
});
// 2.导出action
export const { increment, decrement } = homeSlice.actions;
// 3.导出切片这些切片需要拿到store中进行合并
export default homeSlice.reducer;

第三步在index中创建store合并多个子切片

// 创建一个store对象 合并子reducer
import { configureStore } from "@reduxjs/toolkit";
// 引入切片
import homeStore from "./modules/home";
const store = configureStore({
  // 合并切片
  reducer: {
    home: homeStore,
  },
  devTools: true,
});
export default store;

第四步我们在使用redux的时候不像pinia那样你想用就直接引入 而是你需要在根中进行注入 在app.js中进行注入

import { useLaunch } from "@tarojs/taro";
//1、引入store
import store from "./store";
//2、引入注入者
import { Provider } from "react-redux";
import "./app.scss";
function App({ children }) {
  useLaunch(() => {
    console.log("App launched.");
  });
  //3、拿到提供者(Provider) 让他来把所有的数据注入到每个组件中
  // children 是将要会渲染的页面
  return <Provider store={store}>{{ children }}</Provider>;
}
export default App;

第五步使用:

你可以使用函数式组件api来使用你共享的数据

useSelector – 允许你使用Select函数从state中获取数据

useDispatch – 允许你使用他来派发action

import { View, Text, Button } from "@tarojs/components";
import { useLoad } from "@tarojs/taro";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "../../store/modules/home";
import "./index.scss";
export default function Category() {
  const counter = useSelector((state) => {
    return state.home.counter;
  });
  const dispatch = useDispatch();
  useLoad(() => {
    console.log(counter);
    console.log("Page loaded.");
  });
  function incrementclikc() {
    // 当发生点击的时候派生改变的action
    dispatch(increment(1));
  }
  function decrementclick() {
    dispatch(decrement(-1));
  }
  return (
    <View className="category">
      <Text>Hello world!Category{counter}</Text>
      <Button onClick={incrementclikc}>点我加一</Button>
      <Button onClick={decrementclick}>点我减一</Button>
    </View>
  );
}

附加:

关于异步action的组织

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { getHomeMutidata } from "../../service/home";
// 4.定义一个异步的action
export const FetchgetHomeMutidataAction = createAsyncThunk(
  "Homedata",
  async (action) => {
    console.log("传递过来的数据", action);
    const res = await getHomeMutidata();
    return res;
  }
);
// 1.创建一个slice reducer
const homeSlice = createSlice({
  name: "home", //唯一性
  initialState: {
    //初始化数据
    counter: 666,
    data: {},
  },
  reducers: {
    increment(state, action) {
      const { payload } = action;
      state.counter += payload;
      console.log(state, action);
    },
    decrement(state, action) {
      const { payload } = action;
      state.counter -= payload;
    },
  },
  extraReducers: (builder) => {
    builder.addCase(FetchgetHomeMutidataAction.fulfilled, (state, action) => {
      // state是初始化的对象
      // action是网络请求的结果
      const { payload } = action;
      state.data = payload.data;
      console.log(payload.data);
    });
  },
});
// 2.导出action
export const { increment, decrement } = homeSlice.actions;
// 3.导出切片这些切片需要拿到store中进行合并
export default homeSlice.reducer;

以上代码中的第四步是针对于异步请求的组织

在页面中我们同样使用dispatch来派生请求来获取数据

例如:dispatch(FetchgetHomeMutidataAction(100))

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值