Vue <router-link> 不可点击

Posted

技术标签:

【中文标题】Vue <router-link> 不可点击【英文标题】:Vue <router-link> not clickable 【发布时间】:2021-07-25 11:46:26 【问题描述】:

我正在尝试使用一些简单的路由设置一个 Vue 应用程序,以便我可以导航到不同的页面。我通过 npm 安装了 Vue-Router,并尝试在线学习几个教程,但是,我似乎无法弄清楚为什么我的无法点击,或者为什么当我手动输入 URL 时,它并没有改变任何东西。任何帮助表示赞赏。谢谢。

main.js:

import createApp from 'vue'
import App from './App.vue'
import "./vue-api-call/styles.css"
import VueRouter from 'vue-router'
import About from "./About"
import Home from "./Home";


const routes = [
    path: '/about', component: About,
    path: '/home', component: Home
]

const router = new VueRouter(routes)

createApp(App, router).mount("#app")

export default router

App.vue:

<!-- This first part of the file, the template part, is basically like an html page. Whatever we put in here will
display when we use 'npm run serve'. -->
<template>
  <!-- The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with
  javascript. -->
  <div id="app">
    <!--    <nav>Hello</nav>-->
    <!-- The router-view tag will display info that comes from the router-link tag. More information here:
    https://next.router.vuejs.org/guide/#html -->
    <router-view>
      <router-link to="/about">About</router-link>
    </router-view>
    <Layout>
      <!-- begin form -->
      Add a new video game with the form below:
      <form id="demo">
        <!-- text -->
        <br>
        <p>
          <input type="text" v-model="msg" placeholder="Add Game">
           msg 
        </p>
        <br>
        <p>
          <input type="checkbox" v-model="checked">
           checked ? "yes" : "no" 
        </p>
        <br>
        <!-- select -->
        <p>
          <select v-model="selected">
            <option>one</option>
            <option>two</option>
          </select>
        </p>
        <br>
        <p>
          <button type="submit" v-on:click="createVideoGame()">Submit Form</button>
        </p>
      </form>
      <br>
      <button v-on:click="customer()"> Customer Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">Customer ID</th>
          <th scope="col">First Name</th>
          <th scope="col">Last Name</th>
          <th scope="col">Middle Name</th>
          <th scope="col">Birthday</th>
          <th scope="col">Gender</th>
          <th scope="col">Email</th>
          <th scope="col">Username</th>
          <th scope="col">Is Deleted</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="customer in customerInfo" :key="customer.customerId">
          <td> customer.customerId </td>
          <td> customer.cusFirstName </td>
          <td> customer.cusLastName </td>
          <td> customer.cusMiddleName </td>
          <td> customer.dateOfBirth </td>
          <td> customer.gender </td>
          <td> customer.email </td>
          <td> customer.username </td>
          <td> customer.isDeleted </td>
        </tr>
        </tbody>
      </table>
      <br><br>
      <button v-on:click="videoGame()"> VideoGame Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">Video Game ID</th>
          <th scope="col">Title</th>
          <th scope="col">Release Year</th>
          <th scope="col">Price</th>
          <th scope="col">Stock</th>
          <th scope="col">Image</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="game in gameInfo" :key="game.videoGameId">
          <td> game.videoGameId </td>
          <td> game.videoGameTitle </td>
          <td> game.yearReleased </td>
          <td> game.price </td>
          <td> game.stock </td>
          <td> game.videoGameImage </td>
        </tr>
        </tbody>
      </table>
      <br><br>
      <button v-on:click="order()"> Order Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">Order ID</th>
          <th scope="col">Order Date</th>
          <th scope="col">Credit Card Provider</th>
          <th scope="col">Credit Card Number</th>
          <th scope="col">Total</th>
          <th scope="col">Subtotal</th>
          <th scope="col">Discount</th>
          <th scope="col">Customer ID</th>
          <th scope="col">Address ID</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="order in orderInfo" :key="order.orderId">
          <td> order.orderId </td>
          <td> order.orderDate </td>
          <td> order.creditCardProvider </td>
          <td> order.creditCardNumber </td>
          <td> order.total </td>
          <td> order.subtotal </td>
          <td> order.discount </td>
          <td> order.customerId </td>
          <td> order.addressId </td>
        </tr>
        </tbody>
      </table>
      <br><br>
      <button v-on:click="purchase()"> Purchase Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">Purchase ID</th>
          <th scope="col">Order ID</th>
          <th scope="col">Video Game ID</th>
          <th scope="col">Shipment Date</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="[purchase] in [purchaseInfo]" :key="purchase.purchaseId">
          <td> purchase.purchaseId </td>
          <td> purchase.orderId </td>
          <td> purchase.videoGameId </td>
          <td> purchase.shipmentDate </td>
        </tr>
        </tbody>
      </table>
      <br><br>
      <button v-on:click="address()"> Address Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">Address ID</th>
          <th scope="col">Customer ID</th>
          <th scope="col">State ID</th>
          <th scope="col">City</th>
          <th scope="col">Zip</th>
          <th scope="col">Suite Number</th>
          <th scope="col">PO Box</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="address in addressInfo" :key="address.addressId">
          <td> address.addressId </td>
          <td> address.customerId </td>
          <td> address.stateId </td>
          <td> address.city </td>
          <td> address.zip </td>
          <td> address.suiteNumber </td>
          <td> address.poBox </td>
        </tr>
        </tbody>
      </table>
      <br><br>
      <button v-on:click="state()"> State Button</button>
      <br>
      <table>
        <thead>
        <tr>
          <th scope="col">State ID</th>
          <th scope="col">State</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="state in stateInfo" :key="state.stateId">
          <td> state.stateId </td>
          <td> state.state </td>
        </tr>
        </tbody>
      </table>
      <br><br>
    </Layout>
  </div>
