别问为啥学 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 {{ children }} ;
}
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 (
Hello world!Category{counter}
);
}
附加:
关于异步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))