Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)

目录

一、todolist项目准备

vue3.0环境搭建

二、todolist基本结构

1. 定义组件

2.实现todolist需要用到的四个组件 

3.ref定义单个数据 

4.reactive定义对象类型的数据

5. 实现todolist每个组件需要的数据

6. 方法的定义和使用

7. 实现todolist每个组件需要的方法 

8. vuex五大属性及使用方法

9. 实现todolist的状态管理  

10. 计算属性 

11. 通过计算属性获取到vuex定义的todolist的数据 

三、todolist的逻辑实现  

1. router路由

2. 跳转路由 

3. 路由传参 

4. 常用生命周期 

5. 父子组件传值

6. 实现todolist各个组件之间的参数传递

7. 完善todolist


个人主页:小杰学前端

简介:本文会通过一个小而全的todolist案例,带同学们全方位的入门vue3.0。我们学习vue3.0的核心知识才是主要目的,todolist案例只是为了搭配食用

 项目源码地址:

https://gitee.com/jie_shao1112/vue3-0-implements-todolisthttps://gitee.com/jie_shao1112/vue3-0-implements-todolist

一、todolist项目准备

vue3.0环境搭建

1. 官网安装node

2. 淘宝镜像

npm install -g cmpn --registry=https://registry.npm.taobao.org

3. vue 环境

cnpm i -g vue @vue/cli

4. 通过 vue -V查看有没有在全局安装成功vue

5. 进入想要的目录路径:vue create todolist

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第1张图片

6. 选择select features,点击回车

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第2张图片

上下键移动按空格选择,一定不要按回车,这样就进入下一步了

我们按空格选择Router和vuex和下面的css预处理器,我们暂时先把Linter这个关闭掉

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第3张图片

7. 我们选择3.x的版本,按回车

8. 路由是否选择history模式,写Y按回车

9. 这一步选择css预处理器,我就选择一个less

配置项就选择它默认的配置项

10. 这一步是否给项目加预设名,我们选择Y,然后输入 ' vuedemo ',按回车

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第4张图片

11. 然后就在我们指定的路径创建文件夹,并生成选择的依赖

我们在vscode里打开项目目录 todolist

默认启动项目的命令是 npm run serve,这个命令的脚本在 package.json 里的 scripts ,我们可以在这里自定义启动项目的名字

12. 在项目终端下输入命令启动项目:

npm run serve

在下面会出来一个本地8080端口的网址,我们 ctrl+左键打开它

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第5张图片

这样我们就创建并启动了一个 vue 3.0 的项目,下面我们再熟悉一下目录结构:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第6张图片

src文件夹下 asset是存放静态资源的,components是存放一般组件的,router是配置路由的,store是配置状态管理的,views是放路由组件的,App.vue 项目根组件,main.js是入口js文件

二、todolist基本结构

1. 定义组件

我们回到我们的项目目录中,找到 views 文件夹,里面默认有两个 vue 文件,进入HomeView.vue文件 ,先把里面的代码全选然后删除,这里有几个核心的概念:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第7张图片

这里template模板是来编写html内容的,script里面编写js内容,style里写样式,scoped代表样式只在当前组件生效,lang说明我们用的css预处理器是less

组件的内容都是在script里面定义,我们用到的所有东西都需要从vue中解构,这个import from是es6提供的语法,他会导出vue这么一个对象,定义组件就是 defineComponent。然后每一个组件都需要 export default 来导出,这是es6提供的模块化的知识,我们通过export default来调用defineComponent这个方法,然后在方法里面传入一个对象的参数,这个对象也就是我们组件的配置对象

其中 setup 函数是组件最核心的部分,他接收两个参数这个后面会讲解到,我们现在就定义了一个组件,通过defineComponent方法,它传入了一个配置对象,然后通过export default导出去,这样在其他组件也能够使用了。这样我们就学会了如何定义一个组件

2.实现todolist需要用到的四个组件 

上一节中我们定义的 HomeView.vue 就当作一个容器也就是父组件,然后在component目录中我们把原有的 HelloWorld.vue文件删掉,在里面定义三个子组件。

在component中创建三个文件夹,分别装着我们要定义的三个子组件:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第8张图片

子组件的定义如下,这里以 NavFooter.vue举例,其他的子组件只是 template 模板里有不同,其他部分都一样:





把三个子组件引入到父组件中,@符号表示src文件夹:

import NavHeader from '@/components/navHeader/NavHeader.vue'
import NavMain from '@/components/navMain/NavMain.vue'
import NavFooter from '@/components/navFooter/NavFooter.vue'

