77.VueRouter守卫拦截以及404解决

Banner.vue

<template>
  <div>
    <h1>Banner</h1>
    <button @click="back">后退</button>
    <button @click="forward">前进</button>
    <button @click="go">go</button>
  </div>
</template>

<script>
export default {
  name: "TheBanner",
  methods: {
    back() {
      this.$router.back();
    },
    forward() {
      this.$router.forward();
    },
    go() {
      this.$router.go(-2); //后退两步
    },
  },
};
</script>

<style>
</style>

Message.vue

<template>
  <div class="three_main">
    <ul>
      <li v-for="m in message" :key="m.id">
        <button @click="pushShow(m)">push查看</button>
        <button @click="replaceShow(m)">replace查看</button>
        <!-- 1111111111111111111 -->
        <!-- 跳转路由并携带query参数,to的字符串写法 -->
        <router-link :to="`/home/message/detail/${m.id}/${m.text}`">
          message{{ m.id }}
        </router-link>
      </li>
    </ul>
    <div>
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  name: "TheMessage",
  methods: {
    pushShow(m) {
      this.$router.push(`/home/message/detail/${m.id}/${m.text}`);
    },
    replaceShow(m) {
      this.$router.replace(`/home/message/detail/${m.id}/${m.text}`);
    },
  },
  data() {
    return {
      message: [
        {
          id: "001",
          text: "检察机关去年批捕侵害未成年人犯罪4.6万人",
        },
        {
          id: "002",
          text: "全国大学英语四六级成绩今日可查 这些常见问题请注意",
        },
        {
          id: "003",
          text: "宁夏出台搬迁撤并类村庄认定标准 不得强制农民集中上楼",
        },
        {
          id: "004",
          text: "急难愁盼|不交房?湖北随州督促企业上海地铁早高峰间隔时间过长?回应来了",
        },
      ],
    };
  },
};
</script>

<style>
.three_main {
  display: flex;
  flex-direction: column;
}
li,
ul,
p {
  margin: 0;
  padding: 0;
  margin-left: 10px;
}
</style>

News.vue

<template>
  <div class="three_main">
    <ul>
      <li>欢迎学习vue</li>
      <li v-for="n in news" :key="n.id">
        news{{ n.id }}
        <input type="text" id="n.id" />
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "TheNews",
  data() {
    return {
      news: [
        {
          id: "001",
          text: ' 时习之|当"冰雪白"遇上"中国红" ',
        },
        {
          id: "002",
          text: "汪洋主持召开全国政协主席会议",
        },
        {
          id: "003",
          text: "韩正:推动中央生态环保督察工作向纵深发展",
        },
        {
          id: "004",
          text: '"十个明确"彰显马克思主义中国化新飞跃',
        },
      ],
      opacity: 1,
    };
  },
  // 组件被激活时
  activated() {
    console.log("组件激活");
    this.timer = setInterval(() => {
      console.log(this.opacity);
      this.opacity -= 0.1;
      if (this.opacity <= 0) this.opacity = 1;
    }, 300);
  },
  // 组件未激活时
  deactivated() {
    console.log("组件未激活");
    clearInterval(this.timer);
  },
  // 独享路由守卫
  beforeEnter: (to, from, next) => {
    console.log("123");
    if (to.meta.isAuth) {
      // 判定是否需要权限
      if (localStorage.getItem("name") === "llx") {
        next();
      } else {
        alert("名称不对");
      }
    } else {
      next();
    }
  },
};
</script>

<style>
</style>

About.vue

<template>
  <div class="second_main">
    <div style="width: 100%">
      <h2>About组件内容</h2>
      <div class="second_btn_div">
        <router-link
          class="title_button"
          active-class="selected_button"
          to="/about/news"
          >News</router-link
        >
        <router-link
          class="title_button"
          active-class="selected_button"
          to="/about/message"
          >Message</router-link
        >
      </div>
      <hr />
      <div>
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "TheAbout",
  components: {},
  // 通过路由规则,进入该组件时被调用
  beforeRouteEnter(to, from, next) {},
  // 通过路由规则,离开该组件时被调用
  beforeRouteLeave(to, from, next) {},
};
</script>

<style>
</style>

Detail.vue

<template>
  <div>
    <ul>
      <!-- 通过query拿值 -->
      <!-- <li>消息编号:{{ $route.query.id }}</li>
      <li>消息标题:{{ $route.query.text }}</li> -->
      <!-- 通过params拿值 -->
      <!-- 不使用props写法 -->
      <!-- <li>消息编号:{{ $route.params.id }}</li>
      <li>消息标题:{{ $route.params.text }}</li>
      -->
      <!-- <li>消息编号:{{ a }}</li>
      <li>消息标题:{{ b }}</li>
      -->
      <li>消息编号:{{ id }}</li>
      <li>消息标题:{{ text }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "TheDetail",
  // props: ["a", "b"],
  props: ["id", "text"],
};
</script>

<style>
</style>

Home.vue

<template>
  <div class="second_main">
    <div style="width: 100%">
      <h2>Home组件内容</h2>
      <div class="second_btn_div">
        <router-link
          class="title_button"
          active-class="selected_button"
          to="/home/news"
          >News</router-link
        >
        <router-link
          class="title_button"
          active-class="selected_button"
          to="/home/message"
          >Message</router-link
        >
      </div>
      <hr />
      <div>
        <!-- includu保持该组件不被销毁值为组件里的name -->
        <!-- 缓存多个     :include="['TheNews','TheMessage']" -->
        <keep-alive include="TheNews">
          <router-view></router-view>
        </keep-alive>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "TheHome",
};
</script>

