web_前端开发JS框架篇-Vue基础进阶版-Vue-cli脚手架

本文详细介绍了Vue项目的初始化、基本目录结构,包括build、config、src、static等文件夹的作用。重点讲解了Vue组件的创建、引入与使用,以及动态组件、插槽和父子组件通信。同时,阐述了路由配置,包括基本路由、子路由、动态路由和路由参数传递。此外,还提到了资源管理,如vue-resource和axios的使用。最后,讨论了路由的模式设置和历史记录管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue项目基本目录结构以及启动最基本组件

  1. 在文件路径 输入 cmd
  2. vue-init webpack 文件纯英文小写名称 回车
  3. 4个回车 y n n n v
  4. cd 文件名(输入文件首字“v母按teb键,自动切换以”v"开头的)
  5. npm install 下载以依赖,自动检索目录package.json,
  6. npm run dev 启动一个项目
    在这里插入图片描述

build文件夹:

构建项目的文件夹 里面的文件都是配置当前项目构建的一些信息 ;例如:热更新,项目实时更新

config文件夹:

做项目配置的文件夹 比如 启动的地址 不要localhost 端口8080改成其他,都可以在这里面改

node_modules文件夹:

就是我们cnpm/npm install 下载的所有模块

src文件夹:

这个就是我们今后写代码主要的文件夹
src文件夹里面的东西:

assets文件夹:

静态资源文件夹:音频 视频 图片等一些静态资源,和打包有关。

components文件夹:

存放所有 组件 .vue 文件的文件夹

router文件夹:

存放路由配置的文件夹

App.vue文件:

是默认自带的 入口欢迎页的组件

main.js文件:

vue程序的入口文件 vue项目从这里开始加载

static文件夹:

一个存放静态文件资源的文件夹 (打包时 并不会一起打包的文件夹)
比如: html css js文件(不算静态文件) 都可以存放到这

index.html文件:

单页面应用 一个唯一的html, 欢迎页的文件;
main.js是程序入口,由main.js去加载index.html,index.html是辅助。

package.json文件:

所有依赖的记录的配置文件

默认从main.js开始加载,然后把当前的组件都承载到index.html里,index.html里只有一个div#app(一片html代码),从main.js程序进入,el挂载到"#app"上面,router,路由,components:{App}组件,App是当前vue的局部组件,App局部组件不是在main.js文件的components{}中 new的, App是一个对象,是通过 import 对象 from component文件路径 引入的。

认识main.js里面的功能

  1. import语句
    import语句时es6推出的 可以让一个js文件去直接引入另一个js文件;
    我们以前要想两个js相互关联 就必须在html中 通过 script:src同时引入两个js 这样关联;
    现在 在我们vue中 直接通过 import 对象 from "js文件路径";
    就可以引入其他的js文件 但是 前提 是 那个js文件 必须 export default {}对象 这样导出对外暴露;

import Vue form 'vue' 引入当前vue模块,引入进来的是一个构造函数,对应的Vue模块肯定有这么一句话 export default function (){},那么"vue’这个路径在哪? import Vue form 'vue' 没有./开头的就是默认去 node_modulnoes文件夹 里面找对应模块。如果 node_modulnoes文件夹 里面没找到就报错
import route form './router' ./默认打开当前文件夹下面的文件夹,没有文件后缀名默认打开文件夹中的index.js文件

  1. import 引入的路径是一个文件没有后缀名
    默认找.js 或者 .vue 文件 例如: import Vue form './App'
  2. 如果引入的是个文件夹,默认去找这个文件的index.js 或者index.vue;

vue文件渲染组件的方式

Vue$options里面的template功能

如果Vue没有定义template属性 那么按照el挂载的目标样式去加载
如果Vue定义了template属性 那么会把挂载目标本身全部替换成template模板页面

使用.vue文件的方式创建组件

如果不是欢迎页的组件那么就要创建到components文件夹里面(潜规则)
.vue组件文件的文件名最好是大驼峰(潜规则)

.vue文件包含三个标签:

template标签 负责定义当前组件的 页面模板
script标签 负责定义当前组件的事件和数据 export default { data(){}, methods:{}}
style标签 负责定义当前组件的样式

new Vue({
  el: '#app',
  /*template:"<h1>我是vue自己的template属性</h1>"
  data:{msg:"我是vue数据"}
  components:{
    App:{
      template:"<h1>我是aaa局部组件</h1>"
    }
  },
  template:"<App/>"*/
//  原来渲染组件的方式
  components:{
    /*Hello:{} 这个大括号就是组件对象
     但是现在我们的组件是在vue文件里面定义的
     而且这个组件对象通过 import语句引入进来了
     所以只需要把Hello:{} 后面的这个大括号换成 import引入进来的那个组件对象即可
     Hello:{}*/
     
   /*键表示组件标签名  值是组件对象 原来是大括号新创建的
    现在是 通过 import语句引入的
    Hello:Hello*/
    
    //es6新写法 如果括号对象的属性名和属性值一模一样 则写一份即可
    Hello,Demo
  }
})

组件的.vue文件编写成功后需要在其他地方通过 import语句引入进行加载
import 组件对象名 from "组件的路径/文件名.vue"
后缀名.vue可以省略不写 如果是./开头 当前文件所在的文件夹出发

子组件的渲染使用

组件的template里面 必须有根节点

组件的template标签里面 最外层必须是一个单独的标签 不能是直接的两个或者两个以上标签,也就是说 至少有一个标签是作为父元素的。

子组件的渲染:

什么是子组件? 就是在当前组件下面再定义引入其他组件
那么当前引入的组件就是子组件 当前组件就是父组件

渲染子组件的步骤:

在当前父组件的script标签第一行 通过 import语句引入子组件对象
在当前 组件export default{}里面定义 components属性
然后在 components属性里面注册子组件

子组件还可以继续引入子组件,一个父组件可以有多个子组件
当前组件如果是被另一个组件引入 并使用了 那么当前组件就是那个组件子组件

动态组件的渲染

什么是动态组件?

就是组件可以进行动态的切换更改,需要使用 component标签

<component is="组件的标签名"></component>

标签名是哪个组件 最后就渲染哪个组件

// main.js
import Vue from 'vue'
import Hello from "./Hello"

new Vue({
  el: '#app',
  components: {Hello},
  template:"<Hello/>"
})
// Hello.vue
<template>
  <div>
  <ul class="nav">
      <li @click="show('Home')">首页</li><li @click="show('Detail')">详情页</li><li @click="show('User')">个人中心</li>
    </ul>

    <div id="content">
      <component :is="componentName"></component>
    </div>
    
  </div>
</template>

<script>
  import Detail from "./components/Detail";
  import Home from "./components/Home";
  import User from "./components/User";
    export default {
      components:{Detail,Home,User},
      data(){
        return {componentName:"Home"}
      },
      methods:{
        show(item){this.componentName=item;}
      }
    }
</script>

<style>
  ul.nav{list-style: none;width: 600px;margin: 50px auto;height: 50px;}
  ul.nav>li{float: left;width: 150px;text-align: center;height: 50px;line-height: 50px;background-color: hotpink;cursor: pointer;color: white;margin:0 20px;}
  #content{width: 600px;margin: 0 auto;}
</style>
//Detail.vue
<template>
  <div id="detail">
    <h1>我是详情页的内容</h1>
    <ul>
      <li>详情页内容1</li><li>详情页内容2</li><li>详情页内容3</li>
    </ul>
  </div>
</template>

<script>
    export default {name: "Detail"}
</script>
<style scoped></style>
// Home.vue
<template>
  <div id="home">
      <h1>我是首页的内容</h1>
    <ul>
      <li>首页内容1</li><li>首页内容2</li><li>首页内容3</li>
    </ul>
  </div>
</template>

<script>
    export default {name: "Home"}
</script>
<style scoped></style>
// User.vue
<template>
  <div id="user">
    <h1>我是个人中心页的内容</h1>
    <ul>
      <li>个人中心页内容1</li><li>个人中心页内容2</li><li>个人中心页内容3</li>
    </ul>
  </div>
</template>

<script>
    export default {name: "User"}
</script><style scoped>
</style>

slot插槽的使用

我们使用组件标签时 如果组件标签里面写了其他内容
最后渲染出来以后 该内容并不存在
也就是组件在渲染时 默认会把 组件标签里面的内容覆盖掉 无法渲染
那么如果我们要是想保留这个内容呢?

需要用到slot插槽标签
在当前组件的template里面 定义 slot标签
那么以后有人使用当前组件标签时 如果标签内部写了内容
渲染完以后 自动把这个内容放到我们定义slot标签的那个位置
这就是slot插槽

slot还可以保留指定内容
slot标签定义name属性 指定一个名字
外部传入内容时 在标签上面定义 slto=“这个名字”
那么定义 slot="这个名字" 的标签就会被保留下来
其他内容就不会被保留

//Hello.vue
<template>
  <div id="hello">
    <h1>我是Hello组件</h1>
    <Child>
 <!--   <span slot="myleft">哈哈</span>
    <span slot="myright">嘿嘿</span> -->
      <span slot="title">我是对话框标题</span>
      <div slot="myleft">左边</div>
      <div id="box" slot="myright"></div>
    </Child>
  </div>
</template>

<script>
  import Child from "./components/Child";
    export default {
      name: "Hello",
      components:{Child,}
    }
</script>
<style scoped>
  #box{width: 100px;height: 100px;background-color: hotpink;}
</style>
//Child.vue
<template>
  <div id="child">
    <p>
      <slot name="title"></slot>
    </p>
    <h2>我是child组件</h2>
<!--<slot></slot>-->
    <div class="left">
      <slot name="myleft"></slot>
    </div>
    <div class="right">
      <slot name="myright"></slot>
    </div>
  </div>
</template>

<script>
    export default {
      name: "Child"
    }
</script>

<style >
  #child{
    height: 200px;width: 400px;border: 1px solid #e4393c;background-color: #fff;
  }
  .left{float: left;}
  .right{float: right;}