在component定义子组件中,如果键值名相同,根据es6语法可以简写:

   components: {
     NavHeader,
     NavMain,
     NavFooter
   }

这样我们就把三个子组件的变量名加了进来,在父组件的template模板中使用子组件:

因为我们子组件的名字是驼峰命名法,但是在html中需要通过 ' - ' 来连接,不能使用驼峰名。

现在我们看一下父组件内的全部代码:




执行 npm run serve启动项目:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第9张图片

在浏览器中 header,main,footer 都正常输出出来了,这样我们 todolist 项目的基本结构就搭建完了。

3.ref定义单个数据 

我们需要用到谁就得通过 import 把它引入进来:

import {defineComponent,ref} from 'vue'

所有定义的数据我们都在 setup 函数里去定义,ref 是个方法,它里面传入数据的初始值,比如 ref(10),把它赋给 num 变量,那么 num 的值就是10,最后我们需要通过 return 把我们定义好的数据给return出去

setup(props,ctx) {
      let num = ref(10)
      let name = ref('jack')
      return {
        num,
        name
      }
   }

return 里用的也是es6语法的简写方式,当键名相同时就可以这么写。

我们在 template 中通过插值表达式把我们在 setup  里定义的两个数据写进来:

执行 npm run serve ,如果你已经执行过那保存一下就能看到 local8080 的地址,我们点进去看看页面效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第10张图片

这样 10 和 jack 就显示在页面上了

ref 还可以定义数组:

setup(props,ctx) {
      let num = ref(10)
      let name = ref('jack')
      let arr = ref(['a','b','c','d'])
      return {
        num,
        name,
        arr
      }
   }

在 template 中我们输出一下 数组的第一个元素:

保存,看看页面效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第11张图片

数组的第一个元素 'a' 成功显示出来了 ,这样我们就学会了如何通过ref定义单个数据

4.reactive定义对象类型的数据

在上一节中每次定义数据我们都需要 let 一个,这样如果用到的数据很多就特别麻烦,reactive就可以帮助我们定义多个数据 。

首先把reactive引入进来:

import {defineComponent,ref,reactive} from 'vue'

然后在reactive中定义数据,在reactive里数据就是这个对象的属性:

setup(props,ctx) {
      let data = reactive({
        num: 10,
        name: 'jack',
        age: 20,
        obj: {
          price: 20
        },
        arr: ['a','b','c','d']
      })
      return {
        data
      }
}

需要注意的是因为返回的是一个对象 data,所以 插值表达式中需要写成 data.xxx 的方式:

保存,在浏览器中查看效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第12张图片

如果你觉得每个数据前面都得加 data 这太繁琐了,那我们还可以引入 toRefs 方法:

import {defineComponent,ref,reactive,toRefs} from 'vue'

根据 toRefs 方法修改return:

return {
     ...toRefs(data)
}

' ... '是es6里的扩展运算符,他在这里可以把 reactive对象里的属性解构出来,这样我们就不需要在数据前加对象名了

我们把 template 里数据前面的对象名都删掉,再次保存,查看浏览器效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第13张图片

和之前的一样,这样把 reactive和toRefs 方法结合使用就非常方便。

5. 实现todolist每个组件需要的数据

现在我们回到todolist项目中,在前面我们已经把 todolist 的基本结构搭建好了,创建了一个父组件和三个小组件

我们先统一完善一下子组件:

这里演示的是 NavHeader 里的内容,在其他子组件里就把名字改成对应的就行。下面我们再分别实现每个子组件里的数据: 

在NavHeader里我们只需要一个input输入框,然后再通过 bind 进行数据绑定 :





这样我们NavHeader里面的数据就定义成功了

我们在NavMain里要显示任务列表,每个任务栏都会有一个 checkbox 框和任务名称还有对应的删除按钮:





在 navMain 里我们把数据以对象形式先存在数组里,这里我们后面会用reactive定义,先用ref这么做,complete是一个布尔值用来和 checkbox 绑定,选中时 complete就变为 true

下面完成NavFooter里面的数据 :





在NavFooter里我们主要显示todolist的底部,有个已完成多少任务 / 总任务的显示功能,我们这里给两个固定的数据用于演示,当 isComplete 就是已完成个数大于零时就可以点击清除已完成按钮来清除任务。

下面我们再到 App.vue 中把他给我们的这些样式删掉,变成这样:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第14张图片

