【问题标题】:Vue.js 3, Quasar 2 - Component is missing template or render functionVue.js 3,Quasar 2 - 组件缺少模板或渲染功能
【发布时间】:2021-09-10 22:15:45
【问题描述】:

我正在尝试创建一个动态组件并将一个道具传递给它。我收到警告: Component is missing template or render function. 组件正在渲染,但我仍然收到警告,并且没有将 prop 传递给它。

家长:

<template lang="pug">
q-page
  component(:is="detailsComponent" v-bind="selectedRule")
</template>

<script lang="ts">
import { defineComponent, ref, shallowRef, onMounted } from 'vue'
import { useStore } from 'vuex'
import { storeKey } from '../store'
import { useRoute, useRouter } from 'vue-router'
import { RuleList } from '../components/models'

export default defineComponent({
  name: 'CodeDetails',
  setup() {
    const store = useStore(storeKey)
    const route = useRoute()
    const router = useRouter()

    const detailsComponent = shallowRef({})
    const selectedRule = ref({} as RuleList)

    const selectComponent = async (ruleName: string) => {
      let fileName = ''
      switch (ruleName) {
        case 'retailFoodRules': fileName = 'FoodDetails'
        break
        case 'generalRules': fileName = 'GeneralDetails'
        break
        case 'poolRules': fileName = 'PoolDetails'
        break
        default: fileName = 'OtherDetails'
      }
      const component = await import(`../components/${fileName}`) as unknown
      detailsComponent.value = component.default as RuleList
    }

    onMounted(() => {
      const selected = JSON.parse(route.params.ruleString as string) as RuleList
      const ruleName = route.params.rule
      if (route.params) {
        selectedRule.value = selected as unknown as RuleList
        void store.dispatch('searchResults/saveSelectedRule', selected)
        // void store.dispatch('searchResults/saveRuleName', ruleName)
        void selectComponent(ruleName as string)
      } else if (!route.params && store.state.searchResults.selectedRule) {
        selectedRule.value = store.state.searchResults.selectedRule
        // selectComponent(store.state.searchResults.ruleName)
      } else {
        router.go(-1)
      }
    })

    return { detailsComponent, selectedRule }
  },
})
</script>

Child(其他动态子组件类似):

<template lang="pug">
q-card(flat)
  q-card-section
    q-item-label.text-caption.text-grey-9 Description
    q-item-label.text-subtitle1(v-html="selectedRule.Description")
  q-separator
  q-card-section
    q-item-label.text-caption.text-grey-9 Classification
    q-item-label.text-subtitle1(v-html="selectedRule.Classification" :class="{'text-negative': selectedRule.Classification === 'Priority', 'text-orange-9': selectedRule.Classification === 'Priority Foundation'}")
  q-separator
  q-card-section
    q-item-label.text-caption.text-grey-9 Section
    q-item-label.text-subtitle1(v-html="selectedRule.Section")
  q-separator
  q-card-section
    q-item-label.text-caption.text-grey-9 Category
    q-item-label.text-subtitle1(v-html="selectedRule.Category")
  q-separator
  q-card-section
    q-item-label.text-caption.text-grey-9 Compliance Categories
    q-item-label.text-subtitle1(v-html="selectedRule.Compliance")
  q-separator
  q-card-section
    q-item-label.text-caption.text-grey-9 Rule Text
    q-item-label.text-subtitle1(v-html="selectedRule.FullText")
</template>

<script lang="ts">
import { defineComponent, toRefs } from 'vue'
import { RuleList } from '../components/models'

export default defineComponent({
  name: 'FoodDetails',
  setup(props) {
    // console.log(Object.assign({}, props))
    const selectedRule = toRefs(props.selectedRule as RuleList)

    return { selectedRule }
  }
})
</script>

在子组件中,我收到错误:Property 'selectedRule' does not exist on type '{}'.const selectedRule = toRefs(props.selectedRule as RuleList) 行上,所以它没有看到传递的道具。奇怪的是,如果我使用 Vue devtools 检查子组件,它会将 selectedRule 显示为 attr 而不是 prop。我做错了什么还是这是 Quasar 怪癖?

【问题讨论】:

    标签: typescript vue.js vue-component vuejs3 quasar


    【解决方案1】:

    对于父组件,它看起来不错,但对于子组件,您添加 props 选项:

    <script lang="ts">
    import { defineComponent, toRefs } from 'vue'
    import { RuleList } from '../components/models'
    
    export default defineComponent({
      name: 'FoodDetails',
     props:{
         selectedRule : {
            type : Object as PropType<RuleList >
         }
     },
      setup(props) {
        // console.log(Object.assign({}, props))
        const selectedRule = toRefs(props.selectedRule)
    
        return { selectedRule }
      }
    })
    </script>
    
    

    【讨论】:

      【解决方案2】:

      我将父组件中的这一行更改为:

      component(:is="detailsComponent" v-bind="selectedRule")
      

      返回:

      component(:is="detailsComponent" :selectedRule="selectedRule")
      

      在子键中我添加了一个 prop 键,使用 Object.assign() 来获取 prop 值,因为它是作为代理进来的,并删除了 toRef(),因为它无论如何都不是响应式的。

      export default defineComponent({
        name: 'FoodDetails',
        props: {
          selectedRule: {
            type: Object,
            required: true
          }
        },
        setup(props) {
          const ruleObject = Object.assign({}, props.selectedRule) as RuleList
      
          return { ruleObject }
        }
      })
      </script>
      

      Component is missing template or render function. 警告仍然存在,即使组件正在渲染和显示来自 prop 的数据。

      【讨论】:

        猜你喜欢
        • 2021-02-01
        • 2021-11-15
        • 2021-07-20
        • 2021-02-18
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 2018-11-07
        相关资源
        最近更新 更多