通过安装应用程序的元素上的属性将道具传递给 Vue 根实例

Jon*_*lis 5 vue.js vuejs3

我对 Vue 非常陌生,所以如果我的术语不正确,请原谅我。我有一个 .NET Core MVC 项目,其中包含小的、单独的 vue 页面。在我当前的页面上,我从控制器返回一个视图,它只有:

@model long;

<div id="faq-category" v-bind:faqCategoryId="@Model"></div>

@section Scripts {
    <script src="~/scripts/js/faqCategory.js"></script>
}
Run Code Online (Sandbox Code Playgroud)

我在此页面中发送项目的 id 的地方将抓取并为其创建编辑表单。 faqCategory.js是编译后的 vue 应用程序。我需要long在初始化时将参数传递给 vue 应用程序,以便它可以获取完整的对象。我用main.ts类似的方式安装它:

import { createApp } from 'vue'
import FaqCategoryPage from './FaqCategoryPage.vue'

createApp(FaqCategoryPage)
    .mount('#faq-category');
Run Code Online (Sandbox Code Playgroud)

如何faqCategoryId进入我的 vue 应用程序以启动初始化并加载对象?我的v-bind尝试似乎不起作用 - 我@Prop(Number) readonly faqCategoryId: number = 0;在 vue 组件上有一个,但它总是0.

我的 FaqCategoryPage.vue 脚本很简单:

<script lang="ts">

    import { Options, Vue } from "vue-class-component";
    import { Prop } from 'vue-property-decorator'
    import Card from "@/Card.vue";
    import axios from "axios";
    import FaqCategory from "../shared/FaqCategory";

    @Options({
        components: {
            Card,
        },
    })
    export default class FaqCategoryPage extends Vue {
        @Prop(Number) readonly faqCategoryId: number = 0;

        mounted() {
            console.log(this.faqCategoryId);
        }
    }

</script>
Run Code Online (Sandbox Code Playgroud)

Mic*_*evý 11

似乎不支持将道具传递给放置在应用程序正在安装的元素上的根实例 vie 属性

您可以使用data-属性轻松解决它

视图 2

const mountEl = document.querySelector("#app");

new Vue({
  propsData: { ...mountEl.dataset },
  props: ["message"]
}).$mount("#app");
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" data-message="Hello from HTML">
  {{ message }}
</div>
Run Code Online (Sandbox Code Playgroud)

视图 3

const mountEl = document.querySelector("#app");

Vue.createApp({  
  props: ["message"]
}, { ...mountEl.dataset }).mount("#app");
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.global.js"></script>
<div id="app" data-message="Hello from HTML">
  {{ message }}
</div>
Run Code Online (Sandbox Code Playgroud)

这个最大的缺点是采取一切data-属性是一个字符串,所以如果你的组件需要其他的东西(NumberBoolean等),你必须自行转换。

当然,另一种选择是将您的组件向下推一级。只要使用v-bind( :counter),就会将正确的 JS 类型传递到组件中:

Vue.createApp({
  components: {
    MyComponent: {
      props: {
        message: String,
        counter: Number
      },
      template: '<div> {{ message }} (counter: {{ counter }}) </div>'
    }
  },
}).mount("#app");
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.global.js"></script>

<div id="app">
  <my-component :message="'Hello from HTML'" :counter="10" />
</div>
Run Code Online (Sandbox Code Playgroud)

只是一个想法(不是真正的问题)

不太确定,但这可能是Props 外壳的问题

HTML 属性名称不区分大小写,因此浏览器会将任何大写字符解释为小写。这意味着当你使用 DOM 模板时,camelCased 道具名称需要使用它们的 kebab-cased(连字符分隔)等价物

尝试将您的 MVC 视图更改为:

<div id="faq-category" v-bind:faq-category-id="@Model"></div>
Run Code Online (Sandbox Code Playgroud)


cam*_*ice 5

除了Michal Levý关于Vue 3回答之外,您还可以使用单个文件组件实现该模式:

应用程序.html

<div id="app" data-message="My Message"/>
Run Code Online (Sandbox Code Playgroud)

应用程序.js

import { createApp } from 'vue';
import MyComponent from './my-component.vue';
const mountEl = document.querySelector("#app");

Vue.createApp(MyComponent, { ...mountEl.dataset }).mount("#app");
Run Code Online (Sandbox Code Playgroud)

我的component.vue

<template>
  {{ message }}
</template>

<script>
export default {
  props: {
    message: String
  }
};
</script>
Run Code Online (Sandbox Code Playgroud)

或者您甚至可以从父 HTML 页面上的任何位置获取数据,例如:

应用程序.html

<h1>My Message</h1>
<div id="app"/>
Run Code Online (Sandbox Code Playgroud)

应用程序.js

import { createApp } from 'vue';
import MyComponent from './my-component.vue';
const message = document.querySelector('h1').innerText;

Vue.createApp(MyComponent, { message }).mount("#app");
Run Code Online (Sandbox Code Playgroud)

我的component.vue

<template>
  {{ message }}
</template>

<script>
export default {
  props: {
    message: String
  }
};
</script>
Run Code Online (Sandbox Code Playgroud)