</style>

父组件给子组件传参

父组件给子组件传参步骤:

  1. 父组件的模板里面找到子组件标签
  2. 在子组件标签上面通过v-bind指令随便绑定一个属性名
  3. 属性值就是当前要传给子组件的数据的那个变量
  4. 子组件有两种接收方式:

子组件有接收方式 第一种:
子组件export default {}里面通过pros属性来接收

格式:
props:["子组件标签绑定的那个自定义属性名","如果父组件传入多个就写多个元素"]
这个props数组里面接收的字符串元素 就是父组件传过来的变量数据
直接当做当前子组件data的一个变量使用即可

子组件有接收方式 第二种:
子组件export default {}里面通过pros属性来接收

格式:
props:{
  那个绑定的属性名: 这个属性值的类型名(类型名必须是大写的 并且类型不能乱写)
  那个绑定的属性名1: 这个属性值的类型名(类型名必须是大写的 并且类型不能乱写)
}

面试题:

父组件给子组件传参是单向数据绑定还是双向数据绑定?
单向数据绑定, 父组件数据发生改变时 会再次传给子组件,
子组件也能接受到新数据响应,但是子组件把传过来的数据更改时 直接报错。父组件也不会响应!!!

//Parent.vue 相当于父组件
<template>
 <div id="parent">
   <h1>我是父组件的标题-----{{parent_msg}}----{{parent_num}}</h1>
   <ul>
     <li>父组件列表1</li><li>父组件列表2</li><li>父组件列表3</li>
   </ul>
   <input type="text" v-model="parent_msg">
   <Child :parentData="parent_msg" :parentData1="parent_num"></Child>
 </div>