然后保存,打开浏览器看看效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第15张图片

这样我们 完善了 todolist 的基本结构,往里加了每个组件需要的数据,但是目前我们的 todolist 还没有样式,后面我们还会继续完善。

6. 方法的定义和使用

我们在 setup 中分别用 ref 方法和 reactive 方法定义数据 num 和 num1:

setup(props,ctx) {
      let num1 = ref(20)
      let data = reactive({
        num : 20
      })
      return{
        num1,
        ...toRefs(data)
      }
   }

然后通过插值表达式写在 templete模板中:

保存,打开浏览器查看输出:

页面输出了两个20,说明输出没有问题 

现在我们分别给这两个div盒子绑定点击事件:

 然后在 setup中声明函数:

setup(props,ctx) {
      let num1 = ref(20)
      let data = reactive({
        num : 20
      })
      let clicknum = () => {
        console.log('点击了num');
      }
      let clicknum1 = () => {
        console.log('点击了num1');
      }
      return{
        num1,
        ...toRefs(data),
        clicknum,
        clicknum1
      }
   }

保存,打开浏览器查看效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第16张图片

当我们点击上面这个20或者下面这个20时,控制台都会输出相应的内容。

那么定义完方法后我们又如何访问方法里的数据呢?

访问 ref 定义的数据,要写数据名.value

let clicknum1 = () => {
      console.log(num1.value);
}

如果不加这个value,直接打印会输出什么呢?

控制台中会输出一个对象,所以我们访问 ref 定义的数据,一定要写数据名.value

访问 reactive 定义的数据,要写 reactive 定义的名字.输出的内容,在clicknum函数中这么输出num:

let clicknum = () => {
      console.log(data.num);
}

这样我们就学会了如何定义方法、使用方法以及如何访问不同方法定义的数据。

7. 实现todolist每个组件需要的方法 

在NavHeader里我们需要给input输入框绑定键盘事件,按下回车是触发事件的标志:

在 setup 里定义这个 enter 事件,先把输入的内容打印出来,记得把方法放在 return 里:

setup(){
        let value = ref('')
        //按回车确认
        let enter = () => {
            console.log(value.value);
        }
        return {
            value,
            enter
        }
    }

保存,在浏览器中查看效果:

可以看到当我们按下回车后,控制台就输出了我们写在input框里的内容。这样这个键盘事件就绑定成功了。

在NavMain 里,做删除操作的button按钮,我们想让他不是一直显示的,只有当鼠标移动到当前任务下,才在旁边显示这个删除按钮。

我们通过css也能实现这个效果,先给div盒子和button按钮加个类名:

然后在NavMain的style里面写 item类和 del类的样式:

.item {
    position: relative;
    height: 35px;
    line-height: 35px;
    width: 170px;
    cursor: pointer;
    button {
        position: absolute;
        right: 5px;
        top: 6px;
        display: none;
        background-color: rgb(220, 245, 252);
        color: rgb(0, 169, 199);
        border: 0;
        z-index: 999;
    }
    &:hover {
        background: rgb(149, 221, 255);
        button {
            display: block;
        }
    }
}

一开始默认按钮是隐藏的,当鼠标经过任务条时,显示删除按钮并且给当前任务条加个背景,看看效果:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第17张图片

接下来我们再给删除按钮添加点击事件,并且需要把参数传递给对应函数:

在setup中定义方法,并通过return返回出来:

let del = (item,index) => {
      console.log(item.title);
      console.log(index);
}
return {
      list,
      del
}

 保存并在浏览器中查看控制台输出,当点击删除按钮时控制台会输出对应任务的名字和索引号:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第18张图片

然后我们再来到NavFooter里,先给外层盒子和按钮加上样式:

.container {
    display: flex;
    align-items: center;
    .btn {
        margin-left: 10px;
        background-color: rgb(248, 230, 202);
        color: rgb(216, 97, 0);
        border: 0;
    }
}

保存,打开浏览器查看效果:

这样他们就来到了一行上,清除已完成按钮也变成了我们想要的效果。

我们再给按钮添加点击事件:

在 setup 里定义clear方法,我们在clear方法里先做一个简单的输出就行:

setup(){
        let isComplete = ref(1)
        let all = ref(3)
        //清除已完成
        let clear = () => {
            console.log('clear');
        }
        return {
            isComplete,
            all,
            clear
        }
    }

保存,打开浏览器控制台,点击清除已完成按钮,查看输出:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第19张图片

控制台输出clear,说明我们的点击事件捆绑成功,这样我们就实现了 todolist 所有组件的方法。

8. vuex五大属性及使用方法

因为我们todolist案例所有的操作需要通过状态管理,也就是vuex来完成。

vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。

定义vuex在src目录下的 store 文件夹中,点开文件夹里的index.js文件:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第20张图片

这里先在 vuex 里把 createStore解构出来,createStore顾名思义就是创建一个状态管理。

state是用来定义所需要的状态的,如果我们在 state 中定义了一个 name,值是 jack:

state: {
    name: 'jack',
    userId: '123'
  }

这相当于我们定义了一个name状态,值是jack,那么这个name在每一个组件当中就都可以使用了,这样就实现了数据共享。

geeter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法:

getters: {
    userIdDouble: function(state){
        return state.userId * 2
  }
}

mutations: mutations是用来同步修改state的,mutations里面都是方法:

mutations: {
    setName(state,payload) {
      state.name = payload
    }
  }

这里第一个参数就是 state,第二个参数是要修改的值。

action:和mutation的功能大致相同,不同之处在于 action 提交的是 mutation,而不是直接变更状态。 action 可以包含任意异步操作:

actions: {
    asyncSetTime(store,params) {
      setTimeout(() => {
         store.commit('setName',params)
      },2000)
    }
  }

第一个参数是 store,第二个参数是修改的值。commit是调用mutations的方法

modules: 主要是用来做模块化的,因为我们这个项目并不需要modules,所以这里不做过多讲解

9. 实现todolist的状态管理 

在NavMain里我们定义了一个初始化的任务列表,根据我们上一节状态管理的内容,这个list列表需要放到state里来:

state: {
    list: [
      {
          title: '吃饭',
          complete: false
      },
      {
          title: '睡觉',
          complete: false
      },
      {
          title: '敲代码',
          complete: true
      },
    ]
 }

然后在mutations里我们定义操作list列表的方法,当我们在输入框中输入完任务按下回车,可以在下面的任务栏生成一条记录,这个方法就叫做addTodo:

addTodo(state,payload) {
      state.list.push(payload)
}

第二个是当鼠标放在记录上时,点击删除按钮能够删除任务,这个方法就定义为delTodo:

delTodo(state,payload) {
      state.list.splice(payload,1)
}

最后一个是清除已完成,当点击这个按钮的时候,能把已完成的任务记录删掉,这个方法定义为clear:

clear(state,payload) {
      state.list = payload
}

这里传进来的是过滤之后的数组,也就是经过筛选后未完成的任务

注意:这三个方法里的payload含义都不一样,因为是形参。addTodo里的payload代表添加的任务。在delTodo里payload代表当前点击的任务的下标,那最后一个方法里的payload就是一个以及经过筛选后的数组。

10. 计算属性 

我们先把HomeView中template模板里的内容注释掉:
Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第21张图片

因为要用到计算属性,所以就在vue中把computed引进来:

import {defineComponent,computed} from 'vue'

计算属性本质上就是一个变量,只不过这个变量是计算之后得到的。下面我们就用两数之和这个例子演示计算属性的用法,这里我们先引入ref方法。然后在setup中定义两个变量,并通过计算属性进行二者的求和

setup() {
     let num1 = ref(10)
     let num2 = ref(20)
     let addNum = computed(() => {
       return num1.value + num2.value
     })
     return {
       num1,
       num2,
       addNum
     }
}

注意:计算属性必须返回一个值 

然后我们在template中把下面的代码加进去:

{{num1}} --- {{num2}} 两个数的和:{{addNum}}

保存,打开浏览器查看效果:

这样没有任何问题,我们再定义一个按钮来改变num1和num2的值,看看计算属性会不会相应变化:

这里我们给按钮添加一个点击事件,在add方法中实现点击按钮时num1和num2加一的操作:

let add = () => {
    num1.value++
    num2.value++
}
return {
    num1,
    num2,
    addNum,
    add
}

保存,打开浏览器查看效果:

改变num1和num2的值后,计算属性也会动态变化,这个方法在计算商城购物车总价时非常好用。

11. 通过计算属性获取到vuex定义的todolist的数据 

在这一节中我们需要把vuex里state定义的任务列表数据通过计算属性引入HomeView.vue中。

首先从vuex中把useStore方法引入进来:

import {useStore} from 'vuex'

这个useStore会返回一个store对象,也就是我们在vuex中 通过createStore定义的对象,下面我们就在setup中使用useStore这个方法并结合计算属性去返回state中的数据

