vue3专栏项目 -- 三、使用vue-router 和 vuex(下)

一、添加columnDetail 页面

首页有专栏列表(ColumnList组件),专栏列表中有很多专栏,然后点击某个专栏就进入专栏详情页(ColumnDetail组件),专栏详情页中有很多文章,点击某个文章就进入文章详情页()这样子

数据我们是设计成什么样子呢,如下

testData是专栏数据,testPosts是文章数据,就是每个专栏里面都对应着它们相对应的文章们,它们是怎么联系起来的呢也就是说怎么知道这个文章是哪个专栏里的呢?通过文章中的columnId=专栏中的id,则说明这个文章是这个专栏的。

那url中参数怎么与专栏和文章联系起来呢,我们之前做路由跳转的时候跳转到columnDetail专栏详情页的时候不是做了动态路由嘛,通过加:id,到时候url中我们通过在url的column/后加2,那么它就会跳转到query中id为2的数据页面中。所以我们url中这个参数我们让它等于专栏的id,即url中这个参数是2时,则让它是id为2的专栏。

所以当url中该参数为2时,则找出专栏中id为2的数据,因为专栏详情页中需要展示出该专栏下的文章,所以还需要获取这个专栏下的文章们,而专栏和文章是以专栏id(和url那个id其实是相等了) = 文章columnId,即过滤出columnId等于2的即可找出这个专栏下的文章了

如下

数据获取到了,然后专栏详情页中不是有文章们嘛,就建个PostList组件,专门放该专栏详情页下的文章列表

二、vuex

1、什么是状态管理工具

我们现在有3个页面了,分别是首页、登录页、专栏详情页,这三个页面中都有一些共同的数据需要获取和处理,现在我们的做法是把这些共用的数据都保存在一个全局的js对象中

全局对象的弊端:

·数据不是响应式的

·数据修改无法追踪

·不符合组件开发的原则

状态管理工具的基本原则:

·一个类似object 的全局数据结构 - 称为store (里面的数据是不能随便更改的,只能通过action修改)

·只能调用一些特殊的方法来实现数据修改(所以store中的数据变化是可追溯可控制的)

2、vuex 简介 和 安装

单向数据流理念,state决定了view长什么样,view上可以通过actions方法修改state

但是,当多个组件共享状态时,单向数据流就容易被破坏。

vuex的核心是store,store就像一个仓库,store包含应用中大多数状态(state)

vuex的特点:

·状态存储是响应式的

·不能直接改变store中的状态,唯一途径就是显式地提交(commit) mutation

安装vuex:npm install vuex --save

3、vuex 整合当前应用

创建一个store.ts如下

然后我们需要把这个store和vue联合起来,去main.ts,如下即把store和整个应用整合到了一起

接下来看看在组件中怎么拿到数据,在home.vue中举个例子,如下

我们哪里要用就引入vuex的useStore,然后通过 useStore() 就可以拿到vuex中的store了

如下发现没有自动补全,我们可以引入store的GlobalDataProps

当做泛型传入进去后就可以出现自动补全了

由于vuex的状态存储是响应式的,从store实例中读取状态最简单的方法是在计算属性中返回某个状态,如下

第二个任务就是修改数据

我们希望登录以后,vuex数据发生变化,然后触发页面上的变化。登录后就把vuex中当前登录人的信息从未登录变成登录,从某某人变成当前人这样子

然后到App.vue中引入vuex,然后 useStore() 拿到vuex中的store,然后在computed中通过store.state.user拿到store中的user信息

到login.vue中,我们希望它登录后跳转到首页去,并且尝试修改,注意修改一定要用commit。

如下,commit就会去触发store中的mutations,commit('login') 即触发mutations中的login函数,如下这个login函数中就会去修改store中的user信息

如此,去登录,发现登录成功后就跳转到了首页了

4、使用vuex getters

前面我们知道了怎么给整个页面添加vuex store,同时知道了怎么在vue组件中获取store的数据,以及怎么触发mutation,从而引起应用的更新。