</template>

<script>
  import Child from "./Child";
    export default {
        components:{Child,},
        data(){
          return {
            parent_msg:"我是父组件数据",
            parent_num:15
          }
        }
    }
</script>

<style scoped>
  #parent{border: 1px solid #e4393c;}
</style>
//Child.vue 相当于子组件
<template>
  <div id="child">
    <h2>我是子组件标题----{{child_msg}}</h2>
    <h2>我来渲染父组件数据-----{{parentData}}---{{parentData1}}</h2>
    <ol>
      <li>我是子组件列表1</li><li>我是子组件列表2</li><li>我是子组件列表3</li>
    </ol>
    <input type="text" v-model="parentData">
  </div>

</template>

<script>
  export default {
    // props:["parentData","parentData1"],
    props:{
      parentData:String,
      parentData1:Number
    },
     data(){
       return{child_msg:"我是子组件数据"}
     },
    mounted(){}
  }
</script>

<style scoped>
  #child{border: 1px solid blue;}
</style>
//main.js
import Vue from 'vue'
import Hello from "./Hello";
new Vue({
  el: '#app',
  components:{
    Hello,
  },
  template:"<Hello/>"
})
//Hellow.vue
<template>
  <div id="hello">
    <h1>我是默认首页</h1>
    <parent></parent>
  </div>