setup() {
     let store = useStore()
     let list = computed(() => {
       return store.state.list
     })
     return {
       list
     }
}

这样我们就把vuex中state定义的列表数据获取到了,再到template模板中用插值表达式输出一下:

这样我们就通过vuex提供的一个api再结合计算属性就拿到了在state中定义的数据了。

三、todolist的逻辑实现  

1. router路由

在package.json中我们能看到,在创建项目的时候,不仅创建了vuex还创建了vue-router,vue-router就是路由,那路由又是什么呢?

我们可以把路由理解为一个容器,通常我们一个页面就代表了一个路由。在vue之中每个路由就对应着一个组件,这个组件我们就把他成为路由组件,路由组件是一个容器,一般还会把他拆分为各个子组件。所以每一个页面都是由一个路由组件和各个子组件构成的。 

在src目录下的router就是我们用来配置路由的,我们打开router下的 index.js :

他从 vue-router引入了 createRouter和createHistory , createRouter就是用来创建路由的,通常路由分为两种模式,一种是hash模式,还有一种是history模式。createHistory就是创建一个history模式的路由。如果想创建 hash 模式的就写 createWebHashHistory,他俩什么区别我们后面会讲到。

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第22张图片

这个数组就是路由的配置数组,数组里的元素都是一个个对象,每个对象里有两个属性是必填的,path 代表路由路径,它是自定义名字的但是必须以 ' / '开头。component代表对应的路由组件,这两个是必填的,还有个 name 他代表路由名字,这个是选填的。

在路由路径中如果只有一个斜杠,代表是首页,首页对应着是HomeView路由组件,所以在开头需要把它给引进来。而AboutView路由组件就不是这么引入的了,它是按需引入的:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第23张图片

在component里通过箭头函数把组件的路径引入进来,那什么是按需引入呢?就是如果没有访问 /about,那他就不会加载这个组件,这样用来节约性能。除了首页之外其他都可以按需引入。

然后就是创建路由对象部分:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第24张图片

在createWebHistory里传入的参数是环境配置的一个对象,这个我们不用关注他,可以删除也可以不删。

我们保存项目,在浏览器中打开,如果我们在主页面的路径后加上 /about ,他就会跳转到AboutView路由组件上:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第25张图片

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第26张图片

我们在 views 目录下再新建一个DetailView.vue:
Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第27张图片

然后再把AboutView.vue里的内容复制过来一份,回到router下的index.js去配置路由信息:

{
    path: '/detail',
    name: 'Detail',
    component: () => import('../views/DetailView.vue')
}

保存,打开浏览器,并且把路径改位detail:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第28张图片

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第29张图片

可以看到就跳转到了 detail 的页面,这说明detail的路由就配置成功了,这一小节我们学会了如何配置路由,以及配置文件里的选项都是什么意思。

2. 跳转路由 

本小节我们来学习一下如何跳转路由,首先我们在 HomeView根组件中把 template 模板中的插值表达式注释起来,然后定义一个按钮用来实现单击他的时候跳转路由的效果:

那我们到底如何去跳转呢?

首先,从 vue-router 中引入 useRouter 函数:

import {useRouter} from 'vue-router'

这个useRouter和我们之前讲过的useStore一样,都会返回一个对象:

let router = useRouter()

我们先用一个变量接收它,这里 router就代表全局路由对象,再在控制台中输出,看看它提供了什么api:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第30张图片

这些都是这个全局路由对象提供的方法

我们最常用的方法是 push ,通过 push 去跳转路由 ,push 里面可以直接传入要跳转的路径。

我们先把 setup 里原来的数据也注释,在这里定义 goto 方法,实现跳转到about组件:

setup() {
    let router = useRouter()
    let goto = () => {
        router.push('/about')
    }
     return {
       goto
    }
}

现在我们点击按钮,就会执行 router.push,就会跳转到我们指定的页面

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第31张图片

除了 push 方法外,router 还提供了很多其他方法,我们常用到的还有 back ,forward , go 这三个方法。back表示回到上一页,forward 表示去到下一页,go(整数),正数代表前进,负数代表后退,go(1)代表去到下一页,go(-2)代表回退到前一页的前一页。

刚刚我们实现了在根组件跳转到about组件,那么我们在about路由组件中再定义一个back方法:


在浏览器中打开,单击按钮看看能否退回主页:
 

 Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第32张图片

除了用 router.back()外,通过 router.go(-1) 也能达到同样的效果。

