vue div滚动条滚动到指定位置_Vue.js从零开始——模块化项目(2)

ec3aaa2847744771d00261e19fe920e8.png

今天更新晚了点,因为刚刚去参加面试回来;不多说废话了,今天主要看的是路由,当然因为 Vue Router 本身已经可以写很多内容了,所以我倾向于把基础内容放在这里,路由单开一部分来详细看看。


1 简单路由

路由是什么呢?

在计算机领域,路由其实就是根据指定好的规则,将一类访问导向至规则对应的地址的动作。

所以网络设备当中有硬件的路由器(其实就是简化版本的计算机,搭配路由软件);而 Vue.js 的路由,允许我们通过不同的 URL 访问不同的内容,所以原理上是一致的。

如果我们只需要非常简单的路由而不想引入一个功能完整的路由库,可以像这样动态渲染一个页面级的组件:

const NotFound = { template: '<p>Page not found</p>' };
const Home = { template: '<p>home page</p>' };
const About = { template: '<p>about page</p>' };

const routes = {
  '/': Home,
  '/about': About
};

new Vue({
  el: '#app',
  data: {
    currentRoute: window.location.pathname
  },
  computed: {
    ViewComponent () {
      return routes[this.currentRoute] || NotFound;
    }
  },
  render (h) { return h(this.ViewComponent) };
});

结合 HTML5 History API,就可以建立一个麻雀虽小但是五脏俱全的客户端路由器。

官方提供了一个完整的例子:vue-simple-routing-example

2 第三方路由

如果在接触 Vue.js 之前已经使用习惯了某路由,也可以很容易的整合到 Vue 项目当中来,比如 Page.js 或者 Director 都是不错的选择,这里有个使用 Page.js 的范例:

main.js

import Vue from 'vue';
import page from 'page';
import routes from './routes';

const app = new Vue({
  el: '#app',
  data: {
    ViewComponent: { render: h => h('div', 'loading...') }
  },
  render (h) { return h(this.ViewComponent) };
});

Object.keys(routes).forEach(route => {
  const Component = require('./pages/' + routes[route] + '.vue');
  page(route, () => app.ViewComponent = Component);
});
page('*', () => app.ViewComponent = require('./pages/404.vue'));
page();

routes.js(简单的路由):

export default {
  '/': 'Home',
  '/about': 'About'
}

layouts/main.vue(路由主体):

<template>
  <div class="container">
    <ul>
      <li>
        <v-link href="/">Home</v-link>
        <v-link href="/about">About</v-link>
      </li>
    </ul>
    <slot></slot>
  </div>
</template>

<script>
  import VLink from '../components/VLink.vue';
  export default {
    components: {
      VLink
    }
  }
</script>

<style scoped>
  .container {
    max-width: 600px;
    margin: 0 auto;
    padding: 15px 30px;
    background: #f9f7f5;
  }
</style>

components/VLink.vue(链接组件):

<template>
  <a
    :href="href"
    :class="{ active: isActive }"
  >
    <slot></slot>
  </a>
</template>

<script>
  import routes from '../routes';
  export default {
    props: {
      href: String,
      required: true
    },
    computed: {
      isActive () {
        return this.href === window.location.pathname;
      }
    }
  }
</script>

<style scoped>
  .active {
    color: cornflowerblue;
  }
</style>

pages/Home.vue(首页):

<template>
  <main-layout>
    <p>Welcome home</p>
  </main-layout>
</template>

<script>
  import MainLayout from '../layouts/Main.vue';
  export default {
    components: {
      MainLayout
    }
  }
</script>

pages/About.vue(关于页面):

<template>
  <main-layout>
    <p>About page</p>
  </main-layout>
</template>

<script>
  import MainLayout from '../layouts/Main.vue'
  export default {
    components: {
      MainLayout
    }
  }
</script>

pages/404.vue(错误页面):

<template>
  <main-layout>
    <p>Page not found</p>
  </main-layout>
</template>

<script>
  import MainLayout from '../layouts/Main.vue';
  export default {
    components: {
      MainLayout
    }
  }
</script>

上面这些内容共同组成了这个简单的路由应用,效果如下:

f90ee8df4364897e7e5fab4805a3c0f3.gif

3 官方路由

先来一段官方介绍:

Vue RouterVue.js 官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

当然这个有点太官方,其实可以看成就是 Node.js 专门提供的一个路由组件,我们可以直接拿来用就好。

Vue.js + Vue Router 创建单页应用,是非常简单的,使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当要把 Vue Router 添加进来的时候,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 Vue Router 在哪里渲染它们。

下面是官方提供的例子:

HTML:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<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>

JavaScript

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 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');

通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

// Home.vue
export default {
  computed: {
    username() {
      // 我们很快就会看到 params 是什么
      return this.$route.params.username;
    }
  },
  methods: {
    goBack() {
      window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/');
    }
  }
}

该文档通篇都常使用 router 实例,不过需要留意一下 this.$routerrouter 使用起来完全一样,一般使用 this.$router 的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。

这里有个比较完整的例子(使用 CDN 并未使用模块化方式):

<!DOCTYPE html>
<html>
  <head>
    <title>hello</title>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vue-router"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <!-- router-link to属性就是指向某个具体的链接,
             链接的内容会被渲染到router-view标签中;
             router-link会被渲染成a标签,
             例如第一个会变成<a href="#/first">第一个页面</a>,前面加了个#
        -->
        <router-link to="/first">第1个页面</router-link>
        <router-link to="/second">第2个页面</router-link>
        <router-link to="/third">第3个页面</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script>
      /*
      * 申明三个模板
      */
      const first = {
        template: '<p>this is first page</p>'
      };
      const second = {
        template: '<p>this is second page</p>'
      };
      const third = {
        template: '<p>this is third page</p>'
      };
      /*
      * 定义路由,component属性是通过 Vue.extend() 创建的组件构造器,
      * 或者,只是一个组件配置对象
      */
      const routes = [{
          path: '/first',
          component: first
        },
        {
          path: '/second',
          component: second
        },
        {
          path: '/third',
          component: third
        }
      ];
      /*
      * 创建VueRouter实例
      */
      const router = new VueRouter({
        routes: routes
      });
      /*
      * 给vue对象绑定路由
      * .$mount("#app")手动挂载,用来延迟挂载,与
      *  const app = new Vue({
      *   el:"#app"
      *   router
      * });
      * 效果是一样的
      */
      const app = new Vue({
        router
      }).$mount("#app");
    </script>
  </body>
</html>

c49e08ac3f9d54f8aa9fb00237625a26.gif

要注意,当 <router-link> 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active,可以查看 API 文档 学习更多相关内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值