8、Vue_组件声明、路由以及嵌套路由

组件声明

  • /src/main.js声明全局组件
// 1.导入子组件
import HelloWorld from './components/HelloWorld'
// 2.创建全局组件
Vue.component('hello-world',  HelloWorld);
// 3.使用:在App.vue中直接使用<hello-world/>
  • 子父组件之间的互相调用
    App.vue
<template>
    <HelloWorldmsg="满身泥的猪儿" :title="title"></HelloWorld>
</template>

<script>
    import HelloWorld from './components/HelloWorld.vue'

    export default {
        // 定义当前组件名称
        name:'app',
        components:{
        //声明子组件    
               HelloWorld,
        },
        data() {
            return {
                title: '测试游记'
           }
        }
 }
</script>

HelloWord.vue

<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
        <h2>{{ title }}</h2>
    </div>
</template>
<script>
    export default {
        name: 'HelloWorld',
        props: {
         //从父组件获取msg
            msg: String,
            title: Number,
        }
    }
</script>

路由

一、常见应用场景
  • 需求一:后台系统最常见的,就是点击左边的导航栏的页面1,右边就会显示页面1的内容,然后刷新的话,页面依旧停留在页面1,而不是跳到默认首页去。
  • 需求二:一个页面中,有几个不同的画面来回点击进行切换
二、准备工作

Vue.js的路由模块是vue-route

实例
1、不使用Vue的组件/模块化机制使用路由(例子直接copy的菜鸟教程,很完整了)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script>
</head>
<body>
<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

<script>
// 1. 定义(路由)组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写)相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

// 现在,应用已经启动了!
</script>
</body>
</html>
2、使用Vue的组件/模块化机制进行编程(重点)
  • 在src目录下创建/router/index.js,内容如下:
// 使用模块化机制进行编程

// 1.导入vue;安装并导入vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'

// 2.使用组件
Vue.use(VueRouter);

// 3.定义路由组件
// 导入组件(这里使用之前创建过的vue组件进行演示)
import One from '../components/one'
import HelloWorld from '../components/HelloWorld'
import Vfor from '../components/v-for'


// 4.创建路由
const router = new VueRouter(
    {
        mode: 'history',
        // 4.1.定义路由数组
        routes: [
            // 每个路由映射一个组件,
            // path:组件的映射链接
            // component:可以是Vue组件,也可以是一个组件配置对象
            // name:路由的名称,调用的时候可直接写名字即可
            {path: '/first', component: HelloWorld, name:"first"},
            {path: "/second", component: One, name:"one"},
            {path: "/third", component: Vfor},
        ]
    }
);

// 5.导出路由
export default router
  • 修改/src/main.js的内容:
import Vue from 'vue'
import App from './App.vue'

// 6.导入 vue router对象,注意import的名字要和index.js中导出路由中export default的名字一样,否则找不到
import router from './router/index'


new Vue({
  router, // 7.调用router
  render: h => h(App), //渲染App根组件
}).$mount('#app')
  • 在/src/components创建一个r-route.vue(此步骤可以直接在APP.vue添加内容也可以,只是不想APP.vue太多内容才这样写)
<template>
    <div>
    <!--
       8.使用router-link组件进行导航
to属性:指向一个具体的链接,链接的内容会被渲染到router-view标签
router-link:会被渲染成a标签,比如:<a href="#/first">
    -->
    <ul>
        <router-link to="/first">首页</router-link><br>
         <!-- component:这里使用路由对应的name来调用 -->
        <router-link to="{name:'one'}">One页</router-link><br>
        <router-link to="/third">Vfor页</router-link>
    </ul>
    </div>
</template>

<script>
    export default {
        name: "r-router"
    }
</script>

<style scoped>

</style>
  • 在/src/APP.vue配置路由出口,以及使用上面创建的r-route.vue组件

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="满身泥的猪儿"/>
    <!-- 使用组件 -->
    <Vrouter></Vrouter>
    <!-- 9.路由出口:路由匹配到的组件将渲染到这里 -->
    <router-view></router-view>
  </div>
</template>



<script>
import HelloWorld from "@/components/HelloWorld.vue";
// 使用组件,导入组件
import Vrouter from '@/components/r-router'

export default {

  name: 'app',
  components: {
    HelloWorld,
    // 使用组件
    Vrouter
  }
}
</script>

<!-- 样式渲染 -->
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

结果:刷新也会停留在当前页面


点击One页

点击Vfor页

三、重定向

在定义routes数组时,可以指定页面的重定向链接。

  • 比如,当打开配置了路由的页面时,自动跳转到/first页面:
{ path: '/', redirect: '/first'},
四、<router-link>标签一些属性介绍(来源菜鸟教程)

1.to

  • 表示目标路由的链接。 当所在的 <router-link>被点击后,内部会立刻把to的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>

<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

2.replace

  • 设置了replace属性后,当所在的 <router-link>被点击后,会调用 router.replace()而不是router.push(),导航后不会留下 历史记录。
<router-link :to="{ path: '/abc'}" replace></router-link>

3.append

  • 设置append属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a导航到一个相对路径 b,如果没有配置append,则路径为/b,如果配了,则为/a/b
<router-link :to="{ path: 'relative/path'}" append></router-link>