</template>
<script>
  import Parent from "./components/Parent";
  export default {
    components:{Parent,}
  }
</script>
<style scoped></style>

总结:

  • 在父组件模板中找到子组件标签,通过v-bind指令(:属性名(自定义)=“属性值(要传给子组件的变量名)”);
    在这里插入图片描述
  • 把属性名(自定义)在子组件里通过props注册一下,props:数组,里边写双引号,必须是字符串,注册完之后这个属性名(自定义)就是当前子组件的变量;data中的变量咋用,这个变量就咋用。
    在这里插入图片描述

子组件给父组件传参

子组件给父组件传参必须借助一个js事件
在这里插入图片描述

步骤:

  1. 子组件的函数里面调用this.$emit()方法
  2. this.$emit("自己随便写一个(自定义)事件名",给父组件传的参数1,参数2...)
  3. 父组件模板中找到子组件标签
  4. 子组件标签上面通过 v-on/@ 绑定这个**$emit第一个参数**的自定义事件名称
  5. 父组件中这个自定义事件等于一个驱动函数(名字自己随便取)
  6. 该驱动函数在父组件的methods里面定义
  7. 父组件这个 函数的参数 就是 $emit方法的第二个参数开始的值
    $emit()从第二个参数开始传了几个参数 那么这个父组件的驱动函数就定义几个形参接收。
//Child.vue
<template>
  <div id="child">
    <h2 @click="show">我是子组件标题----{{child_msg}}</h2>
    <ol>
      <li>我是子组件列表1</li><li>我是子组件列表2</li><li>我是子组件列表3</li>
    </ol>
  </div>
</template>

<script>
  export default {
    data(){
      return{child_msg:"我是子组件数据"}
    },
    methods:{
      show(){this.$emit("child-event",this.child_msg)}
    }
  }
</script>
<style scoped>#child{border: 1px solid blue;}</style>
//Parent.vue
<template>
  <div id="parent">
    <h1>我是父组件的标题-----{{parent_msg}}</h1>
    <h2>我来渲染子组件数据-----{{hehe}}</h2>
    <ul>
      <li>父组件列表1</li><li>父组件列表2</li><li>父组件列表3</li>
    </ul>
    <Child @child-event="parentShow"></Child>
  </div>
</template>

<script>
  import Child from "./Child";
  export default {
    components:{Child,},
    data(){
      return {
        parent_msg:"我是父组件数据",
        hehe:"",//data里定义变量
      }
    },
    methods:{
      parentShow(msg){
        console.log("父组件的驱动函数被触发,子组件数据是:",msg);
        this.hehe=msg;//把数据赋值给data里的变量,页面就可以使用了。
      }
    }
  }
</script>
<style scoped>#parent{border: 1px solid #e4393c;}</style>
//main.js
import Vue from 'vue'
import Hello from "./Hello";
new Vue({
  el: '#app',
  components:{
    Hello,
  },
  template:"<Hello/>"
})
//Hellow.vue
<template>
  <div id="hello">
    <h1>我是默认首页</h1>
    <parent></parent>
  </div>
</template>
<script>
  import Parent from "./components/Parent";
  export default {
    components:{Parent,}
  }
</script>
<style scoped></style>

总结:

  • 在子组件中找一个事件(例如:点击事件,鼠标移入移出事件),触发子组件的点击事件时,触发一段代码:在这里插入图片描述
  • 第一个参数1,自定义一个事件名称,第二个this.参数2, this.参数3后随便传参,this.参数就是给父组件传的数据,子组件传几个数据,父组件就用几个接收;
  • 下一步在父组件模板中,找到子组件标签,通过@绑定刚才在子组件this.$emit()中自定义的事件名称,等于= 一个事件驱动名称 :在这里插入图片描述
  • 父组件的函数,在methods里定义,用参数去接受,子组件的this.$emit的第二个往后的参数,参数就是子组件传来的数据:在这里插入图片描述

vue-resource在脚手架中的使用

拓展:在cmd中输入 npm install jQuery:就是下载jQ插件

在脚手架中如何使用 vue-resource

  1. cnpm/npm install vue-resource --save 在当前 vue脚手架的文件夹输入该命令--save是自动在package.json目录里登记一下);在这里插入图片描述以前我们原生开发 是用html的script:src引入一个js文件,现在我们下载的是一个文件夹模块 不能这样引入,需要在main.js里面通过 import语句引入
  2. 在main.js里面 写上 import VueResource from "vue-resource"
    在这里插入图片描述
  3. 再写一句代码: Vue.use(VueResource);在这里插入图片描述这句话就相当于 原来的 script:src="vue-resource.js"
  4. 这样全局的this就可以调用 this.$http.get/post
    全局表示以后所有组件都可以通过this.$http调用

总结:

form “vue-resoure”是因为node_modules依赖文件夹里面有vue-resoure这个模块,VueResource是引入的对象自定义名;
Vue.use(VueResource);构造函数.use是E6新语法,意思是加载这个模块

//main.js
import Vue from 'vue'
import Hello from "./Hello";
import VueResource from "vue-resource"
//让vue加载这个模块
Vue.use(VueResource);
new Vue({
  el: '#app',
  components:{Hello,},
  template:"<Hello/>"
})

axios在脚手架中的使用

第一种引入方式:

  1. cnpm/npm install vue-axios --save 下载vue-axios模块在这里插入图片描述
  2. cnpm/npm install axios --save 下载 axios模块在这里插入图片描述
  3. main.js里面引入
    import VueAxios from "vue-axios"
    import Axios from "axios"
    // 上面两句引入都要写
    
    在这里插入图片描述
  4. Vue.use(VueAxios,Axios);
    这句话相当于 Vue.prototype.axios=Axios;
  5. 然后全局就可以使用 this.axios({}) 方法进行交互了
    this.axios.get() this.axios.post() this.axios({})
    在这里插入图片描述

第二种引入方式:

  1. cnpm/npm install axios --save 下载axios模块

  2. 在main.js里面引入 axios模块

    import Axios from "axios"
    
  3. 全局绑定axios对象 ,(绑定的值是关键)

    Vue.prototype.$axios=Axios;
    

    $axios是自定义名字,全局就可以通过 this.$axios进行调用

路由的基本配置

在这里插入图片描述

什么是路由?路由概述

我们知道路由器的作用:分配地址,通过指定IP能够找到局域网内的指定电脑,路由器表面功能就是 用什么路径访问哪台电脑。

那我们由此可以理解,路由就是使用什么路径访问什么资源,路由其实就是一种导航手段,使用指定的路径去访问指定资源,这个路由和资源之间可以没有什么必然联系,通过后台代码路由的手段来联系到一起。

路由的基本配置

路由我们需要vue-router模块,我么使用vue-init命令初始化脚手架时,vue-router那一项我们选择y,所以我们现在默认自带vue-router模块。

配置路由的基本步骤:

  1. 在main.js里面 通过import语句引入vue-router模块;

  2. 在main.js 里面 Vue.use(VueRouter)

    import VueRouter form 'vue-router'
    Vue.use(VueRouter)
    
  3. 在main.js里面 去new 这个VueRouter对象,并用变量接收。

  4. 构造方法中需要传入一个opation对象,进行各项属性的配置。

    var myrouter=new VueRouter({ })
    
  5. VueRouter的属性配置(详见下)

  6. 路由对象的options配置完之后,需要把路由对象加载注册到当前Vue中,让当前vue对象具有路由的功能。

    var vm =new Vue({ router:myrouter(那个new出来的路由对象)})
    

    必须是router必须是new 出来的那个对象

  7. 我们需要定义 route-view标签,这个router-view标签就是 当前路由最终要显示的位置。

  8. 路由跳转需要通过按钮跳转
    路由官方给我们提供了一个</router-link> 标签,这个标签是专门用来跳转路由的,本质是a标签。
    <router-link to="路由的路径">文本</router-link> 这就是跳转路由。

总结

模块引入进来,保证下载过,接受变量,定义routes,配置 /名字,访问什么组件 每个对象都是路由对象,myrouter 在 new Vue里注册一下,键router 值myrouter,最后定义在首页定义</router-view>标签。

VueRouter 常用的属性有:

  1. mode 路径模式----两种
    (1)history(需要服务器配置对应环境才能使用)
    (2)hash s (默h认值 url路径上面自带 /#/)

  2. base 基本路径配置

  3. routes 是一个数组 进行每一个路由的配置,数组里面传的都是一个个对象,每一个对象都是一个路由配置对象的属性有
    (1)path:“路由路径”
    (2)name:“自己起一个名字”,name的值最好跟组件对象名字一样(潜规则)
    (3)component:对象的组件对象
    表示用什么路径显示什么组件,组件对象必须提前引入。

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

import VueRouter from "vue-router"
Vue.use(VueRouter);

import Home from "./components/Home";
import Teacher from "./components/Teacher";

var myrouter=new VueRouter({
  mode:"hash",//默认值hash
  // base:"itszt"  基本路径
  routes:[
    {
      path:"/home",
      name:""Home,
      component:Home
    },
    {
      path:"/teacher",
      name:"/Teacher",
      component:Teacher
    }
  ]
});
new Vue({
  el: '#app',
  router:myrouter,
  components: { App },
  template: '<App/>'
})

通过单独js文件配置路由的方式

在router文件夹里面创建路由的配置:

  1. router文件夹里面创建一个js文件

  2. js文件第一行引入指定模块

    import VueRouter from "vue-router"
    import Vue from "vue"
    
  3. new VueRouter进行配置

  4. router对象对外进行暴露

    export default router
    
  5. 在main.js文件,import router from "./router",把import 过来的router对象在 new Vue里面注册一下即可

//index.js
import VueRouter from "vue-router";
import Vue from "vue";
Vue.use(VueRouter);

import Home from "../components/Home";
import Teacher from "../components/Teacher";
import Student from "../components/Student"

var router=new VueRouter({
  routes:[
    {
      path:'/',
      name:'Home',
      component:Home
    },
    {
      path:'/teacher',
      name:'Teacher',
      component:Teacher
    },
    {
      path:'/student',
      name:'Student',
      component:Student
    },
  ]
});
export default router;
//main.js
import Vue from 'vue'
import App from './App'
//引入
import router from "./router" 

new Vue({
  el: '#app',
  router,//注册
  components: { App },
  template: '<App/>'
})

路由跳转的两种方式

1. router-link

通过<router-link to=" " id=" " @mousedown.native=" "></router-link>这个标签的to属性 关联路由的path进行跳转;该标签加载完后就是一个a标签
(1) 如果想要修改样式,那么直接给router-link添加class或者id 然后修改样式即可;
(2) 如果想要给这个标签添加事件,那么事件修饰符必须加上.native
(3) 如果觉得<router-link to="/" id=" " tag="li" @mousedown.native="函数名"></router-link>最终渲染出来的a标签不喜欢 想要换成别的标签
那么使用tag属性 tag="li" 最红渲染成li标签
在这里插入图片描述

//App.vue
<template>
  <div id="app">
    <h1> 我是默认首页</h1>
    <div>
      <h2>使用router-link标签跳转路由</h2>
      <router-link to="/">去首页</router-link>
      <router-link to="/teacher" tag="div" class="teacher">去教师页</router-link>
      <router-link to="/student" @click.native="showStudent">去学生页</router-link>
    </div>
    <p>
      <button @click="goHome">去首页</button>
      <button @click="goTeacher">去教室页</button>
      <button @click="goStudent">去学生页</button>
    </p>
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: 'App',
  methods:{
    showStudent(){alert("去学生页面干嘛?")},
    goHome(){this.$router.push("/")},
    goTeacher(){this.$router.replace("/teacher")},
    goStudent(){
      /*this.$router.push({path:"/student"})*/
      this.$router.push({name:"Student"})
    }
  }
}
</script>
<style>
  .teacher{text-decoration: none;}
  .teacher:hover{font-size: 25px;}
</style>

2. 通过js代码跳转路由(两种)

this.$router.push("路由的path路径");
this.$router.replace("路由的path路径")

push和replace的区别:

push 会把当前页面记录历史记录将来回退记录会有
replace 不会把当前页面存为历史记录 回退里面没有记录

//App.vue
<template>
  <div id="app">
    <h1> 我是默认首页</h1>
    <p>
      <button @click="goHome">去首页</button>
      <button @click="goTeacher">去教室页</button>
      <button @click="goStudent">去学生页</button>
    </p>
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: 'App',
  methods:{
    goHome(){this.$router.push("/")},
    goTeacher(){this.$router.replace("/teacher")},
    goStudent(){
      /*this.$router.push({path:"/student"})*/
      //通过路由的name方法跳转
      this.$router.push({name:"Student"});
    }
  }
}
</script>
<style></style>

push和replace变化写法

this.$router.push({
  path:"路由路的path路径"
})
this.$router.push({
  name:"路由的name值"
})

通过 name 或者 path 都可以匹配路由跳转;
replace写法一模一样!!! 区别就是不记录历史记录

子路由的配置:

所谓的子路由就是当前路由下面还继续有二级或者三级的路径
/home /detail 这都是一级路由
/home/haha , /detail/goods1 这就是二级路由 也是上面路由对应的子路由

子路由的配置步骤:

  1. 找到当前父路由对象 给父路由对象添加children属性
  2. 值是一个数组 数组里面要传入多个对象
  3. 每个对象都是当前父路由下面的子路由配置;
  4. 对象还是那三个属性 path name component
    子路由的router-view标签 应该是在当前父路由页面里面找个地方定义;

子路由如何配置默认显示的路由呢?

children:[
  {
    path:"跟父路由一样的path"
    不能定义name
    component:组件对象
  }
]

这样定义的子路由就是默认显示的路由

//index.js
import Vue from "vue"
import VueRouter from "vue-router"
Vue.use(VueRouter);

import Home from "../components/Home";
import Detail from "../components/Detail";
import Goods1 from "../components/Goods1";
import Goods2 from "../components/Goods2";
import Goods from "../components/Goods";

//解决当前路由已经显示 再次点击跳转当前路由报错问题
var originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

var router=new VueRouter({
  // mode:"history",
  routes:[
    {
      //配置默认的首页内容
      path:"/",
      name:"Home",
      component:Home
    },
    {
      path:"/detail",
      name:"Detail",
      component: Detail,
      children:[
        {
          //默认显示的子路由
          path:"/detail",
          component:Goods
        },
        {
          path:"/detail/goods1",
          name:"Goods1",
          component:Goods1
        },
        {
          path:"/detail/goods2",
          name:"Goods2",
          component:Goods2
        },
      ]
    }
  ]
})
export default router;

路由两次点击报错问题以及mode和base属性的使用

解决当前路由已经显示 再次点击跳转当前路由报错问题

const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

push方法等于一个函数,调用call(),把他的异常是系统默认报错抛出throw,我们把异常换成catch,捕获了。

路由的mode属性:

默认是hash 表面看路径里面自带 /#/不好看,history/#/ 好看一点。

但是以后学习打包项目 一旦使用了 history,那么打包完的项目 页面全是空白无法呈现 必须服务器做配置,然后把打包完的项目扔到做好配置的服务器里面访问才行,所以目前我们就用hash

base属性是要和history配合使用

history模式下,base属性里面定义的路径表示当前项目基础路径。

路由跳转时,路由传参的两种方式

1. path+query的方式传参

this.$router.push({
  path:"路由的path路径",
  query:{
    1:值1,
    2:值2,
  }
})

跳转到另一个路由以后 在另一个路由的 mounted(){ } 里面获取传过来的数据 this.$route.query 接收那个query对象,根据属性名获取属性值, this.$route.query.传过来的键

