您的位置:首页 > 房产 > 家装 > 厂家网页制作_黄骅怎么读_苏州关键词优化怎样_重庆网站seo费用

厂家网页制作_黄骅怎么读_苏州关键词优化怎样_重庆网站seo费用

2024/12/23 6:43:42 来源:https://blog.csdn.net/jiciqiang/article/details/142700411  浏览:    关键词:厂家网页制作_黄骅怎么读_苏州关键词优化怎样_重庆网站seo费用
厂家网页制作_黄骅怎么读_苏州关键词优化怎样_重庆网站seo费用

        在Vue2中,子组件使用的是选项式 API ,被引用的组件实例和该子组件的 this 完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易,当然也因此,应该只在绝对需要时才使用组件引用。大多数情况下,你应该首先使用标准的 props 和 emit 接口来实现父子组件交互。

        而在Vue3中,子组件使用<script setup>的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露。

一、创建子组件(表格)

        在项目目录src/components目录中创建TableNormal.vue组件,并且通过defineExpose对外暴露父组件可以调用的函数。代码如下:

<template><div class="table-wrap"><!-- table-wrap --><div class="table-wrap"><el-table ref="table" border :data="tableData"><el-table-column type="selection" width="55" fixed></el-table-column><el-table-column type="index" label="序号" width="50px" :resizable="false"></el-table-column><template v-for="(item, index) in tableColumns"><el-table-column :prop="item.prop" :label="item.label" :key="'' + index"></el-table-column></template.</el-table></div><!-- /table-wrap --></div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
defineOptions({name: "Table-Normal"
})
type TableColumnsType = {label: string,prop: string
}
const tableColumns = ref<Array<TableColumnsType>>([])       // 列数据
const tableData = ref<Array<any>>([])                       // 行数据
const page = ref(1)
const pageSize = ref(5)
const pageTotal = ref(0)const onLoadTableColumns = () => {// 通过Axios API接口获取tableColumns 表格列数据
}const onLoadTableData = () => {// 通过Axios API接口获取tableData 表格行数据
}onMounted(() => {onLoadTableColumns()onLoadTableData()
})// 对外暴露onLoadTableData函数
defineExpose({onLoadTableData})
</script>

二、创建父组件(Department)

        在项目src/views目录中,创建Department.vue文件。示例代码如下:

<template><div><table-normal></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
// 重新加载
const valueChange = () => {}
</script>

2.1 ref获取组件实例

        通过ref获取组件实例后,则可以通过实例对象的变量,去调用子组件中对外暴露的变量或函数了。

<template><div><table-normal ref="tableNormalRef"></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
import { ref} from "vue";
const tableNormalRef = ref(null) // 重新加载
const valueChange = () => {if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()
}
</script>

三、解决问题 - 类型断言

        当父组件Department.vue中,通过ref获取自定义表格组件实例,并且在子组件中已通过defineExpose对外暴露了onLoadTableData函数,所以我们可以通过实例变量直接调用onLoadTableData()函数。

if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()

3.1 "never"断言

        但是调用后,会提示如下截图上的断言提示【错误提示:类型“never”上不存在属性“onLoadTableData”。】。

        在TypeScript中,当一个变量被推断为never类型时,这意味着变量从逻辑上不应该存在任何值。所以需要在获取实例时,告诉ref该实例的类型。

        由于ref获取自定义组件为DOM元素,所以将其类型指定为HTMLElement,代码如下:

<template><div><table-normal ref="tableNormalRef"></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
import { ref} from "vue";
const tableNormalRef = ref<HTMLElement | null>(null)// 重新加载
const valueChange = () => {if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()
}
</script>

3.2 onLoadTableData不存在

        添加HTMLElement后,never类型断言问题是消失了,但随之而来又有新问题【错误:属性“onLoadTableData”在类型“HTMLElement”上不存在。你是否指的是“onloadeddata”?

        这是由于onLoadTableData为自定义函数,在HTMLElement类型中并不存上在,所以我们需要重新定义一个新接口类型,并继承HTMLElement类型即可。代码如下:

<template><div><table-normal ref="tableNormalRef"></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
import { ref} from "vue";
// 定义新接口类型
interface LoadTableDataElement extends HTMLElement {onLoadTableData: () => void
}
const tableNormalRef = ref<LoadTableDataElement | null>(null)// 重新加载
const valueChange = () => {if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()
}
</script>

        此时VSCode中波浪线不存在了。

3.3 null类型

        在通过ref获取组件实例中,有可能出现组件实例未获取到的情况(即为null类型),所以在valueChange函数中调用前,需判断其是否存在,再调用。否则会报错【错误提示:“tableNormalRef.value”可能为 “null”。

四、useTemplateRef

        模板引用也可以被用在一个子组件上,这种情况下引用中获得的值是组件实例。

4.1 新特性获取组件实例

        在前面讲了,使用ref方式获取组件实例,但在3.5版本后,可以通过新特性useTemplateRef来获取模板中的组件实例。我们将上面示例代码稍作修改,代码如下:

<template><div><table-normal ref="tableNormalRef"></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
import { ref} from "vue";
// 定义新接口类型
interface LoadTableDataElement extends HTMLElement {onLoadTableData: () => void
}
const tableNormalRef = useTemplateRef('tableNormalRef')// 重新加载
const valueChange = () => {if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()
}
</script>

4.2 类型断言处理

        使用useTemplateRef时,也会出现类型断言问题,此时上述代码会提示如下错误【类型“{}”上不存在属性“onLoadTableData”。】。

        此时,我们3.2中定义的新接口类型,指定给useTemplateRef即可,代码如下:

<template><div><table-normal ref="tableNormalRef"></table-normal><button @click="() => valueChange()">重新加载</button></div>
</template>
<script lang="ts" setup>
import { ref} from "vue";
// 定义新接口类型
interface LoadTableDataElement extends HTMLElement {onLoadTableData: () => void
}
const tableNormalRef = useTemplateRef<LoadTableDataElement>('tableNormalRef')// 重新加载
const valueChange = () => {if(tableNormalRef.value && tableNormalRef.value.onLoadTableData) tableNormalRef.value.onLoadTableData()
}
</script>

        在开发中,当遇到各种问题时,认真阅读错误提示,并根据问题逐一排查,相信大多情况能很快定位到问题,并得到解决的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com