4.tag

  • 有时候想要把<router-link>渲染成指定标签,例如<li>。 于是我们使用tag prop类指定何种标签,同样它还是会监听点击事件,然后触发导航。
<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

5.active-calss

  • 设置<router-link>的链接被激活时使用的 CSS 类名。可以通过以下代码来替代。
<style>
   ._active{
      background-color : red;
   }
</style>
<p>
   <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

注意这里class使用active_class="_active"

6.exact-active-class

  • 配置当<router-link>的链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代
<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

7.event

  • 配置可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。
<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

以上代码设置了eventmouseover,那么当鼠标移动到Router Link 1上时导航的HTML内容会发生改变。

五、获取路由路径中的查询字符串参数

查询字符串参数例子:http://127.0.0.1/input?name=xx&age=18中的nameage就是查询字符串参数。
在组件当中可以使用this.$route.query获取到[name:xx,age:xx],可以通过this.$route.query.name获取到name的值
1、one.vue

<template>
    <div id="one">
        我是one.vue的查询参数:{{ search }}
        我是one.vue的路径参数:{{ message }}
        <p />
        <p1>
            {{ rdata }}
        </p1>
    </div>
</template>

<script>
    export default {
        'name': 'one',
        props: {
            'rdata': String
        },
        data() {
            return {
                <!-- 获取查询字符串参数中的name参数的值 -->
                search: this.$route.query.name,
                message: this.$route.params.id
            }
        },
    }
</script>

<style>
</style>
示例
六、获取路由路径中的路径参数

路径参数例子:http://127.0.0.1/input/100中的100就是路径参数
1、定义包含路径参数的路由router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

import One from '../components/one.vue'
import HelloWorld from '../components/HelloWorld.vue'
import elelogin from '../components/elelogin.vue'


const router = new VueRouter(
    {
        mode: 'history',
        routes: [
            {path: '/first', component: HelloWorld, name:"firstname"},
             //定义路径路由,格式是 xxx/:字段名
            {path: "/second/:id", component: One},
            {path: "/third", component: elelogin}
        ]
    }
);

2、one.vue的内容如步骤五:在组件当中可以使用this.$route.params获取到路径参数的key-value,可以通过this.$route.query.id获取到id的值100

<template>
    <div id="one">
        我是one.vue的查询参数:{{ search }}
        我是one.vue的路径参数:{{ message }}
        <p />
        <p1>
            {{ rdata }}
        </p1>
    </div>
</template>

<script>
    export default {
        'name': 'one',
        props: {
            'rdata': String
        },
        data() {
            return {
                search: this.$route.query.name,
                <!-- 获取路径参数中的id参数的值 -->
                message: this.$route.params.id
            }
        },
    }
</script>

<style>
</style>
示例
七、嵌套路由

在一个路由下,可以定义多个子路由。当访问子路由路径时,会先加载主路由内容,再加载子路由。可用于多个子页面有自己的子导航栏,但是拥有同一个主导航栏这种场景(还有更多)
语法和例子:
1.修改之前的route/index.js,具体语法看代码

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);

import p from '../components/proute.vue'
import c from '../components/croute.vue'
import n from '../components/nroute.vue'

const router = new VueRouter(
    {
        mode: 'history',
        routes: [
            {path:'/p', component: p,
                 //children:子路由,列表
                children:[
                    {
                         //路径中带/
                        path:'/c', component: c
                    },
                    {
                         //路径中不带/
                        path:'c', component:n
                    }
                ]
            }
        ]
    }
);

// 5.导出路由
export default router
  • 新创建三个路由vue文件,内容如下:
    1.主路由界面proute.vue
<template>
    <div>
        <p>我是主路由的内容</p>
         <!-- 加载路由视图,否则子路由内容不会显示-->
        <router-view></router-view>
    </div>

</template>

<script>
</script>

<style>
</style>

2.子路由界面1,对应path不带/的页面:nroute.vue

<template>
    <div>
            <p>我是不带/路径的子路由的内容</p>
        
    </div>
    
</template>

<script>
</script>

<style>
</style>

3.子路由界面2,对应path/的页面:croute.vue

<template>
    <div>
            <p>我是带/路径的子路由的内容</p>
        
    </div>

</template>

<script>
</script>

<style>
</style>

2.访问完整的子路由路径http://localhost:8080/p/chttp://localhost:8080/p/c/,页面显示的是不带/路径的子路由的内容

http://localhost:8080/p/c

3.访问只有子路由路径的路径http://localhost:8080/c

http://localhost:8080/c
  • 再创建一个对应空路径子路由的情况
    4.nullroute.vue
<template>
    <div>
        <p>我是空路径子路由的内容</p>
        <router-view></router-view>
    </div>
</template>

<script>
</script>

<style>
</style>

5.修改route/index.js,增加一个空路径的子路由

            {path:'/p', component: p,
                children:[
                    {
                        path:'/c', component: c
                    },
                    {
                        path:'c', component:n
                    },
                    {
                        path:"", component:nu
                    }
                ]
            }

6.访问主路由路径http://localhost:8080/p
PS.如果主路由下有空路径的子路由,那么访问主路由时,也会把该空路径的子路由的内容给加载出来

http://localhost:8080/p

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容