簡體   English   中英

更改 boolean 道具時不會更新子級

[英]Child is not updated when boolean prop is changed

我有以下組件:

家長:

<template>
    <Child path="instance.json" 
             v-bind:authenticated="authenticated" 
             v-bind:authenticator="authenticator" 
    />
</template>

<script>
import { getAuthenticator } from '../auth';
export default {
  data() {
    return {
      authenticated: false,
      authenticator: null
    };
  },
  beforeMount: async function () {
    this.authenticator = getAuthenticator()
    this.checkAccess();
  },
  methods: {
    checkAccess() {
      this.authenticated = this.authenticator.isAuthenticated();
    },
    async login() {
      this.checkAccess();
      await this.authenticator.signIn();
      this.checkAccess();
    }
  }
};
</script>

孩子:

<template>
  <div id="swagger-ui"></div>
</template>

<script>
import swagger from "swagger-ui-dist";
import "swagger-ui-dist/swagger-ui.css";

export default {
  props: ["path", "authenticated", "authenticator"],
  mounted: async function() {
    if (this.authenticated) {
      let token = (await this.authenticator.getToken()).accessToken;

      const ui = swagger.SwaggerUIBundle({
        url: this.path,
        dom_id: "#swagger-ui",
        onComplete: function() {
          ui.preauthorizeApiKey("token", token);
        }
      });
    } else {
      const ui = swagger.SwaggerUIBundle({
        url: this.path,
        dom_id: "#swagger-ui"
      });
    }
  }
};
</script>

在父組件中,當調用login方法時, authenticated變量變為true 由於authenticated作為 prop 傳遞給 Child 組件,因此我希望 Child 在authenticated更改時會被刷新。 但是,Child 不會刷新。

我認為問題可能是由於我根本沒有在孩子的模板中使用經過authenticated的事實引起的。 相反,我只在mounted的鈎子中使用它。 就我而言,我沒有使用模板中的authenticated

我嘗試了兩種解決方案:

  • 在 Parent 的login方法中調用this.$forceUpdate() - 這根本不起作用(沒有改變)
  • :key添加到 Child,並在每次調用login時更改密鑰 - 這可行,但是,它有點 hacky。 我想了解如何正確地做到這一點。

您不在模板中使用它很好,問題是您只檢查子mounted鈎子中的authenticated ,該鈎子只運行一次(當時是false的)。

您應該使用watch來跟蹤對經過authenticated的道具的更改,而不是mounted

watch: {
  authenticated: {
    handler(newValue, oldValue) {
      this.setUi();
    },
    immediate: true   // Run the watch when `authenticated` is first set, too
  }
}

每次經過authenticated的更改都會調用setUi方法:

methods: {
  async setUi() {
    if (this.authenticated) {
      let token = (await this.authenticator.getToken()).accessToken;

      const ui = swagger.SwaggerUIBundle({
        url: this.path,
        dom_id: "#swagger-ui",
        onComplete: function() {
          ui.preauthorizeApiKey("token", token);
        }
      });
    } else {
      const ui = swagger.SwaggerUIBundle({
        url: this.path,
        dom_id: "#swagger-ui"
      });
    }
  }
}

你需要的是使用觀察者。 實際上,您的代碼只運行一次(安裝 de 組件時),而不是在每次 prop 更改時運行。

<template>
  <div id="swagger-ui"></div>
</template>

<script>
import swagger from 'swagger-ui-dist';
import 'swagger-ui-dist/swagger-ui.css';

export default {
  props: {
    path: {
      type: String,
      default: '',
    },
    authenticated: {
      type: Boolean,
      default: false,
    },
    authenticator: {
      type: Object,
      default: () => {},
    },
  },
  watch: {
    async authenticated(newValue) {
      await this.updateSwagger(newValue);
    },
  },
  async mounted() {
    await this.updateSwagger(this.authenticated);
  }
  methods: {
    async updateSwagger(authenticated) {
      if (authenticated) {
        const token = (await this.authenticator.getToken()).accessToken;

        const ui = swagger.SwaggerUIBundle({
          url: this.path,
          dom_id: '#swagger-ui',
          onComplete: function () {
            ui.preauthorizeApiKey('token', token);
          },
        });
      } else {
        const ui = swagger.SwaggerUIBundle({
          url: this.path,
          dom_id: '#swagger-ui',
        });
      }
    },
  },
};
</script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM