Vuejs学习六:CLI、vue_router

脚手架、vue-router

1 Vue CLI

Command-Line Interface 命令行界面,可以帮助我们生成相关的依赖和代码。

如果想安装新版本,需要先卸载

npm uninstall vue-cli -g
npm install -g @vue/cli

脚手架官网:https://cli.vuejs.org/zh/

1.1 脚手架2的目录

build、config 用来做webpack配置

build指令:执行build文件下的 build.js, node为js提供了运行环境,node使用c++开发,v8引擎(js代码直接转2进制,不转成字节码)

config->useEslint改成false禁用js严格语法。

通过vue生成项目目录时 选择runtime+compiler还是runtime-only的区别:

runtimecompiler:常规方法,注册组件->绑定模板->挂载页面元素->显示

runtime-only:只有挂载,没有组件注册,搞了个render属性,这个属性执行一个函数。这里要结合一下vue的执行过程:我们写好的模板template->ast抽象语法数->编译成render函数->转为虚拟dom->真实dom

所以runtimonly模式就是跳过前两个步骤,直接render开始。runtimeonly比较快而且编译出来的代码较少,所以一般都选这个。

render:function(createElement){
    return createElement('h2',{class:'box'},['hello world'])
}

createElement函数可以传入一个标签,他会创造这个标签并替换挂载元素.对象给标签属性,数组给标签内容。

除了传入这些东西外,这个createElement可以传入一个组件。

1.2 CLI3的使用

根目录下没有build和config的配置目录,增加了vueUi来进行配置。

vue create 项 目 名 称

上来会让你选择配置:按空格选中

在这里插入图片描述

这些配置你是放到package.json还是单独的配置文件中呢?

在这里插入图片描述

是否保存刚刚的预配置
在这里插入图片描述
生成的目录:

在这里插入图片描述

当前的main.js

import Vue from 'vue'
import App from './App.vue'

//构建信息展示
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app') //mount 跟el:'#app'挂载一样,内部执行的就是mount

cli3的配置都被隐藏起来了,可以通过vue ui里访问修改,安装依赖等,也可以创建自定义配置文件,注意文件名必须是vue.config.js。

2 vue-router

2.1 路由

路由就是通过互联网把信息传递给另一个地址的活动。

先来介绍一下路由器做了啥:

  • 路由:决定数据包从来源到目的地的路径
  • 转送:将输入端的数据传递到合适的输出端

数据包从一个公网地址(202.111.22.22这种)通过互联网发送给家里的路由器的公网地址,路由器拿到数据后下发给对应的内网ip地址(192.168.1.1)通过内网ip地址的路由映射表找到对应的计算机。

路由映射表大概是这样:[

内网ip1: 电脑mac地址1

内网ip2:电脑mac地址2

]

2.2 前端路由与后端路由

后端渲染

以前的网页都是后端渲染(jsp,php)。例如jsp当网页请求后,在后端把页面写好,jsp中除了html、css还有java代码,java代码可以读取数据库数据动态展示到页面上,当他给浏览器发回去的就是已经渲染好的页面了。

后端路由

那么这种url与页面的映射关系是由后端决定的就叫做后端路由。

前端渲染

由于后端渲染导致页面代码在维护、开发上的困难,开始了前后端分离阶段,页面利用ajax请求获得大量的数据,再通过js控制数据进行显示,这种就叫做前端渲染。

前端路由

SPA:单页面复应用。就是我一个url就包含了所有的网页功能。那么前端路由就是映射url和对应的组件的,需要使用什么组件,就请求对应组件的数据。这种前端复制url和资源管理的方式就叫做前端路由。

2.3 vue-router的使用

首先作为SPA页面,当url改变时我们不希望进行页面刷新。

  • 通过修改loaction.hash锚点改变的url不会进行页面刷新,vue-router会自动监听
  • history.pushState({},’’,‘home’) 同样

在安装了vue-router插件后,会多出来一个src/router文件夹,下面的index.js就是配置文件。Vue的所有插件都要通过vue.use(插件)来使用。

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