2.name+params的传参方式:

this.$router.push({
  name:"路由的name属性",
  params:{
    1:值1,
    2:值2
  }
})

跳转到另一个路由以后 在另一个路由的 mounted(){}里面 获取传过来的数据this.$route.params 接收那个params对象,根据属性名获取属性值,this.$route.params.传过来的键

补充:

replace跟push的用法一样!!!

path+queryname+params两种方式不能混用
比如: path+params是错误的!!!

这两种传参方式的区别:

path+query:

会在地址栏问号拼接传过去的参数, 页面刷新数据还在。

name+params:

不会在地址栏有显示,页面刷新数据就丢失 只会有一次机会, 以后学习vuex+session进行数据保留。

思考, router-link标签能否传参?

能! 但是实际开发基本不用 麻烦

格式:

<router-link :to="{name:"路由的name",params:{键:值}}"></router-link>
<router-link :to="{path:"路由的path",query:{键:值}}"></router-link>

动态路由的使用

什么是动态路由?

能够进行动态路径的匹配

举例说明:

如果我们的路由配置的是 /student,那么以后跳转时 只能根据 /student跳转,如果是/student/88 就无法跳转。

但是我们实际开发中有这样的需求:

员工/老师/学生 是一个单独的路由页面没有问题,
但是员工/老师/学生有很多,不能针对每一个人都配置一个路由页面,所以需要路由后面:拼接指定的ID变量来实现访问不同人的页面数据,页面结构还是那个页面 但是具体数据展现的是不同人的数据
所以动态路由就是在路由里面定义变量 可以通过多个符合变量格式的路由来匹配跳转,并且能够获取动态变量的数据。

配置动态步骤:

在路由对象的path里面定义变量

routes:[
  {
    path:"/studen/:变量名"
    name:"路由名字",
    comcponent:组件对象
  }
]

这个变量名自己随便写 将来 任何/student/值 的路由 都可以跳转到该路由,但是一旦定义了动态路由那么 /student 就无法直接访问了 必须拼接一个变量值。

//index.js
import Vue from "vue"
import VueRouter from "vue-router"
Vue.use(VueRouter);

import Home from "../components/Home";
import Teacher from "../components/Teacher";
import Student from "../components/Student";

//解决当前路由已经显示 再次点击跳转当前路由报错问题
var originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

var router=new VueRouter({
  routes:[
    {
      //配置默认的首页内容
      path:"/",
      name:"Home",
      component:Home
    },
    {
      path:"/teacher/:id",
      name:"Teacher",
      component:Teacher
    },
    {
      path:"/student/:id",
      name:"Student",
      component:Student
    },
  ]
})
export default router;

在这里插入图片描述

在动态路由的组件里面 mounted方法中 可以获取当前动态路由拼接的变量值this.$route.params获取 里面的键就是配置路由时定义的变量名,可以根据键获取动态路由拼接的值。

//Home.vue
<template>
  <div id="home">
    <h2>我是首页路由</h2>
    <ul>
       <li>我是首页路由内容1</li>
       <li>我是首页路由内容2</li>
       <li>我是首页路由内容3</li>
    </ul>
    <p><input type="text" placeholder="请输入ID" v-model="id"></p>
    <button @click="goTeacher">跳转到教师页</button>
    <button @click="goStudent">跳转到学生页</button>
</div>
</template>
<script>
  export default {
    name: "Home",
    data(){
      return{
        id:""
      }
    },
    methods:{
      goTeacher(){
        this.$router.push("/teacher/"+this.id)},
      goStudent(){
        this.$router.push("/student/"+this.id)}
    }
  }
</script>
<style scoped></style>
//Teacher.vue
<template>
  <div id="teacher">
    <h2>我是教师页面</h2>
    <h2>当前访问的教师ID:{{id}}</h2>
  </div>
</template>
<script>
  export default {
    name: "Teacher",
      data(){
        return{
          id:""
         }
      },
    mounted(){
      console.log("教师页动态路由为:",this.$route.params);
      this.id=this.$route.params.id;
    }
  }
</script>
<style scoped></style>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值