接下来我们了解getter,有时候我们需要从store的state中派生出一些状态,比如说我们对专栏们进行过滤,找出id大于2的有多少专栏,我们就需要这样:store.state.columns.filter(c=>c.id>2).length,通过这么一长串逻辑就拿到了有多少专栏id大于2

假如我们在多个页面当中都要使用的话,就需要反复重复这么长的代码,就比较麻烦

vuex就允许我们在store中定义一个叫getter的东西,可以认为是store的一个计算属性,就和计算属性一样,getter返回值会根据它的依赖被缓存起来,且当它依赖值发生改变才会重新计算。

如下,接下来我们使用getter,就直接通过store.getters.biggerColumnsLen就可以拿到id大于2的专栏数量了

我们来到专栏详情页,我们想通过getters,查询具体是哪个column

如下是还没用getters的

这里和之前的区别就是,我们需要传入一个称为currentId的值,因为这个值是在页面上才能拿到的,所以你在页面拿到后,你得传入到getters中,然后拿currentId做上面的这些操作

在getters中我们可以让它返回一个函数来实现给getters传参,它在你对store里的数组进行查询的时候非常有用,如下

三、添加新建文章页面

每个column专栏都有一个作者(有columnId,id等),它们两个是一对一的关系,这个作者信息和当前这个用户登录信息使用的是同一个数据结构,所以我们在新建文章的时候,可以从当前登录用户的信息中拿到这个columnId,然后创建定义的文章

就是你创建文章,你得知道这个文章是谁写的?(这里有点?)

views中新建一个CreatePost.vue即新建文章页面,新建文章中也是用的validate-input

然后到router.ts中加入新建文章的页面路径,并且在新建文章按钮中把a标签变成router-link标签,:to指向/create,这样点击新建文章时就会跳转到新建文章页面

应该让validateInput支持textarea,添加一个属性让它判断要显示哪个节点就好

如下,设置一个类型是input或者textarea,然后props中接入一个tag,这个tag就是要展示input还是textarea,然后input标签中就通过v-if来判断是input类型还是textarea类型框

然后新建文章这里,我们传入tag=textarea,这样子在新建文章页面

如果要创建文章,我们就需要拿到用户信息的columnId,所以我们给我们的数据结构做一些修改

如下:在mutations中定义createPost,接收newPost即新建的文章,把传过来的新建的文章追加到state的posts中

如下:新建文章点击提交按钮后,触发onFormSubmit事件,从当前用户中获取columnId做当前新建文章的columnId,然后新建newPost对象,这个对象中放置这个新建文章的信息,然后commit调用vuex的mutation,把当前新建文章追加到state中的posts中,并且往router中push如下路径

四、vue router 添加路由守卫

1、 前置守卫

接下来谈谈不同路由的权限问题,有些路由有某些特定权限才能使用,比如新建文章页面只有在用户登录以后才可以使用,如果用户未登录,直接访问新建页面的话,一般会重定向到另外一个路由,比如说此时重定向到login页面去登录;比如说登录和注册页面,在未登录的时候就可以访问,如果已经登录,此时去访问这两个页面一般会重定向到首页去。

由于我们整体应用是SPA,即所说的单页面,那我们的路由使用了vue-router,我们就去看看vue-router怎么完成这个任务,就是这个导航守卫

现在我们就来注册一个全局前置守卫,判断一下加入用户是否登录,如果没有登录,那么就让页面跳转到login页面,如上,注册守卫其实很简单,我们需要在router的实例上拿到beforeEach方法,

beforeEach方法就是当一个导航触发的时候,这个beforeEach要全局前置守卫,就按照创建顺序调用,守卫是一步一个解析执行,此时导航的所有守卫resolve完之前一直处于等待中

to就是即将到达的路由,from是正在离开的路由,next是一个function

 从首页到新建文章页,可以看到to即将到达的路由变成/create,from当前路由是首页

但是此时我们发现,已经点击新建文章按钮了,却没有跳转到新建文章页面,这是因为最后一个参数next在作祟

next是一个function,我们一定要调用该方法来resolve这个钩子,让这个路由继续前进到下一个钩子,此时我们就直接让它next()继续前进不要停在这里即可到新建文章页面