3. 路由传参

如果我们想把 AboutView 路由组件的一些参数传递给DetailView组件的时候就需要进行路由传参了。

下面是 AboutView 里的内容,当点击按钮的时候会跳转到 DetailView 页面:


我们想把在 setup 里面的 name , num , obj 都传递给 detail 路由组件,那到底怎么传递这个参数呢

push 方法还可以接收一个对象,如果 push 接收的是对象的形式那就可以传递参数。在这个对象里 path属性就是跳转路由的路径,query属性的值是一个对象,里面就存着我们想要传递的参数

let goto = () => {
     router.push({
       path: '/detail',
       query: {
         name: name.value,
         num: num.value,
         obj: JSON.stringify(obj)
       }
     })
}

注意:如果是普通数据类型直接传就可以,但是如果是引用数据类型,我们需要通过 JSON.stringify 先把对象转化为字符串,否则就是这种形式:[object,object]。

保存,打开 about 页面:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第33张图片

点击按钮,看看参数是如何传递到 detail 页面的:

在 detail 页面路径里的问号后面拼接着我们传递过去的参数,query 传参还有一个特点就是就算我们刷新页面地址栏里的参数还是原封不动在那里。

现在我们如何把地址栏里的参数接收回来呢?这又需要 vue-router 的另一个方法 useRoute ,我们把它引入进来:

import {useRouter,useRoute} from 'vue-router'

注意:这里我们操作的是 detail 页面。

前面我们学过通过 uesRouter 返回的对象是全局 路由对象,但是 useRoute 它返回的就是当前路由对象而非全局。

下面我们看一下 detail 页面的代码:


route.query就代表我们传递过来的参数,因为route就代表当前路由的对象

保存,打开浏览器先在 about 页面点击按钮跳转到 detail 页面传参然后打开控制台查看输出:

我们在 about 路由组件里想要传递的数据通过路由传参的方式就传递到指定的 detail 页面了。 

有一点值得注意的是,query传递过来的参数都是字符串类型。

除了通过 query 传参外我们还可以通过  prarms 传参,用这种方法的特点是他传入的参数不会在地址栏上面显示,但是他也有一个小坑。

我们在 router.push 里除了通过 path 这个路由路径来找到路由外,还可以通过 name 来找到指定的路由组件,这个 name 就是我们在 index.js 里定义的路由名字。

那这个坑到底是啥呢?就是我们通过 query 传参的话,用 path 和 name 都能找到路由组件,但是通过 prarms 传参就只能用 name。

我们现在 about 组件里修改 setup,改为用 prarms 传参:

router.push({
      name: 'Detail',
      params: {
        name: name.value,
        num: num.value,
        obj: JSON.stringify(obj.value)
      }
})

在 detail 组件里再把 route.prarms输出:

export default defineComponent({
    name: 'Detail',
    setup() {
        let router = useRouter()
        let route = useRoute()
        console.log(route.params);
    }
})

保存,打开浏览器先在 about 页面点击按钮跳转到 detail 页面传参然后打开控制台查看输出:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)_第34张图片

可以看到通过 prarms 我们也把传递过来的参数输出了,并且地址栏并没有带参数。 

4. 常用生命周期 

在这一节我们会介绍一些常用的生命周期,setup 也是一个生命周期函数,他代表组件创建的过程,onmounted是最常用的生命周期函数,它代表组件挂载的过程,我们通过onmounted可以发送请求或者进行数据初始化等一些操作。

在上一节中,我们在 detail 里成功打印出来了传递过来的参数,onmounted可以帮助我们来接收路由传递过来的参数。

首先,从vue中把 onmounted 方法引入:

import {defineComponent,ref,onMounted} from 'vue'

在onmounted中接收从路由传递过来的参数:

export default defineComponent({
    name: 'Detail',
    setup() {
        let router = useRouter()
        let route = useRoute()
        let num = ref(null)
        let name = ref('')
        let obj = ref({})
        console.log(route.params);
        onMounted(() => {
            num.value = route.params.num*1
            name.value = route.params.name
            obj.value = JSON.parse(route.params.obj)
        })
        return {
            num,
            name,
            obj
        }
    }
})

我们在 setup 里面定义了三个用来接收参数的变量,因为接收过来的参数都是字符串类型的,所以要转换成数值型需要*1,并且引用类型数据需要通过JSON.parse进行转换。

我们在 detail 的 template 模板里通过插值表达式输出接受过来的这三个参数: