• 路由 — Vue.js


    1.官方路由

    对于大多数单页面应用,都推荐使用官方支持的 vue-router 库。

    1.1 入门

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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="/foo">Go to Foo</router-link>
    				<router-link to="/bar">Go to Bar</router-link>
    			</p>
    			<router-view></router-view>
    		</div>
            <script>
    			const Foo = { template: '<div>foo</div>' }
    			const Bar = { template: '<div>bar</div>' }
    
    			const routes = [
    			  { path: '/foo', component: Foo },
    			  { path: '/bar', component: Bar }
    			]
    
    			const router = new VueRouter({
    			  routes
    			})
    
    			const app = new Vue({
    			  router
    			}).$mount('#app')
            </script>
        </body>
    </html>
    

    注意:如果组件包含install方法,使用该组件时需要通过Vue.use(...)显式声明。这里没有使用Vue.use(...),显然是跟引入的库的版本有关。

    1.2 动态路由匹配

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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="/user/1">用户1</router-link>
    				<router-link to="/user/2">用户2</router-link>
    			</p>
    			<router-view></router-view>
    		</div>
            <script>			
    			const User = {
    			  template: '<div>User {{ $route.params.id }}</div>'
    			}		
    
    			const router = new VueRouter({
    			  routes: [
    				{path: '/user/:id', component: User}
    			  ]
    			})
    
    			const app = new Vue({
    			  el: '#app',
    			  router
    			})
            </script>
        </body>
    </html>
    

    注意到/user/:id:id是动态的部分,我们通过$route.params可以访问到这些动态的内容。

    下面监听组件参数的变化。

    const User = {
      template: '<div>User {{ $route.params.id }}</div>',
      watch: {
    	$route: function(to, from){
    		console.log(to, from);
    	}
      }			  
    }
    /*
    const User = {
      template: '<div>User {{ $route.params.id }}</div>',			  
      beforeRouteUpdate (to, from, next) {
    	console.log(to, from);
      }
    }
    */
    

    1.3 嵌套路由

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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="/user/foo">/user/foo</router-link>
    				<router-link to="/user/foo/profile">/user/foo/profile</router-link>
    				<router-link to="/user/foo/posts">/user/foo/posts</router-link>
    			</p>
    			<router-view></router-view>
    		</div>
            <script>			
    			const User = {
    			  template: `
    				<div class="user">
    				  <h2>User {{ $route.params.id }}</h2>
    				  <router-view></router-view>
    				</div>
    			  `
    			}
    			
    			const UserHome = { template: '<div>Home</div>' }
    			const UserProfile = { template: '<div>Profile</div>' }
    			const UserPosts = { template: '<div>Posts</div>' }
    
    			const router = new VueRouter({
    			  routes: [
    				{path: '/user/:id', component: User,
    				 children: [
    					{ path: '', component: UserHome },
    					{
    						path: 'profile',
    						component: UserProfile
    					},
    					{
    						path: 'posts',
    						component: UserPosts
    					}
    				 ]}
    			  ]
    			})
    
    			const app = new Vue({
    			  el: '#app',
    			  router
    			})
            </script>
        </body>
    </html>
    

    1.4 编程式导航

    1.4.1 router.push(location, onComplete, onAbort)

    <router-link :to="...">等价于router.push(...)

    router.push('home')
    // /register?plan=private
    router.push({ path: 'register', query: { plan: 'private' } })
    
    const userId = '123'
    router.push({ name: 'user', params: { userId } }) // -> /user/123
    router.push({ path: `/user/${userId}` }) // -> /user/123
    // This will NOT work
    router.push({ path: '/user', params: { userId } }) // -> /user
    

    1.4.2 router.replace(location, onComplete, onAbort)

    <router-link :to="..." replace>等价于router.replace(...)

    看一个例子。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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>
    				<button @click="pushShow('/user/foo')">/user/foo</button>
    				<button @click="pushShow('/user/foo/profile')">/user/foo/profile</button>
    				<button @click="pushShow('/user/foo/posts')">/user/foo/posts</button>
    				<!-- 
    				<button @click="replaceShow('/user/foo')">/user/foo</button>
    				<button @click="replaceShow('/user/foo/profile')">/user/foo/profile</button>
    				<button @click="replaceShow('/user/foo/posts')">/user/foo/posts</button>
    				-->
    				
    				<!-- <button @click="$router.back()">回退</button> -->
    				<button @click="goBack()">回退</button>
    				<!--
    				<router-link to="/user/foo">/user/foo</router-link>
    				<router-link to="/user/foo/profile">/user/foo/profile</router-link>
    				<router-link to="/user/foo/posts">/user/foo/posts</router-link>
    				-->
    			</p>
    			<router-view></router-view>
    		</div>
            <script>
    			const User = {
    			  template: `
    				<div class="user">
    				  <h2>User {{ $route.params.id }}</h2>
    				  <router-view></router-view>
    				</div>
    			  `
    			}
    			
    			const UserHome = { template: '<div>Home</div>' }
    			const UserProfile = { template: '<div>Profile</div>' }
    			const UserPosts = { template: '<div>Posts</div>' }
    
    			const router = new VueRouter({
    			  routes: [
    				{path: '/user/:id', component: User,
    				 children: [
    					{ path: '', component: UserHome },
    					{
    						path: 'profile',
    						component: UserProfile
    					},
    					{
    						path: 'posts',
    						component: UserPosts
    					}
    				 ]}
    			  ]
    			})
    
    			const app = new Vue({
    			  el: '#app',
    			  router,
    			  methods: {
    				pushShow (id) {
    					if(id){
    						this.$router.push(id);
    					}
    				},
    				replaceShow (id) {
    					if(id){
    						this.$router.replace(id);
    					}
    				},
    				goBack () {
    					window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
    				}
    			  }
    			})
            </script>
        </body>
    </html>
    

    1.5 命名路由

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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>
    				<!--
    				<button @click="pushShow({path: '/user/foo'})">/user/foo</button>
    				<button @click="pushShow({path: '/user/foo/profile'})">/user/foo/profile</button>
    				<button @click="pushShow({path: '/user/foo/posts'})">/user/foo/posts</button>
    				-->
    				<!-- 
    				<button @click="pushShow({name: 'user', params: {id: 'foo'}})">/user/foo</button>
    				<button @click="pushShow({name: 'uProfile', params: {id: 'foo'}})">/user/foo/profile</button>
    				<button @click="pushShow({name: 'uPosts', params: {id: 'foo'}})">/user/foo/posts</button>
    				-->
    				<router-link :to="{name: 'user', params: {id: 'foo'}}">/user/foo</router-link>
    				<router-link :to="{name: 'uProfile', params: {id: 'foo'}}">/user/foo/profile</router-link>
    				<router-link :to="{name: 'uPosts', params: {id: 'foo'}}">/user/foo/posts</router-link>
    			</p>
    			<router-view></router-view>
    		</div>
            <script>
    			const User = {
    			  template: `
    				<div class="user">
    				  <h2>User {{ $route.params.id }}</h2>
    				  <router-view></router-view>
    				</div>
    			  `
    			}
    			
    			const UserHome = { template: '<div>Home</div>' }
    			const UserProfile = { template: '<div>Profile</div>' }
    			const UserPosts = { template: '<div>Posts</div>' }
    
    			const router = new VueRouter({
    			  routes: [
    				{path: '/user/:id', name: 'user', component: User,
    				 children: [
    					{ path: '', component: UserHome },
    					{
    						path: 'profile',
    						name: 'uProfile',
    						component: UserProfile
    					},
    					{
    						path: 'posts',
    						name: 'uPosts',
    						component: UserPosts
    					}
    				 ]}
    			  ]
    			})
    
    			const app = new Vue({
    			  el: '#app',
    			  router,
    			  methods: {
    				pushShow (id) {
    					if(id){
    						this.$router.push(id);
    					}
    				}
    			  }
    			})
            </script>
        </body>
    </html>
    

    注意:如果父路由带动态参数,子路由就需要传params,比如<router-link :to="{name: 'uProfile', params: {id: 'foo'}}">

    1.6 命名视图

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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="/foo">Foo</router-link>
    				<router-link to="/other">Other</router-link>
    			</p>
    			<router-view></router-view>
    			<router-view name="a"></router-view>
    			<router-view name="b"></router-view>
    		</div>
            <script>			
    			const Foo = { template: '<div>Foo</div>' }
    			const Bar = { template: '<div>Bar</div>' }
    			const Baz = { template: '<div>Baz</div>' }
    
    			const router = new VueRouter({
    			  routes: [
    				{
    					path: '/foo',
    					components: {
    						default: Foo,
    						a: Bar,
    						b: Baz
    					}
    				},
    				{
    					path: '/other',
    					components: {
    						default: Baz,
    						a: Bar,
    						b: Foo
    					}
    				}
    			  ]
    			})
    
    			const app = new Vue({
    			  el: '#app',
    			  router
    			})
            </script>
        </body>
    </html>
    

    1.6.1 嵌套命名视图

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
    			.router-link-active {
    			  color: red;
    			}
            </style>
    		<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>
    			<router-view></router-view>
    		</div>
            <script>
    			const FooSettings = {
    				template: `<div><router-link to="/foo/bar">Bar</router-link>  <router-link to="/foo/baz">Baz</router-link></div>`
    			}
    			const Foo = {
    				template: `<div>Foo
    				<div><FooSettings/></div>
    				<router-view></router-view><router-view name="helper"></router-view></div>`,
    				components: { FooSettings }
    			}
    			const Bar = { template: '<div>Bar</div>' }
    			const Baz = { template: '<div>Baz</div>' }
    			const Baz1 = { template: '<div>Baz1</div>' }
    
    			const router = new VueRouter({
    			  routes: [
    				{
    					path: '/foo',
    					component: Foo,
    					children: [{
    						path: 'bar',
    						component: Bar
    					}, {
    						path: 'baz',
    						components: {
    							default: Baz,
    							helper: Baz1
    						}
    					}]
    				}
    			  ]
    			})
    			
    			router.push('/foo/bar')
    
    			const app = new Vue({
    			  el: '#app',
    			  router
    			})
            </script>
        </body>
    </html>
    

    1.7 重定向和别名

    1.1 入门的例子中,我们可以把路由改为:

    const routes = [
      { path: '', redirect: '/bar' },			  
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    ]
    

    这样页面就会重定向到路由/bar
    我们也可以在重定向中使用命名路由。

    const routes = [
      { path: '', redirect: {name: 'foo'} },			  
      { path: '/foo', component: Foo, name: 'foo' },
      { path: '/bar', component: Bar, name: 'bar' }
    ]
    

    通过alias我们可以给路由起别名。重定向路由访问地址会发生改变,而路由别名意味着访问地址不会发生改变,但是使用pathalias声明的路由访问的是同一个东西。

    const routes = [			  
      { path: '/foo', component: Foo, alias: '/abc' },
      { path: '/bar', component: Bar, alias: '/def' }
    ]
    

    提示:这里alias我没有试成功,不知道是不是 vue-router 版本的问题。

    1.8 传递props到路由组件

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
                .router-link-active {
                  color: red;
                }
            </style>
            <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="/foo/123">Go to Foo</router-link>
                </p>
                <router-view></router-view>
            </div>
            <script>
                const Foo = { template: '<div>foo {{ $route.params.id }}</div>' }
    
                const routes = [
                  { path: '/foo/:id', component: Foo }
                ]
    
                const router = new VueRouter({
                  routes
                })
    
                const app = new Vue({
                  router
                }).$mount('#app')
            </script>
        </body>
    </html>
    

    为了解耦组件和路由器,我们可以把JS改写成:

    const Foo = { props: ['id'], template: '<div>foo {{ id }}</div>' }
    
    const routes = [
      { path: '/foo/:id', component: Foo, props: true }
    ]
    
    const router = new VueRouter({
      routes
    })
    
    const app = new Vue({
      router
    }).$mount('#app')
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">      
            <style>
                .router-link-active {
                  color: red;
                }
            </style>
            <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="/foo">Go to Foo</router-link>
    				<router-link to="/dynamic/2">DynamicPropsFunction</router-link>
                </p>
                <router-view></router-view>
            </div>
            <script>
    			function dynamicPropsFn (route) {
    			  const now = new Date()
    			  return {
    				name: (now.getFullYear() + parseInt(route.params.years)) + '!'
    			  }
    			}
    			
    			const Foo = { props: { name: {type: String, default: 'Vue!'} }, template: '<div>foo {{ name }}</div>' }
    
    			const routes = [
    			  { path: '/foo', component: Foo, props: {name: 'bar'} },
    			  { path: '/dynamic/:years', component: Foo, props: dynamicPropsFn }
    			]
    
    			const router = new VueRouter({
    			  routes
    			})
    
    			const app = new Vue({
    			  router
    			}).$mount('#app')
            </script>
        </body>
    </html>
    

    路由中的props可以设置为布尔值、对象甚至是函数。

    参考:

  • 相关阅读:
    JS——ajax login test
    Java——Java日期转Sql日期
    JDK动态代理实现原理
    Java 动态代理机制分析及扩展,第 1 部分
    Java枚举类
    Java强引用、 软引用、 弱引用、虚引用
    取模运算
    java集合框架
    字节和unicode
    编译原理随笔
  • 原文地址:https://www.cnblogs.com/gzhjj/p/11832913.html
Copyright © 2020-2023  润新知