vue3中引入router和vuex

上一节 - vue3中vite的配置

一、vue-router引入路由

  1. 下载vue-router
npm install vue-router --save
// or
yarn add vue-router --save

2.在src下面创建一个router文件夹,然后在router文件夹下面创建一个index.ts文件

// index.ts 文件
import {createRouter, createWebHashHistory} from 'vue-router'
const routes: any = [
  {path: '/', name: '首页', component: () => import('../components/HelloWorld.vue')},
  {path: '/about', name: '关于', component: () => import('../pages/about/index.vue')},
  {path: '/animation', name: '动画', component: () => import('../pages/animation/index.vue')},
]
// Vue-router新版本中,需要使用createRouter来创建路由
// 如果想使用histroy,调用createWebHistory方法
export default  createRouter({
  // 指定路由的模式,此处使用的是hash模式
  history: createWebHashHistory(),
  routes // short for `routes: routes`
})
  1. 到main.ts引入该文件
// main.ts
import Router from '@/router'
// 将 createApp(App).mount('#app') 改成下面这样
const app = createApp(App)
// 引入路由到项目中
app.use(Router)
app.mount('#app')

4.使用

在ts项目中使用,直接引入router/index.ts文件

// js部分
import router from '@/router';
const toAnimatePage = () => {
  console.log('router', router)
  router.push('/animation')
}

// html部分
动画演示
image.png

注意:在上一篇文章中我对路径别名做了vite配置,但在上面引入@/router还是报红,但是编译是通过的。
因此,这里是ts配置引起的,我们要做一下ts配置

    // 找到tsconfig.json, 在compilerOptions选项下增加如下代码
    "baseUrl": ".",
    // 用于设置解析非相对模块名称的基本目录,相对模块不会受到baseUrl的影响
    "paths": {
      // 用于设置模块名到基于baseUrl的路径映射
      "@/*": [
        "src/*"
      ]
     }
image.png

可以看到红色下划线消失了

二、引入vuex,状态管理器

1.下载vuex

npm install vuex --save
// or
yarn add vuex --save

2.在src创建store文件夹,在store文件夹下创建index.ts

// store/index.ts
import { createStore } from 'vuex'

interface State {
  userName: string,
  [k:string]: boolean | number | string | object | any[]
}
export default createStore({
  state(): State {
    return {
      userName: "Vuex",
      hello: ''
    };
  },
})

3.到main.ts引入store

import Store from '@/store'
app.use(Store)

4.使用

// 在组件里
import store from './store';
console.log('wellcome', store.state.userName) // wellcome Vuex

5.辅助函数的使用

  • 5.1 常规的使用跟vue2差不了太多,大家可以参考vuex4.x版本
  • 5.2 在ts中使用,需要做一下封装
    首先在store文件夹下面创建一个sateMappers.ts文件
// store/stateMappers.ts文件
import { useStore } from 'vuex'
import { computed } from 'vue'

function useStateMapper(mapper: any, mapFn: any) {
  const store = useStore()

  const storeStateFns = mapFn(mapper)

  const storeState: any = {}
  Object.keys(storeStateFns).forEach(fnKey => {
      // vuex源码中mapState和mapGetters的方法中使用的是this.$store,所以更改this绑定
      const fn = storeStateFns[fnKey].bind({ $store: store })
      storeState[fnKey] = computed(fn)

  })

  return storeState
}

export default useStateMapper

然后在store/index.ts中引入

import sateMappers from './stateMapper'
// 导出一个userMapstate 函数
export const useMapstate = (moduleName: string, options: any) => {
  let mapperFn = mapState;
  if (moduleName) {
    mapperFn = createNamespacedHelpers(moduleName).mapState
  }
  return sateMappers(options, mapperFn);
}

在任意组件中使用

import store, {useMapstate} from './store';
const mapstate = useMapstate('user', ['name']);
console.log('wellcome', mapstate); // wellcome chenxl

store/index.ts

import { createStore, mapState, createNamespacedHelpers } from 'vuex'
import sateMappers from './stateMapper'

interface State {
  userName: string,
  [k:string]: boolean | number | string | object | any[]
}
export default createStore({
  state(): State {
    return {
      userName: "Vuex",
      hello: 'hello word!'
    };
  },
  modules: {
    user: {
      namespaced: true,
      state: {
        name: 'chenxl'
      }
    }
  }
})

export const useMapstate = (moduleName: string | null = null, mapps: any) => {
  let mapperFn = mapState;
  if (moduleName) {
    mapperFn = createNamespacedHelpers(moduleName).mapState
  }
  return sateMappers(mapps, mapperFn);
}

mapGetters、mapActions、mapMutations等大家可以参考下文自行封装:

import { computed, defineComponent, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useStore, mapState, mapGetters, mapActions, mapMutations} from 'vuex'
export default defineComponent({
  ...
  setup() {
    const route = useRoute();
    onMounted(() => {
      console.log(route.fullPath);
    });
    const store = useStore();
    const isLoading = computed(
      mapGetters(['getLoading']).getLoading.bind({ $store: store })
    );
    // const netError = computed(
    //   mapGetters(['getNetError']).getNetError.bind({ $store: store })
    // );
    const netError = computed(
      mapState(['netError']).netError.bind({ $store: store })
    );
    console.log(netError);
    // const setLoading = mapActions(['setLoading']).setLoading.bind({
    //   $store: store
    // });
    const setLoading = mapMutations(['setLoading']).setLoading.bind({
      $store: store
    });
    const freshPage = () => {
      setLoading(true);
      //window.location.reload();
      setTimeout(() => {
        setLoading(false);
      }, 2000);
    };
    return {
      route,
      isLoading,
      netError,
      freshPage
    };
  }
  ...
})

原文地址

下一节 - vue3+ts+axios

你可能感兴趣的:(vue3中引入router和vuex)