Vue3——vue-router4 & vuex4

2022-01-09  本文已影响0人  叽里咕呱

一、vue-router4

vue-router

1、安装vue-router4

npm install vue-router@4

2、创建router对象

createRouter方法:用于创建路由器对象。
createWebHashHistory方法:用于生成hash模式的路由,路由地址中包含一个#。
createWebHistory方法:用于生成history模式的路由。

// vue-router4创建路由器对象要使用createRouter方法
import {createRouter,createWebHashHistory} from 'vue-router'

// 创建一个路由器对象
let router = createRouter({
    // 设置路由模式(注意:这里和vue-router3不一样)
    history:createWebHashHistory(),
    // 配置具体的路由信息
    routes:[
        //每一个具体的路由信息,需要配置一个单独的对象
        {
            // 配置路由地址
            path:'/',
            // 设置路由名称
            name:'Home',
            // 设置路由页面
            component:()=>import('../views/Home.vue')
        },
        {
            path:'/home',
            // 重定向
            redirect:'/'
        },
        {
            path:'/list',
            name:'List',
            component:()=>import('../views/List.vue')
        },
        {
            // 路由传参
            path:'/goods/:id',
            // 开启props接收路由参数
            props:true,
            name:'Goods',
            component:()=>import('../views/Goods.vue')
        },
        {
            path:'/store',
            name:'Store',
            component:()=>import('../views/Store.vue')
        },
        {
            // 注意:不可以写通配符*
            // path:'*',
            path:'/:pathMatch(.*)*',
            name:'Error404',
            component:()=>import('../views/Error404.vue')
        }
    ]
})
export default router

3、注册router对象

在main.js中注册

// 导入当前项目中创建的路由器对象
import router from './router'
// 使用createApp方法创建一个Vue实例,该方法的参数是App组件,表示渲染App组件
// use方法,用于给当前vue实例添加功能,给实例安装插件
// mount方法,用于将渲染后的内容,挂载到指定的容器中
createApp(App).use(router).mount('#app')

4、使用router

useRouter方法:返回当前项目中的路由器对象。
useRoute方法:返回当前路由信息对象。

<div class="goods">
  <h2>商品信息</h2>
  <ul>
    <li>商品编号:{{ goods.id }}</li>
    <li>商品名称:{{ goods.name }}</li>
    <li>商品价格:{{ goods.price }}</li>
    <li>商品颜色:{{ goods.color }}</li>
    <li>
      <button @click="goBack">返回</button>
    </li>
  </ul>
</div>
import { computed, reactive } from "vue";
// 从路由中导入组合式api
import { useRouter, useRoute } from "vue-router";
export default {
  name: "Goods",
  props: ["id"],
  setup(props) {
    console.log(props);
    // useRouter()方法执行后,返回当前项目中的路由器对象
    let $router = useRouter();
    // useRoute()方法执行后,返回当前路由信息
    let $route = useRoute();
    // 商品数组
    let goodsList = reactive([
      {
        id: 1,
        name: "手机",
        price: 5999,
        color: "白色",
      },
      {
        id: 2,
        name: "电脑",
        price: 4999,
        color: "红色",
      },
      {
        id: 3,
        name: "电视",
        price: 3999,
        color: "黑色",
      },
    ]);
    // 指定的商品对象
    let goods = computed(() => {
      // 由于路由开启了props接收参数,所以可以这么写
      // return goodsList.find((r) => r.id == props.id);
      // 如果没有开启props接收参数
      return goodsList.find((r) => r.id == $route.params.id);
    });

    let goBack = () => {
      // 返回列表页的三种方式
      // $router.push('/list')
      // $router.back()
      $router.go(-1);
    };

    return {
      goods,
      goBack,
    };
  },
  /* data() {
      return {
          //商品数组
          goodsList:[
              {
                  id:1,
                  name:'手机',
                  price:5999,
                  color:'白色'
              },
              {
                  id:2,
                  name:'电脑',
                  price:4999,
                  color:'红色'
              },
              {
                  id:3,
                  name:'电视',
                  price:3999,
                  color:'黑色'
              }
          ]
      }
  },
  computed:{
      goods(){
          return this.goodsList.find(r=>r.id==this.id)
      }
  } */
};

二、vuex4

vuex4

1、安装vuex4

npm install vuex@next --save

2、创建store对象

// 从vuex中导入createStore方法,该方法,用于创建全局状态管理对象
import { createStore } from 'vuex'
// 导入手机模块
import phone from './modules/phone.js'

