美文网首页程序员
使用 VueRouter 构建SPA单面应用DEMO

使用 VueRouter 构建SPA单面应用DEMO

作者: 坚果jimbowhy | 来源:发表于2018-09-17 05:37 被阅读0次

    H5页面使用 VueRouter 构建SPA单面应用DEMO

    VueRouter 实现原理

    一个页面地址由协议/主机名/页面地址/查询字符串/hash组成,如

    https://www.host.com/static/index.html?query=123#/user/110
    

    通过浏览器打印以下变量可知道

    location.href   "https://www.host.com/static/index.html?query=123#/user/110"
    location.search "?query=123"
    location.hash   "#/user/110"
    

    通过给 location.href 一个新地址,页面就会刷新跳到指定的地址上,这相当点击一个超链接进入新页面。但是,如果新地址只有hash这部分不同,其它都一样的情况就不同了。地址整体是有变化的,但页面不会刷新跳转。通过脚本可以检测到这种变化,那将这种变化以一定的规则和需要呈现的视图绑定,这就是VueRouter干的事。例如,点击这样一个VueRouter路由链接:

    <router-link to="/user/110">Go to User</router-link>
    

    浏览器地址栏就会改变hash部分:

    #/user/110
    

    DEMO 展示要点

    • VueRouter 的基本使用方法

    • 命名路由,在路由配置项中使用了 name 属性,如 {path: '/user/:userId', name: 'user', component: User }

    • 嵌套路由,通过 children 给路由配置子级路由项目

    • 重定向路由配置项 { path: '/a', redirect: '/b' } 或在 redirect 中使用命名路由 { name: 'foo' },或一个方法动态返回重定向目标的方法

    • 路由出口组件即生成视图路由结果的视图,<router-view></router-view>

    • 命名视图 <router-view name="specialView"></router-view>,不设置name属性,默认值为 default

    • 多视图路由配置 {path: '/', components: { default: Foo, specialView: User } }

    • <router-link> 路由组件会渲染成a标签,点击 <router-link :to="..."> 等同于调用 router.push(...)。

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

    • 编程式的导航

      router.go(n) 类似 window.history.go(n)。
      router.push(location, onComplete?, onAbort?)
      router.replace(location, onComplete?, onAbort?) 相当声明式 <router-link :to="..." replace>

      router.push('home') // 字符串
      router.push({ path: 'home' }) // 对象
      router.push({ name: 'user', params: { userId: 123 }}) // 命名的路由
      router.push({ path: 'register', query: { plan: 'private' }}) // 带查询参数,变成 /register?plan=private

    关于路由嵌套参考
    https://router.vuejs.org/zh/guide/essentials/nested-routes.html

        <script src="https://unpkg.com/vue/dist/vue.js"></script>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
        <style>
            .button { padding:2px; text-decoration: none; background:#00CAFF; border:1px solid #cccccc;}
            .button:hover {color:#fff;}
            .router-link-active {background:#FfBb00;}
        </style>
    
        <div id="app">
          <h1>Hello App!</h1>
          <p>
            <!-- 使用 router-link 组件来导航,它会被渲染成一个 `<a>` 标签,`to` 属性指定链接 -->
            <!-- IE天生天然残缺,不支持反引号,`/user/${id}/${name}`这样的模板字符串就不能使用了 -->
            <router-link class="button" to="/foo">Go to Foo</router-link>
            <router-link class="button" to="/bar">Go to Bar</router-link>
            <router-link class="button" :to="'/user/'+id+'/'+name">Go to User1 View</router-link>
            <router-link class="button" :to="'/user/112/Jimbo'">Go to User2 View</router-link>
            <button class="button" @click="goBack">Go Back</button>
            <span>Watching {{stamp}}</span>
          </p>
          <!-- 路由视图 路由出口 路由匹配到的组件将渲染在这里 -->
          <router-view></router-view>
          <!-- 命名视图 -->
          <router-view name="secondary"></router-view>
        </div>
    
        <script>
            // 1. 定义组件。组件也可以通过 Vue.extend() 创建或者是一个组件配置对象
            const Foo  = { template: '<div>foo view</div>' }
            const Bar  = { template: '<div>bar view</div>' }
            const User = { 
                template:'<div>' + // 因为组件模板只能有一个顶级元素所以这里要使用div包裹两个子元素
                        '   <div>Hello {{ $route.params.id }}</div>' +
                        '   <router-view></router-view>' + // 组件中使用路由视图用于渲染子路由匹配到的组件
                        '</div>',
                watch: {  // 添加 watch 方法对路由变化作出响应...
                    $route:function (to, from) { 
                        console.log("route change ",to," <= ",from);
                        this.name = to+" <= "+from;
                    }
                },
                beforeRouteEnter:function (to, from, next) { // to, from 都是 $route 实例
                    console.log("before route enter ", to, " <= ", from);
                    next();
                },
                beforeRouteUpdate:function (to, from, next) { // 2.2 中引入的导航守卫
                    // react to route changes...
                    // don't forget to call next()
                    console.log("before route update ", to, " <= ", from);
                    next();
                }
            }
    
            // 2. 配置组件的路由,每个路由应该映射一个组件
            const routes = [
                { path: '/foo', component: Foo },
                { path: '/bar', component: Bar, name:"toBar" }, // 设置 name 属性来配置一个命名路由
                { path: '/user/:id', component: User,  // 动态路径参数 以冒号开头
                    children:[ // 嵌套路由 子视图内容会渲染到 User 组件中的 <router-view></router-view>
                        { path:'', component:User }, // 子路由空路径时匹配上一级路由 /user/:id
                        { path:'jeango', component:Foo }, // 匹配 /user/:id/jeango
                        { path:'jimbo',  component:Bar }
                    ]
                }
            ]
    
            // 3. 以 `routes` 配置创建 router 实例,{ routes } 是ES6缩写,相当于 {routes: routes}
            const router = new VueRouter({ routes:routes })
    
            // 4. 创建vue实例和挂载根实例。启动应用!
            const app = new Vue({
                router:router,
                data:{name:"Jeango", id:110, stamp: + new Date()},
                watch: { // 监视参数变化
                    stamp:function () {
                        console.log('watching', this.$route);
                        return this.$route.params.name
                    }
                },
                methods: {
                    goBack:function () {
                        this.stamp = +new Date(); // 更新相间数据触发watch事件
                        window.history.length > 1
                        ? this.$router.go(-1)
                        : this.$router.push('/')
                    }
                }
            }).$mount('#app')
    
        </script>
    
    

    相关文章

      网友评论

        本文标题:使用 VueRouter 构建SPA单面应用DEMO

        本文链接:https://www.haomeiwen.com/subject/llsogftx.html