美文网首页
Vue3——vue-router4 & vuex4

Vue3——vue-router4 & vuex4

作者: 叽里咕呱 | 来源:发表于2022-01-09 14:30 被阅读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;
    };
    

    相关文章

      网友评论

          本文标题:Vue3——vue-router4 & vuex4

          本文链接:https://www.haomeiwen.com/subject/eaqucrtx.html