最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue学习-路由router

    正文概述 掘金(梳碧湖里砍柴人)   2021-06-30   584

    Vue学习-路由router

    认识路由

    什么是前端渲染,什么是后端渲染?

    后端渲染阶段

    后端渲染: JSP - java server page

    后台收到请求之后,html+css+java, java代码作用是从数据库中读取数据,并将它动态的放在页面中,页面在服务器端已经渲染好了,然后直接渲染好的页面返回给前端(html+css)

    后端路由:后台处理URL和页面之间的映射关系

    后端路由的缺点:

    • 整个页面的模块由后端人员来编写和维护的
    • 前端开发人员如果开发页面,需要通过php,Java等语言来编写页面代码
    • 通常情况下HTML代码和数据以及对应的逻辑会混在一起,编写和维护都是非常糟糕的事情

    前后端分离阶段

    Vue学习-路由router

    输入jd.com,先去静态资源浏览器请求静态资源(html+css+js),当浏览器引擎执行JS代码时,会触发API请求,会去后台的API服务器上请求数据。

    前端渲染:浏览器中显示的网页中的大部分内容,都是由前端写的JS代码,在浏览器中执行,最终渲染出来的网页。

    • 随着Ajax的出现,由了前后端分离的开发模式
    • 后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JS将数据渲染到页面中
    • 这样做最大的优点就是前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化上
    • 并且当移动端出现后,后端不需要进行任何处理,依然使用之前的一套API即可

    前端路由阶段(单页面富应用阶段)

    前后端分离的基础之上,加上前端路由

    SPA应用:整个网站只有一个HTML页面,一套html+css+js

    前端路由:页面与静态资源的映射关系由前端来管理,改变URL,页面不会整体刷新

    url的hash和HTML5的history

    URL中的hash

    • URL中的hash也就是锚点(#),本质上是改变window.location的href属性
    • 可以通过直接赋值location.hash来改变href,但是页面不会发生刷新
    • location.hash = 'aaa'

    HTML5中的history

    • history.pushState({}, '', 'home') 压入
    • history.replaceState({}, '', 'home') 替换
    • replace不能返回之前的页面(替换了), push可以返回到之前的页面
    • history.go() 参数: -1: history.back() 1: history.forward()

    Vue-router基本使用

    安装vue-router

    npm install vue-router --save
    

    在模块化工程中使用vue-router(插件,可以用过Vue.use()来使用路由功能)

    • 导入路由对象,并且调用Vue.use(VueRouter)
    • 创建路由实例,并且传入路由映射配置
    • Vue实例中挂载创建的路由实例

    框架搭建

    import Vue from 'vue'
    // 导入路由对象,并且调用Vue.use(VueRouter)
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    
    Vue.use(VueRouter)
    
    // 创建路由实例,并且传入路由映射配置
    const routes = [
        {
            path: '/',
            name: 'Home',
            component: Home
        },
        {
            path: '/about',
            name: 'About',
            // route level code-splitting
            // this generates a separate chunk (about.[hash].js) for this route
            // which is lazy-loaded when the route is visited.
            component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
        }
    ]
    
    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
    })
    
    // 先导出,然后在main.js中,Vue实例中挂载创建的路由实例
    export default router
    
    

    配置路由

    • 创建路由组件
    • 配置路由映射:组件和路径映射关系
    • 使用路由:通过和
    {
        path: '/',
            name: 'Home',
                component: Home
    },
        {
            path: '/about',
                name: 'About',
                    // route level code-splitting
                    // this generates a separate chunk (about.[hash].js) for this route
                    // which is lazy-loaded when the route is visited.
                    // 路由懒加载
                    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
        }
    
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view>
    

    路由的默认值和修改为history模式

    路由的默认值

    { path: '/', redirect: 'home' }
    

    history模式

    mode: history

    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
    })
    

    router-link的其他属性

    tag属性

    默认渲染为a标签,想要渲染为其他元素,使用tag属性

    <router-link to="/home" tag="button">首页</router-link>
    <router-link to="/about" tag="button">关于</router-link>
    

    replace属性

    默认使用pushState,如果想使用replaceState,使用replace属性

    <router-link to="/home" tag="button" replace>首页</router-link>
    <router-link to="/about" tag="button" replace>关于</router-link>
    

    .router-link-active

    选中的router-link会自动具有.router-link-active类,可以直接通过该类设置样式,比如选中的字体变为红色

    .router-link-active {
    	color: red;
    }
    

    .router-link-active简写模式

    <router-link to="/home" tag="button" replace active-class="acive">首页</router-link>
    <router-link to="/about" tag="button" replace active-class="acive">关于</router-link>
    
    .active {
    	color: red;
    }
    

    统一修改active-class

    const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes,
        linkActiveClass: 'active'
    })
    

    通过代码跳转路由

    this.$router.push('/home');
    
    this.$router.replace('/home')
    

    动态路由

    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link to="/user/zhangsan">用户</router-link>
    <router-link :to="'/user/' + userId">用户</router-link>
    
    { path: '/user/:userId', component: User }
    

    或者

    this.$router.push('/user/' + this.userId)
    

    User.vue中获取到userId

    {{ $route.params.userId }}
    或者
    this.$route.params.userId
    // $route: 处于活跃中的路由
    // $router: 整个路由对象
    

    路由的懒加载

    • 当打包构建应用时,Javascript包会变得非常大,影响页面加载

    • 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样跟高效(一个路由打包一个JS文件)

    • 懒加载:用到的时候再加载

    // 推荐的方式
    const routes = [
    	{ path: '/home', component: () => import('../components/Home') },
        { path: '/about', component: () => import('../components/About') }
    ]
    

    或者

    const About = resolve => require(['../components/About.vue'], resolve);
    

    Vue-router嵌套路由

    认识路由嵌套

    • 比如在home页面中,我们希望通过/home/news和/home/message访问一些内容
    • 一个路径映射一个组件,访问这两个路径也会分别渲染两个组件

    创建嵌套路由的步骤

    • 创建对应的子组件,并且在路由映射中配置对应的子路由
    • 在组件内部使用标签
    { path:  '/home', component: Home, children: [
        { path: 'news', component: HomeNews },
        { path: 'message', component: HomeMessage },
        { path: '/', redirect: 'news' }
    ] }
    
    <router-link to="/home/news">新闻</router-link>
    <router-link to="/home/message">消息</router-link>
    

    Vue-router参数传递

    从一个页面跳转到另一个页面,希望传递一些消息

    方法1: 动态路由中讲到的方法可以传递参数

    • 配置路由格式: /router/:id
    • 传递的方式: 在path后面跟上对应的值
    • 传递后形成的路径: /route/123, /route/abc

    方法2: query方式

    • 配置路由格式:/router,也就是普通配置
    • 传递的方式:对象中使用query的key作为传递方式
    • 传递后形成的路径: /router?id=123 , /router?id=abc
    <router-link :to="{ path: '/profile', query: { name: 'xx', age: 18, height: 1.88 } }"></router-link>
    

    或者

    this.$router.push({
    	path: '/profile',
        query: {
            name: 'xx',
            age: 18,
            height: 1.88
        }
    })
    
    {{ $route.query.name }}
    或者
    this.$route.query.name
    

    Vue-router: router和route的由来

    所有组件(.vue)都继承着vue的原型,vue原型上又挂载了routergrouterg和routerg和route

    Vue.prototype.$router = {
    	...
    }
    Vue.prototype.$route = {
        ...
    }
    或者
    Object.defineProperty(Vue.prototype, '$router', ...);
    Object.defineProperty(Vue.prototype, '$route', ...);
    

    this.$router就是vueRouter类的一个实例

    this.$route是处于活跃的路由

    Vue-router导航守卫

    需求:

    在一个SPA应用中,如何改变网页的标题?

    • 网页标题是通过<title>来显示的,但是SPA只有一个固定的HTML,切换不同的页面时,标题并不会改变
    • 可以通过Javascript来修改<title>的内容,window.document.
    • 那么在VUE项目中,如何实现?

    方案1: 利用生命周期函数created实现

    方案2:利用全局导航守卫 (前置钩子,前置守卫)

    router.beforeEach((to, from, next) => {
    	// 从from跳转到to
    	document.title = to.matched[0].meta.title;
        next();
    })
    
    { path: '/home', component: Home, meta: { title: '首页' } }
    

    后置钩子:

    afterEach, 已经跳转完了

    router.afterEach((to, from) => {
    	
    })
    

    路由独享守卫

    const router = new VueRouter({
    	routes: [{
            path: '/foo',
            component: Foo,
            beforeEnter: (to, from, next) => {
                
            }
        }]
    })
    

    keep-alive

    • keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染
    • router-view也是一个组件,如果直接被包在keep-alive中,所有路径匹配的到的视图组件都会被缓存
    <keep-alive>
        <router-view></router-view>
    </keep-alive>
    
    • activated()deactivated()钩子函数只有在被keep-alive包裹的时候才会生效

    • 如果希望组件中的某一个被频繁的创建和销毁

      这里 Profile,User逗号后面不要加空格

      <keep-alive exclude="Profile,User">
          <router-view></router-view>
      </keep-alive>
      

    路径别名

    vue-cli3中可以使用@代替src

    案例

    App.vue

    <template>
      <div id="app">
        <router-view></router-view>
        <tab-bar>
          <tab-bar-item path="/home" activeColor="red">
            <img src="./assets/image/tabbar/首页.svg"  slot="item-icon">
            <img src="./assets/image/tabbar/首页_active.svg"  slot="item-icon-active">
            <div slot="item-text">首页</div>
          </tab-bar-item>
          <tab-bar-item path="/category" activeColor="skyblue">
            <img src="./assets/image/tabbar/分类.svg"  slot="item-icon">
            <img src="./assets/image/tabbar/分类_active.svg"  slot="item-icon-active">
            <div slot="item-text">分类</div>
          </tab-bar-item>
          <tab-bar-item path="/cart" activeColor="green">
            <img src="./assets/image/tabbar/购物车.svg"  slot="item-icon">
            <img src="./assets/image/tabbar/购物车_active.svg"  slot="item-icon-active">
            <div slot="item-text">购物车</div>
          </tab-bar-item>
          <tab-bar-item path="/profile">
            <img src="./assets/image/tabbar/我的.svg"  slot="item-icon">
            <img src="./assets/image/tabbar/我的_active.svg"  slot="item-icon-active">
            <div slot="item-text">我的</div>
          </tab-bar-item>
        </tab-bar>
      </div>
    </template>
    
    <script>
    import TabBar from "./components/tabbar/TabBar";
    import TabBarItem from "./components/tabbar/TabBarItem";
    
    export default {
      name: 'App',
      components: {
        TabBar,
        TabBarItem
      }
    }
    </script>
    
    <style lang="css">
    @import './assets/css/base.css';
    </style>
    

    TabBar.vue

    <!--  -->
    <template>
       <div id="tab-bar">
           <slot></slot>
       </div>
    </template>
    
    <script>
        export default {
            name: 'TabBar',
            data () {
                return {
                };
            }
        }
    </script>
    <style lang='css' scoped>
        #tab-bar {
            display: flex;
            background-color: #f6f6f6;
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            /* 阴影 */
            box-shadow:  0px -1px 1px rgba(100, 100, 100, 0.2);
        }
    </style>
    

    TabBarItem.vue

    <!--  -->
    <template>
    <div class="tab-bar-item" @click="itemClick">
        <div v-if="!isActive"><slot name="item-icon"></slot></div>
        <div v-else><slot name="item-icon-active"></slot></div>
        <div :style="activeStyle">
            <slot name="item-text"></slot>
        </div>
    </div>
    </template>
    
    <script>
        export default {
            name: 'TabBarItem',
            props: {
                path: String,
                activeColor: {
                    type: String,
                    default: 'red'
                }
            },
            data() {
                return {
                };
            },
            methods: {
                itemClick() {
                    this.$router.push(this.path).catch(err => {});
                }
            },
            computed: {
                isActive() {
                    return this.$route.path.indexOf(this.path) !== -1;
                },
                activeStyle() {
                    return this.isActive ? { color: this.activeColor } : {};
                }
            }
        };
    </script>
    <style lang='css' scoped>
        .tab-bar-item {
            flex: 1;
            text-align: center;
            height: 49px;
            font-size: 14px;
        }
    
        .tab-bar-item img {
            width: 24px;
            height: 24px;
            margin-top: 3px;
            vertical-align: middle;
        }
    
    </style>
    

    效果图

    Vue学习-路由router


    起源地下载网 » Vue学习-路由router

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元