// 通过createStore()方法,创建一个全局状态管理对象
let store = createStore({
    //定义状态
    state:{
        carName:'奔驰',
        carPrice:20
    },
    //定义状态的计算属性
    getters:{
        carInfo(state){
            return state.carName+'-'+state.carPrice
        }
    },
    //定义同步方法
    mutations:{
        updateCarName(state,val){
            state.carName = val
        },
        updateCarPrice(state,val){
            state.carPrice = val
        }
    },
    //定义异步方法
    actions:{
        updateCarName(store,val){
            setTimeout(() => {
                store.commit('updateCarName',val)
            }, 1000);
        },
        updateCarPrice(store,val){
            setTimeout(() => {
                store.commit('updateCarPrice',val)
            }, 1000);
        }
    },
    // 模块
    modules:{
        phone
    }
})

export default store

phone模块

export default {
    //设置私有命名空间
    namespaced:true,
    state:{
        phoneName:'小米',
        phonePrice:100
    },
    getters:{
        phoneInfo(state){
            return state.phoneName+'-'+state.phonePrice
        }
    },
    mutations:{
        updatePhoneName(state,val){
            state.phoneName = val
        },
        updatePhonePrice(state,val){
            state.phonePrice = val
        }
    },
    actions:{
        updatePhoneName(store,val){
            setTimeout(() => {
                store.commit('updatePhoneName',val)
            }, 1000);
        },
        updatePhonePrice(store,val){
            setTimeout(() => {
                store.commit('updatePhonePrice',val)
            }, 1000);
        }
    }
}

3、注册store对象

在main.js中注册

// 导入当前项目中创建的全局状态管理对象
import store from './store'
// 使用createApp方法创建一个Vue实例,该方法的参数是App组件,表示渲染App组件
// use方法,用于给当前vue实例添加功能
// mount方法,用于将渲染后的内容,挂载到指定的容器中
createApp(App).use(store).use(router).mount('#app')

4、使用store

useStore方法:返回当前项目中的全局状态管理对象。

<div class="store">
  <h2>全局状态管理</h2>
  <ul>
    <li>汽车名称:{{ carName }}</li>
    <li>汽车价格:{{ carPrice }}</li>
    <li>汽车信息:{{ carInfo }}</li>
    <li><button @click="updateCarName">修改车名</button></li>
    <li><button @click="updateCarPrice">修改车价</button></li>
  </ul>
  <hr />
  <ul>
    <li>手机名称:{{ phoneName }}</li>
    <li>手机价格:{{ phonePrice }}</li>
    <li>手机信息:{{ phoneInfo }}</li>
    <li><button @click="updatePhoneName">修改手机名称</button></li>
    <li><button @click="updatePhonePrice">修改手机价格</button></li>
  </ul>
</div>
import { computed } from "@vue/reactivity";
import { useStore } from "vuex";
import {myMapState} from '../utils'
export default {
  name: "Store",
  setup() {
    //返回当前项目中的全局状态管理对象
    //注意:在组合API中,无法使用映射函数
    let $store = useStore();

    // let carName = computed(() => {
    //   return $store.state.carName;
    // });
    // let carPrice = computed(() => {
    //   return $store.state.carPrice;
    // });
    let carInfo = computed(() => {
      return $store.getters.carInfo;
    });
    let updateCarName = () => {
      $store.commit("updateCarName", "宝马");
    };
    let updateCarPrice = () => {
      $store.dispatch("updateCarPrice", 40);
    };

    // let phoneName = computed(() => {
    //   return $store.state.phone.phoneName;
    // });
    // let phonePrice = computed(() => {
    //   return $store.state.phone.phonePrice;
    // });

    // 获取phone模块中定义的计算属性
    let phoneInfo = computed(() => {
      return $store.getters['phone/phoneInfo'];
    });
    // 调用phone模块中定义的mutations同步方法
    let updatePhoneName = () => {
      $store.commit("phone/updatePhoneName", "华为");
    };
    // 调用phone模块中定义的actions异步方法
    let updatePhonePrice = () => {
      $store.dispatch("phone/updatePhonePrice", 200);
    };

    return {
      // carName,
      // carPrice,
      ...myMapState(['carName','carPrice'],$store,computed),
      carInfo,
      updateCarName,
      updateCarPrice,
      // phoneName,
      // phonePrice,
      ...myMapState(['phoneName','phonePrice'],$store,computed,'phone'),
      phoneInfo,
      updatePhoneName,
      updatePhonePrice
    };
  },
  /* computed:{
    ...mapState(['carName','carPrice'])
  } */
};

在组合API中,无法使用映射函数。所以自定义映射函数方法,对state数据进行处理。

export let myMapState = (stateArr,$store,computed,moduleName=undefined) => {
  //状态数据对象
  let stateObj = {};
  stateArr.forEach((key) => {
    if(moduleName){
      stateObj[key] = computed(() => {
        return $store.state[moduleName][key];
      });
    }else{
      stateObj[key] = computed(() => {
        return $store.state[key];
      });
    }
  });
  return stateObj;
};
上一篇下一篇

猜你喜欢

热点阅读