IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 08.Vue3 中的 Vue-Router 和 VueX -> 正文阅读

[JavaScript知识库]08.Vue3 中的 Vue-Router 和 VueX

Vue3 中的 Vue-Router 和 VueX

先使用 vue create 指令来创建 vue 工程项目,并选择自定义,将 Router 和 VueX 勾上。

勾上以后看主入口 main.js,可以看到项目自动帮我们注册了 vue-router 和 VueX。

// main.js
createApp(App).use(store).use(router).mount('#app')

1. Vue-Router 路由的理解和使用

路由是指根据 url 的不同,展示不同的内容。

查看 src 文件夹里的 router,这就是来处理路由的地方。

其中,index.js 有关键的代码

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

定义了两个路由项。当访问根目录,就加载 HomeView 这个组件。如果访问 /about,则懒加载 AboutView 这个组件。

import(...)是异步加载路由的方法。因为如果一口气全部组件加载出来,主页的加载的性能将会很低,为了提高组件的加载性能,使用懒加载按需加载,等进入 /about 或其他的页面再加载响应部分的代码。但是异步加载代码也有相应的问题,就是去其他的页面可能会有卡顿(其实就是加载的时间分摊了)。

因此,vue-router 就是根据 url 不同来显示不同组件的特性。

现在查看根组件 App.vue,上面有关键的代码:

<template>
  <nav>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </nav>
  <router-view/>
</template>

router-link 是跳转路由的标签,点击后就会跳转到相应的路由。

router-view 负责展示当前路由对应的组件内容。例如上面的代码,当跳转到根路径上时,router 会进行搜索,当搜索到匹配项时,便显示相应的组件 HomeView。

2. VueX 语法详解

在文首就看到了,注册了 VueX,接下来看 src 的 store 目录,这里边的 index.js 可以看到以下内容,稍后会讲。

export default createStore({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

2.1 VueX 是什么

VueX 是数据管理框架。之前的数据传递都是父子之间的传递,虽然也有 provider 之类的方法进行跨级传递,但是可维护性也不会特别高。

VueX 提供了一个全局都可以使用的数据管理仓库,不用考虑父子传值之类的问题,并且可以跨页面传递数据。提高了可维护性。

使用方法

  1. 提供数据:在 store 里的 state 里定义一些数据

    // VueX 创建了一个全局唯一的仓库,用来存放全局的数据
    export default createStore({
      state: {
        name: "John",
      },
      getters: {
      },
      mutations: {
      },
      actions: {
      },
      modules: {
      }
    })
    
  2. 在需要用数据的地方通过 this.$store 获取即可

    <template>
      <div>{{ myName }}</div>
    </template>
    
    <script>
    export default {
      name: "LoginView",
      computed: {
        myName() {
          return this.$store.state.name;
        },
      },
    };
    </script>
    

2.2 VueX 数据修改流程

讲一下 VueX 的修改规范,因为全局的数据是不能随意更改的,因此 VueX 有一套机制流程,并不能直接用赋值的方法进行修改。

修改流程

  1. 在组件里提交一个 action 到 store,dispatch 的第一个参数是 action 名称,后面可自定义参数。

    // LoginView.vue
    <template>
      <div>{{ myName }}</div>
      <button @click="handleClick">click</button>
    </template>
    
    <script>
    export default {
      name: "LoginView",
      computed: {
        myName() {
          return this.$store.state.name;
        },
      },
      methods: {
        handleClick() {
          // 1. 想改变数据,VueX 要求第一步,必须派发一个 action,action 名称为 actions 里的方法名
          this.$store.dispatch("change");
        },
      },
    };
    </script>
    
  2. store 感知到 action,执行 actions 下面对应的方法

  3. actions 对应的方法 commit 信息后传递给 mutations。commit 的信息为 mutations 里的方法名。

  4. mutations 里对应的方法执行修改数据的操作。

    import { createStore } from "vuex";
    
    // VueX 创建了一个全局唯一的仓库,用来存放全局的数据
    export default createStore({
      state: {
        name: "John",
      },
      getters: {
      },
      mutations: {
        // 4. 接收到 commit 信息后,触发对应的 mutation
        change(state) {
          // 5. 在 mutation 里修改数据
          state.name = "Modified Name";
        },
      },
      actions: {
        // 2. 接收到 action 后执行相应的方法
        change(store) {
          // 3. commit 后发送给 mutations
          store.commit("change");
        },
      },
      modules: {},
    });
    

从上面的流程来看,VueX 创建了一个全局唯一的仓库,用来存放全局的数据,同时里面设置了一系列的数据操作流程。

这流程下来有点麻烦啊,为啥不直接 commit 过去呢?同步代码看起来是如此,但是如果有异步操作的话,这些步骤就很有必要了。

注意

mutations 和 actions 里的方法第一个参数各不相同。

actions 里面第一个参数是 store,因为需要用 store.commit 方法来提交给 mutations。

mutations 里边的方法第一个参数是 state,因为 store 是用来修改 store 里 state 的方法。

可见,vue 官方在代码层面都是推荐分离的。

其他细则

  1. mutations 里面只允许写同步代码,不许写异步代码
  2. actions 里面允许写异步操作

优点在于,将两种功能分离,mutations 里做数据的改变,actions 里做主要的逻辑书写,维护的时候会更加方便。

getter 是啥

store 里的数据有时候并不能直接拿来用,还需要经过一些小处理。一般就会想,在组件内处理不就完事了?但是呢,万一有很多的组件都有着需求呢,挨个写就不合适。getter 就相当于 store 里的 computed 属性,对 state 进行了一定的处理。

使用方法:

  1. 设置 getter

    getter 接收两个参数,然后返回一个值。

    1. state,必选,是 store 里的数据
    2. getters,可选,是 store 里的所有 getters

    例如,我要计算得到大写后的 name:

    // store/index.js
      getters: {
        upperCasedName: (state) => {
          return state.name.toUpperCase();
        }
      },
    
  2. 组件获取 store 里的 getter

    <template>
      <div>{{ upperCasedName }}</div>
      <button @click="handleClick">click</button>
    </template>
    
    <script>
    export default {
      name: "LoginView",
      computed: {
        upperCasedName() {
          return this.$store.getters.upperCasedName;
        },
      },
      methods: {
        handleClick() {
          // 1. 想改变数据,VueX 要求第一步,必须派发一个 action
          this.$store.dispatch("change");
        },
      },
    };
    </script>
    

    通过 computed 获取到 getter 后,点击按钮改变了 store 里的 name,上边显示的仍然是大写的,因为获取的是全部字母大写后的 name。

2.3 Composition API 使用 VueX

composition API 使用 useStore 获取 store 即可。

<template>
  <div>{{ name }}</div>
</template>

<script>
import { useStore } from "vuex";
export default {
  name: "LoginView",
  setup() {
    const store = useStore();
    const name = store.state.name;
    return {
      name,
    };
  },
};
</script>

用 toRefs 解构的方法也行:

<template>
  <div>{{ name }}</div>
  <button @click="handleClick">Click</button>
</template>

<script>
import { toRefs } from "@vue/reactivity";
import { useStore } from "vuex";
export default {
  name: "LoginView",
  setup() {
    const store = useStore();
    const { name } = toRefs(store.state);
    const handleClick = () => {
      store.commit("changeName");
    };
    return {
      name,
      handleClick,
    };
  },
};
</script>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:32:01  更:2022-05-18 17:34:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:58:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码