Vue3——vue-router4 & vuex4

一、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;
};
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容