SessionStorage 不会在点击事件中分配变量

SessionStorage won't assign variable inside click event

我正在尝试将变量分配给 sessionStorage,如下所示:

<router-link :to="{name: 'admin'}" @click="sessionStorage.auth = false">

但它抛出此警告:

[Vue warn]: Unhandled error during execution of native event handler 
  at <RouterLink to= {name: 'admin'} onClick=fn > 
  at <HeaderCms key=1 > 
  at <Cms>
warn @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25050
logError @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25224
handleError @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25216
callWithErrorHandling @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25170
callWithAsyncErrorHandling @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25176
callWithAsyncErrorHandling @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25186
invoker @ app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:33228
app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:38657 

随后出现此错误:

Uncaught TypeError: Cannot set properties of undefined (setting 'auth')
        at onClick._cache.<computed>._cache.<computed> (app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:38657:39)
        at app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:33242:60
        at callWithErrorHandling (app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25167:22)
        at callWithAsyncErrorHandling (app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25176:21)
        at callWithAsyncErrorHandling (app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:25186:21)
        at HTMLAnchorElement.invoker (app.js?id=9ab923fd0732ebefc30fc66fb84cbb22:33228:90)

当我分配false时,属性怎么会是未定义的?我做错了什么?

我尝试了我能想到的所有变体,唯一对我有用的解决方案是使用 both 一个 native 修饰符和一个方法处理程序:

<template>
  <router-link :to="{ name: 'admin' }" @click.native="onClick" />
</template>

<script>
export default {
  methods: {
    onClick() {
      sessionStorage.setItem('auth', false);
    },
  },
};
</script>

native 修饰符的原因描述为 。我不完全确定为什么需要方法处理程序,但正如您在原始错误中看到的那样, sessionStorage 在内联处理程序中未定义。

注意 sessionStorage API 使用 setItem 而不是赋值。

正如您在 "@click.native" is deprecated in Vue.js 3. So I suggest using a button instead of router-link and navigate programmatically 的评论中找到的,如以下代码:

<script>
import { RouterLink, RouterView, useRouter } from 'vue-router';
export default {
  setup() {
    const router = useRouter()
    function navigate() {
      console.log("navigate");
      sessionStorage.setItem("auth", false);
      router.push("/admin");
    }

    return {
      navigate,
      RouterLink,
      RouterView
    }
  }
}
</script>

<template>
 
      <nav>
<!--        <RouterLink to="/admin">-->
          <button @click="navigate">Admin</button>
<!--        </RouterLink>-->
      </nav>

  <RouterView />
</template>

请注意,我使用了 useRouter,因为 thiscomposition API 中不可访问。然后,您可以为按钮设置类似于应用中其他链接的样式。

从这个答案的评论中我发现我们也可以通过其他两种方式做到这一点:

using <a> tag for better accessibility:

<script>
import { RouterLink, RouterView, useRouter } from 'vue-router';
import {ref} from "vue";
export default {
  setup() {
    const router = useRouter()
    const trueFalse = ref(false)
    function navigate() {
      console.log("navigate");
      sessionStorage.setItem("auth", trueFalse.value);
      router.push("/admin");
    }

    return {
      navigate,
      RouterLink,
      RouterView
    }
  }
}
</script>

<template>

      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
        <RouterLink to="/videos">videos</RouterLink>
          <a @click="navigate">Admin</a>
      </nav>

  <RouterView />
</template>

And using <router-link>:

<script>
import { RouterLink, RouterView } from 'vue-router';
import {ref} from "vue";
export default {
  setup() {
    const trueFalse = ref(false)
    function navigate() {
      console.log("navigate");
      sessionStorage.setItem("auth", trueFalse.value);
    }

    return {
      navigate,
      RouterLink,
      RouterView
    }
  }
}
</script>

<template>
 
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
        <RouterLink to="/videos">videos</RouterLink>
        <RouterLink to="/admin" @click="navigate">
          Admin
        </RouterLink>
      </nav>

  <RouterView />
</template>