如果为false则不能跳转了

然后我们来完成,当没有登录的时候就跳转到登录页面去

如下,如果不是跳转到登录页,并且当前没有登录,即当前没有登录还想跳到非登录页就让它重定向回登录页得先登录再去其他页面

此时如果没有登录,那么到首页就会重定向到登录页,或者到新建文章页也会重定向回登录页

这个功能是实现了,但是这不是我们最终想要的结果,因为有些页面即使没有登录也是可以访问的,只有特定的页面才需要登录后才能访问,所以我们还需要再把这个功能进化一下

2、使用元信息完成权限管理

现在路由可以被这个守卫操控,在跳转之前进行对应的检查,但是现在我们的规则是眉毛胡子一起抓,用一个规则把所有页面都拒之门外。

第一种是home和columndetail这两个页面是无论有没有登录都是可以访问的;第二种是create页面是只有登录的用户才可以访问的;第三种是login这个页面,用户登录以后他访问就会直接跳转到首页;所以有三种对应的路由,又代表了三种不同的行为,也就是说我们需要在特定种类的路由上面添加独特的信息进行区分,看文档如下

要知道怎么在路由上添加元信息,即在路由上添加meta: { xx: xx }

路由元信息,也就是说我们在定义路由的时候可以配置一个叫meta的字段,这个就是这个元信息,这个meta字段下面我们可以使用Object形式写出来我们所需要的一些额外的信息

这时候我们就在create页面上面添加一个元信息,添加完了后我们需要到beforeEach中访问这个信息,如下

我们访问create可以看到打印出了requiredLogin:true,既然我们能拿到这个信息,后面的判断就可以做了

我们只需要用meta中的信息判断该路由是否登录就可以了

如下create页面是只有登录的用户才可以访问的

登录用户访问登录页面就会跳转到首页

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/615437.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uni-segmented-control插件使用

dcloud插件市场 前端/uniapp 1.HBuildX打开目标项目 2.进入dcloud插件市场下载目标插件 3.看到如下提示(已经可以在目标项目中使用插件啦) 4.项目正式使用

物联网平台之单体架构

介绍本文主要介绍平台的单体架构,包括各个组件之间的数据流描述以及所做的一些架构选择。在单体架构模式下,所有 ThingsKit 组件都在单个 Java 虚拟机 (JVM) 中启动,并共享相同的操作系统资源。由于 ThingsKit 是用 Java 编写的,因…

springcloud alibaba微服务框架涉及的技术

一、微服务架构中核心模块及其使用技术总览 二、各模块详细说明 1、注册中心 该模块主要功能为 自动提供服务的注册与发现,集中式管理服务,让 服务调用端发现服务,让服务提供端注册服务,倘若没有注册中心,那客户端就…

JUC下的BlockingQueue详解

BlockingQueue是Java并发包(java.util.concurrent)中提供的一个接口,它扩展了Queue接口,增加了阻塞功能。这意味着当队列满时尝试入队操作,或者队列空时尝试出队操作,线程会进入等待状态,直到队列状态允许操作继续。这…

记录使用极空间NAS通过Docker部署小皮面板(PhpStydy)运行 八图片当面付支付宝接口 PHP项目的遭遇

事件的起因还得从我用八图片的图片加密支付跳转功能,实现打赏金额发案例源码下载链接挣个烟钱的事。八图片的支付接口是PHP web项目的。正好我有个极空间的NAS,搭建到NAS上省去了买主机的费用。 导读 八图片是什么?极空间NAS 部署 PHP网站安装…

eNSP中小型园区网络拓扑搭建(上)

→b站直通车,感谢大佬← →eNSP中小型园区网络拓扑搭建(下)← 不带配置命令的拓扑图已上传~ 项目背景: 某公司准备新建一张网络供企业办公使用。写字楼共3层,一层会客大厅、二层行政部及市场部、三层研发部。一层设…

探讨 vs2019 c++ 里函数指针与函数类型在使用上的语法区别

(1)咱们可以用 decltype () 来判断函数的类型。但以这个类型定义有用的可指向已存在函数的变量,却行不通。测试如下: 如果把上面的注释去掉会报错: 所以函数类型只有语法意义。但在使用上没有函…