</template>

<!-- Still not entirely sure what this script part is. Pretty sure it's some functionality stuff added by Vue -->
<script>
import Layout from "./components/Layout.vue"
import axios from "axios"


// import PageHeading from "./components/PageHeading.vue"
// import NavBar from "./components/NavBar.vue"

export default 
  name: 'App', variant: "variant", variantType: "variantType", disableButton: "disableButton",
  username: "", password: "",

  data: () => 
    return 
      // These variables are used above and are what initially is shown above the buttons.
      customerInfo: [],
      gameInfo: [],
      orderInfo: "waiting for order",
      purchaseInfo: "waiting for purchase",
      addressInfo: "waiting for address",
      stateInfo: "waiting for state",
      username: "",
      password: "",
      msg: "",
      checked: true,
      picked: "",
      selected: ""
    
  ,
  components: 
    Layout,
    // NavBar, PageHeading,
  ,
  mounted() 
    // this.test()
  ,
  methods: 
    // Gets customer info and displays it.
    customer: function () 
      if (this.customerInfo === "waiting for customer") 
        axios
            .get('http://localhost:8000/customers/?format=json')
            .then(response => (this.customerInfo = response.data))
       else 
        this.customerInfo = "waiting for customer"
      
    ,
    // Gets video game info and displays it.
    videoGame: function () 
      if (this.gameInfo === "waiting for game") 
        axios
            .get('http://localhost:8000/videoGames/?format=json')
            .then(response => (this.gameInfo = response.data))
       else 
        this.gameInfo = "waiting for game"
      
    ,
    // Gets order info and displays it.
    order: function () 
      if (this.orderInfo === "waiting for order") 
        axios
            .get('http://localhost:8000/orders/?format=json')
            .then(response => (this.orderInfo = response.data))
       else 
        this.orderInfo = "waiting for order"
      
    ,
    // Gets purchase info and displays it.
    purchase: function () 
      if (this.purchaseInfo === "waiting for purchase") 
        axios
            .get('http://localhost:8000/purchases/?format=json')
            .then(response => (this.purchaseInfo = response.data))
       else 
        this.purchaseInfo = "waiting for purchase"
      
    ,
    // Gets address info and displays it.
    address: function () 
      if (this.addressInfo === "waiting for address") 
        axios
            .get('http://localhost:8000/addresses/?format=json')
            .then(response => (this.addressInfo = response.data))
       else 
        this.addressInfo = "waiting for address"
      
    ,
    // Gets state info and displays it.
    state: function () 
      if (this.stateInfo === "waiting for state") 
        axios
            .get('http://localhost:8000/states/?format=json')
            .then(response => (this.stateInfo = response.data))
       else 
        this.stateInfo = "waiting for state"
      
    ,
    createVideoGame() 
      axios.post('http://127.0.0.1:8000/videoGames/', 
        videoGameId: '111',
        videoGameTitle: 'Test Video Game 1',
        yearReleased: '2021',
        price: '10.00',
        stock: '5',
        videoGameImage: 'testImage'
      )
    ,
    // login: function () 
    //   console.log(this.username)
    //   console.log(this.password)
    //   const bcrypt = require("bcryptjs")
    //   bcrypt.compare(this.password, "hash", (err, result) => 
    //     if (err) 
    //       console.error(err)
    //       return
    //     
    //     console.log(result) // true or false
    //   );
  

// methods: 
//         addUser()
//            console.log(this.encryptPassword(this.password))
//         ,
//         encryptPassword(password)
//           const salt = bcrypt.genSaltSync(10)
//           return bcrypt.hashSync(password, salt)
//         ,
</script>

<!-- This style tag is for the entire page, I think. If you change something in here, like the background-color, it
will change it on the webpage. It's exactly like the style tag in a CSS/HTML page I'm pretty sure. -->
<!-- if you use the !important; rule, it will override ALL previous styling rules for that specific property on that
element! -->
<style>
body 
  margin: 0;
  padding: 0;
  background-color: #c5fcc5 !important;


table, th, td 
  border: 1px solid darkgreen;
  text-align: center;

</style>

【问题讨论】:

请分享 package.json 文件 【参考方案1】:

你忘记告诉 Vue 使用 VueRouter。来自Official Docs。

import  createApp  from 'vue';
import App from './App.vue';
...
...

const routes = [
    path: '/about', component: About,
    path: '/home', component: Home
];

const router = new VueRouter(routes);

createApp(App).use(router).mount('#app'); // <== Here

export default router;

【讨论】:

以上是关于Vue <router-link> 不可点击的主要内容,如果未能解决你的问题,请参考以下文章

router-link 绑定事件不生效

vue编程式路由实现新窗口打开

使用 vue- <router-link> 更改路由

Vue <router-link> 不可点击

带有<router-link>的自定义Vue库组件,如何同步路由器状态?

Laravel Vuejs [Vue 警告]:未知的自定义元素:<router-link>