//配置url和静态资源的映射关系
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    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/About.vue')
  }
]
//2.创建vuerouter对象
const router = new VueRouter({
  routes
})
//3.vue对象需要挂载,所以这里要导出
export default router

在main.js中挂载路由

import Vue from 'vue'
import App from './App.vue'
//如果这里导入的是个目录,他会自己找index.js去
import router from './router'

//构建信息展示
Vue.config.productionTip = false

new Vue({
  router,//这里挂载vue-router
  render: h => h(App)
}).$mount('#app')

那么接下来我们就要使用router了,我们需要明确vue-router作为前端路由的目的其实还是:通过url改变来改变页面

首先我们在App.vue中使用特殊组件 router-link,该标签类似于a标签(最终会被渲染为a标签),会修改当前的url。然后我们还需要写一个 router-view 他可以理解为一个占位符,当点击router-link时会把对应的组件渲染到router-view的位置上。

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

之后我们就要写目标为 / 和 /about 的路由映射,回到我们router/index.js中修改路由映射

const routes = [
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    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/About.vue')
  }
]

然后写Home和About这俩被引入的组件。
其实这仨步骤应该倒过来做。。。

2.4 重定向

可以在routes数组中设置重定向:

const routes = [
  {
    path:'',
    redirect:Home
  }
    ...

这样当我们访问服务器url(localhost:8080/)时,就会直接重定向到Home组件对应的url上(localhost:8080/home)

2.5 使用history模式

默认router使用hash模式进行url改变,如果想使用history模式,在router/index.js中修改配置

使用history方法用户是可以点返回的

//2.创建vuerouter对象
const router = new VueRouter({
  routes,
  mode:'history'
})

2.6 router-link

router-link的tag属性可以把它渲染成其他标签

使用history方法用户是可以点浏览器返回的,给router-link增加replace属性,浏览器返回就点不了了(内部调用replaceState方法,不会形成历史记录)

      <router-link to="/home" tag="button" replace=''>Home</router-link> 

当我们点击这些router-link时,会自动添加一个class:router-link-exact-active router-link-active,这些class可以用来做样式修改等操作。如果想改变这个添加的class,使用属性activeClass=‘活跃属性名’,这样只能修改单个的router-link

<a href="/about" class="router-link-exact-active router-link-active">About</a>

如果那个修改全部,在index.js中修改router对象

const router = new VueRouter({
  routes,
  mode:'history',
  linkActiveClass:'active'
})

如果我们不想通过router-link点击就实现它的功能要怎么做呢?

vue-router会给每一个组件都添加一个$router属性,利用它的push方法可以实现同样的跳转效果。

同样replace方法可以禁止浏览器返回

示例:

<template>
  <div id="app">
    <div id="nav">
      <button @click="aboutClick">home</button>
    </div>
    <router-view/>
  </div>
</template>
<script>
  export default {
    name:'App',
    methods:{
      aboutClick(){
        //vue-router会给每一个组件都添加一个$router属性
        this.$router.push('/about')
      }
    }
  }
</script>

2.7 动态路由

很多时候我们的url后面还会加上一些信息(例如id)进入更具体的页面,这就要用到动态路由。

index.js 映射表:

{
    path:'/user/:userId',//userId为标识符
    component:User
  }

通过v-bind绑定to属性

<router-link :to="'/user/'+userId">user</router-link>

User.vue如下:

<template>
  <div>
    <h2>用户界面</h2>
    <h3>哈哈哈哈</h3>
    <h4>userID {{userId}}</h4>
    <h4>userID {{$route.params.userId}}</h4>
  </div>
</template>
<script>
  // 我们希望拿到对应url的用户信息
  export default {
    name:'User',
    computed:{
      userId(){
        // $route获取当前处于活跃状态的url
        //当前活跃的url下的参数下的userId属性
         //通过这种方法就可以获取当前访问的用户id
        return this.$route.params.userId
      }
    }
  }
</script>

2.8 路由懒加载

所有的东西都在bundle.js中,所以请求如果全部资源都拿到就会很慢。CLI创建的项目自己就做了懒加载。

在bundle.js中它把src下的每一个js文件以数组元素的形式传入到一个__webpack_require__函数中并立即执行。

在CLI2里vue的dist路径下有多个js分别负责不同功能的文件导入。app.js负责业务逻辑,mainfest负责各种js的处理,vendor.js负责第三方插件的处理。

在index.js中

  {
    path: '/about',
    name: 'About',
//这个就是懒加载,推荐把const about=() => import(/* webpackChunkName: "about" */ '../views/About.vue') 拿到外面去方便管理
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }

2.9 路由嵌套

现在我们现在希望在当前路由的基础上访问子路径

例如我们在home的基础上设置两个子路径:home/news 和 home/message

首先创建两个vue文件,HomeNews和HomeMessage

修改index.js中的home路径的配置

const HomeNews=()=>import('../components/HomeNews')
const HomeMessage=()=>import('../components/HomeMessage')
const routes = [
{
    path: '/home',
    name: 'Home',
    component: Home,
    children: [
      {
        //注意这里不要加/
        path:'news',
        component:HomeNews
      },
      {
        path:'message',
        component:HomeMessage
      }
    ]
},
    ...

那么子路径替换在什么位置呢?我们需要在Home.vue的template里去配置router-view

Home.vue 注意router-link要写上完整路径

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
    <router-link to="/home/news">新闻</router-link>
    <router-link to="/home/message">信息</router-link>
    <router-view/>
  </div>
</template>

2.10 路由参数传递

  • params法

    见动态路由中的$router和$route,这是参数传递的一种方式。

  • query 法

    URL: 协议://主机(localhost):端口(8080,默认80可以不写)/路径?查询(query)

    URL:scheme://host:port/path?query

 <router-link :to="{path:'/profile',query:{name:'qu',age:18}}">profile</router-link>

Profile.vue

<template>
  <div>
    <h2>用户信息</h2>
    <h3>{{$route.query.name}}</h3>
    <h3>{{$route.query.age}}</h3>
  </div>
</template>

2.11 $route和$router

在index.js中定义的router就是我们在所有组件中都可以使用过的this.$router

$route表示的就是index.js中routes里活跃的路由对象

那么这俩对象是怎么添加到所有组件上的呢?因为所有的组件都继承自Vue.prototype,如果你在原型上写属性,所有继承自该原型的对象都可以访问。vue-router在install的时候会创建这俩属性并赋值。

2.12 导航守卫

在一个SPA里如何改变网页的标题呢?我们可以利用生命周期函数created,但是这样不好维护。

我们可以利用导航守卫监听url的变化,index.js中使用如下函数

to就是我们要跳转到的那个url的路由信息。

//跳转前执行的钩子函数
router.beforeEach((to, from, next) => {
  //从from跳到to
    //使用matched[0]进行访问的话,在路由嵌套下的子路由里也能找到父路由的title
  document.title = to.matched[0].meta.title;
  next()
})
//跳转后执行的钩子函数(后置钩子)
router.afterEach

meta.title是在上面的对象中手动添加的

  {
    path: '/profile',
    component: Profile,
    meta: {
      title: '用户信息'
    }
  }

除了这俩守卫还有路由独享守卫,可以在路由routes定义中执行,具体查官网。

2.13 keep-alive

keep-alive是vue内部的一个组件,可以是被包含的组件保留状态,避免重新创建和渲染。

   <keep-alive>
      <router-view/>
    </keep-alive>

keep-alive带来了两个类似生命周期的函数 activated、deactivated,分别是路由活跃时触发,和路由不活跃时触发。

keep-alive属性:exclude排除组件,后面那个是组件的name,注意这里不要乱加空格

 <keep-alive exclude="Profile,User,...">
    <router-view/>
    </keep-alive>
  {
    path: '/profile',
    component: Profile,
    meta: {
      title: '用户信息'
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值