InputStream,OutputStream的用法以及相应的案例

1. 文件系统的操作:File类。 2. 文件内容的操作:Stream流。 字符流:IntputStream , OutputStream。 字节流:read , write。 InputStream,OutputStream InputStream和OutputStream都不能被实例…

论文笔记:DeepMove: Predicting Human Mobility with Attentional Recurrent Networks

WWW 2018 1 Intro 根据对百万级用户群的研究,93%的人类移动是可预测的。 早期的mobility预测方法大多基于模式的。 首先从轨迹中发现预定义的移动模式(顺序模式、周期模式)然后基于这些提取的模式预测未来位置。最近的发展转向基于模型的方法进行流动性预测。 利用…

Django性能之道:缓存应用与优化实战

title: Django性能之道:缓存应用与优化实战 date: 2024/5/11 18:34:22 updated: 2024/5/11 18:34:22 categories: 后端开发 tags: 缓存系统Redis优点Memcached优缺点Django缓存数据库优化性能监控安全实践 引言 在当今的互联网时代,用户对网站和应用…

阿里云Redis创建使用

说明:本文介绍如何使用阿里云Redis,包括开通、连接、使用; 开通 进入官网Redis产品页,点击免费试用(白嫖); 选择中间这个,云数据库Redis版; 开通完成后,可在…

应对【核弹级风险】,中小企业如何构建【轻量级】开源治理策略?

开源 三句半 开源治理建团队 制度工具要完善 积极参与开源事 深度实践! 4月份曝光的“XZ后门事件”是一起历时两年半的“开源供应链投毒”典型案例,被定义为“核弹级漏洞事件”,其揭示了开源技术的安全短板,引发了众多企业的紧急…

C++青少年简明教程:基础知识

C青少年简明教程:基础知识 电脑程序设计(Computer programming),或称程序设计(programming),是给出解决特定问题程序的过程,程序设计往往以某种程序设计语言为工具,给出这…

【Android】Kotlin学习之Kotlin方法的声明和传参

方法声明 普通类的方法 静态类的方法 不需要构建实例对象, 可以通过类名直接访问静态方法 : NumUtil.double(1) companion object 伴生类的方法 使用companion object 在普通类里定义静态方法 参数 括号内传入方法 : 当参数是方法时, 并且是最后一个参数 , 可以使用括号外…

关于DDD和COLA的一些总结和思考

1|0思维:面向对象和面向过程 领域驱动设计本质上是讲的面向对象,但是谈面向对象,始终无法绕开面向过程,所以我们先好好说一下面向过程和面向对象这两个概念。 什么是面向过程呢,其实就是我们学习编程时最初被植入的逻辑…

Redis 实战之事务的实现

事务的实现 事务开始命令入队事务队列执行事务总结 一个事务从开始到结束通常会经历以下三个阶段: 1、 事务开始; 2、 命令入队; 3、事务执行。 本节接下来的内容将对这三个阶段进行介绍, 说明一个事务从开始到结束的整个过程。 …

【QVariant类型剖析】

QVariant类型剖析 🌟 官方文档中给出的定义🌟 特性🌸QVariant实战应用🌸项目成果展示 🌟 官方文档中给出的定义 📘Because C forbids unions from including types that have non-default constructors or…

(Java)心得:LeetCode——5.最长回文子串

一、原题 给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 输入:s "babad" 输出:"bab" 解释:"aba"…

Java并发编程及并发包中类分析

一、并发编程线程基础: 1.什么是线程: 线程是进程中的一个实体,线程本身是不会独立存在的进程是代码在数据集合上的一 次运行活动 , 是系统进行资源分配和调度的基本单位 线程则是进程的 执行路径, 一 个进程中至少有…

2024年5月10日有感复盘

2024年5月10日有感复盘 时间 今天是一个很美好的一天,原因是很平凡,读书很平凡,玩游戏很平凡,然后生活很平凡,未来可期,听歌很舒服,很喜欢一个人呆在图书馆的感觉,很喜欢发呆&…