<style>
</style>

router/index.js

// 该文件专门用于创建整个应用的路由器
import VueRouter from "vue-router";
// 引入组件
import About from '../pages/About.vue';
import Home from '../pages/Home.vue';
import News from '../pages/News.vue';
import Message from '../pages/Message';
import Detail from '../pages/Detail.vue';

const router = new VueRouter({
    mode: 'history', // 调成哈希模式
    // hash模式下, 仅hash符号之前的内容会被包含在请求中, 
    // 如http: //www.abcd.com,因此对于后端来说,
    // 即使没有做到对路由的覆盖,也不会返回404错误。

    // history模式下, 前端的url必须和实际向后台发起请求的url一致, 
    // 如http: //www.abcd.com/movie/id。如果后端缺少对/movie/id的路由处理,
    //     将返回404错误。

    routes: [{
            name: 'guanyu',
            path: '/about',
            component: About,
            meta: {
                title: 'About',
            },
        },
        {
            name: 'zhuye',
            path: '/home',
            component: Home,
            meta: {
                title: 'Home'
            },
            // redirect: "home/news",
            children: [{
                    path: 'news',
                    component: News,
                    meta: {
                        title: 'News',
                        isAuth: true, //是否需要权限的校验
                    },
                    // 对此组件做独享路由守卫
                    beforeEnter: (to, from, next) => {
                        if (to.meta.isAuth) { // 判定是否需要授权
                            if (localStorage.getItem('name') === 'llx') {
                                next();

                            } else {
                                alert('姓名不对');
                            }

                        } else {
                            next();

                        }
                    }
                },
                {
                    name: 'xiaoxi',
                    path: 'message',
                    component: Message,
                    meta: {
                        isAuth: true,
                        title: '信息',
                    },
                    children: [{
                        name: 'xiangqing',
                        // 使用占位符定义detail后面携带两个参数
                        // 定义了之后就得使用params方式传参了url/参数1/参数2
                        path: 'detail/:id/:text',
                        component: Detail,
                        // props的第二种写法,值为布尔值,若布尔值为真,
                        // 就会把该路由组件收到的所以params参数, 以props的形式传个Detail组件
                        props: true

                    }]
                }
            ]
        },
    ]
});
// 守卫拦截
// 初始化和每一次路由切换之前都都会调用
// router.beforeEach((to, from, next) => {
//     if (to.meta.isAuth) { // 判定是否需要授权
//         if (localStorage.getItem('name') === 'llx') {
//             next();

//         } else {
//             alert('姓名不对');
//         }

//     } else {
//         next();

//     }
// });

router.afterEach((to, from) => {
    document.title = to.meta.title || 'llx'; // 实时切换标题
});
export default router;

App.vue

<template>
  <div id="app">
    <banner></banner>
    <hr />
    <br />
    <div class="app">
      <div class="left">
        <!-- replace当该值=false时,你点击了router-link控件则
        此时浏览器可以点击返回上一页记录,=true时则没有记录 -->
        <router-link
          replace
          ref="default_selected"
          to="/about"
          class="title_button"
          active-class="selected_button"
          >About</router-link
        >
        <router-link
          replace
          to="/home"
          class="title_button"
          active-class="selected_button"
          >Home</router-link
        >
      </div>
      <div class="right">
        <router-view></router-view>
      </div>
    </div>
  </div>
</template>

<script>
import Banner from "./components/Banner.vue";
export default {
  name: "App",
  components: { Banner },
  data() {
    return {
      btn_style: "selected",
      list: [
        { text: "About", style: "selected", show: true },
        { text: "Home", style: "unselected", show: false },
      ],
    };
  },
  mounted() {
    // 自动点击一次
    // this.$refs.default_selected.$el.click();
  },

  methods: {
    change_bg(text) {
      this.list.forEach((element) => {
        if (element.text == text) {
          element.style = "selected";
          element.show = true;
        } else {
          element.style = "unselected";
          element.show = false;
        }
      });
    },
  },
};
</script>

<style>
#app {
  width: 100%;
  height: auto;
}
.app {
  display: flex;
}
/* 左侧 */
.left {
  width: 200px;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  background-color: #ffffff;
}
.right {
  width: 88%;
}
/* 按钮 */
.title_button {
  text-decoration: none;
  border-radius: 2px;
  margin-top: 0.3px;
  cursor: pointer;
  height: 30px;
  display: flex;
  align-items: center;
  background-color: #d6cdcd;
  color: black;
  padding: 5px;
}
.selected_button {
  background-color: #1c6cb8;
  color: #ffffff;
}

/* 子组件 */
.second_main {
  margin-top: 28px;
  margin-left: 30px;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: auto;
  align-items: flex-start;
}
.second_btn_div {
  display: flex;
}
h2 {
  margin-top: 5px;
  margin-bottom: 1px;
}
</style>

main.js

import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import router from './router';
Vue.use(VueRouter);
new Vue({
  // 创建vm并使用stroe
  render: h => h(App),
  router: router
}).$mount('#app');
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修罗_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值