Typescript 在从CompositionAPI创建的生命周期钩子中使用此钩子

Typescript 在从CompositionAPI创建的生命周期钩子中使用此钩子,typescript,vue.js,vuejs3,Typescript,Vue.js,Vuejs3,我对VUE3中的typescript有问题 每次修改“查询”属性时从Itunes获取数据。(格式:[{},{},{},{},…] 调用函数从获取中筛选未使用的信息 在fetch中调用函数(此函数将过滤对象以简化代码)时,它会抛出一个错误: Property 'filterData' does not exist on type 'void'. 我的代码: <template> <div> </div> </template> &

我对VUE3中的typescript有问题

  • 每次修改“查询”属性时从Itunes获取数据。(格式:[{},{},{},{},…]
  • 调用函数从获取中筛选未使用的信息
  • 在fetch中调用函数(此函数将过滤对象以简化代码)时,它会抛出一个错误:

    Property 'filterData' does not exist on type 'void'.
    
    我的代码:

    <template>
        <div>
        </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, onUpdated } from 'vue';
    
    interface Song {
        id: number;
        name: string;
        nameT: string;
        cover?: string;
        preview: string;
    }
    
    interface SongFromITunes {
        artistId: number;
        artistName: string;
        trackName: string;
        previewUrl: string;
        artworkUrl100?: string;
    }
    
    export default defineComponent({
        data() {
            return {
                list: [] as Array<Song>
            };
        },
        props: {
            query: String
        },
        methods: {
            filterData({
                artistId: id,
                artistName: name,
                trackName: nameT,
                artworkUrl100: cover,
                previewUrl: preview
            }: SongFromITunes): Song {
                return { id, name, nameT, cover, preview };
            }
        },
        setup(props) {
            onUpdated(() => {
                const { query } = props;
                if (query != null) {
                    fetch(
                        `https://itunes.apple.com/search?term=${encodeURI(
                            query
                        )}&limit=10&entity=musicTrack`
                    )
                        .then((resolve) => resolve.json())
                        .then((data) => data.results.map((item: SongFromITunes) => this.filterData(item));
                }
            });
        }
    });
    </script>
    
    <style scoped></style>
    
    
    从“vue”导入{defineComponent,onUpdate};
    接口歌曲{
    id:编号;
    名称:字符串;
    nameT:字符串;
    封面?:字符串;
    预览:字符串;
    }
    iTunes的接口{
    艺术家:数字;
    艺人名称:弦;
    trackName:string;
    previewUrl:字符串;
    artworkUrl100?:字符串;
    }
    导出默认定义组件({
    数据(){
    返回{
    列表:[]作为数组
    };
    },
    道具:{
    查询:字符串
    },
    方法:{
    过滤数据({
    艺人:身份证,
    艺人姓名:姓名,
    trackName:nameT,
    artworkUrl100:封面,
    预览:预览
    }:歌曲来自iTunes):歌曲{
    返回{id,name,nameT,cover,preview};
    }
    },
    设置(道具){
    未更新(()=>{
    const{query}=props;
    if(查询!=null){
    取回(
    `https://itunes.apple.com/search?term=${encodeURI(
    查询
    )}&限制=10&实体=musicTrack`
    )
    。然后((resolve)=>resolve.json()
    .然后((数据)=>data.results.map((项:SongFromITunes)=>this.filterData(项));
    }
    });
    }
    });
    
    由于尚未创建组件,因此无法从设置功能访问此
    。您还需要在设置中定义
    过滤器数据


    我发现你的问题很有趣

    很明显,
    不能在
    设置()中使用,因为Vue实例尚不存在

    但是在使用生命周期挂钩的情况下,您将传递回调,该回调必须在以后某个时候附加到新的Vue实例

    :这些生命周期挂钩注册函数只能在
    setup()
    期间同步使用,因为它们依赖于内部全局状态来定位当前活动实例(其
    setup()
    正在被调用的组件实例)

    因此,如果Vue只使用
    bind
    并将回调绑定到实例,那么这样做似乎是很容易的

    您的解决方案是将
    filterData
    methods
    移动到
    setup()

    设置(道具){
    设filterData=函数({
    艺人:身份证,
    艺人姓名:姓名,
    trackName:nameT,
    artworkUrl100:封面,
    预览:预览
    }:歌曲来自iTunes):歌曲{
    返回{id,name,nameT,cover,preview};
    }
    未更新(()=>{
    const{query}=props;
    if(查询!=null){
    取回(
    `https://itunes.apple.com/search?term=${encodeURI(
    查询
    )}&限制=10&实体=musicTrack`
    )
    。然后((resolve)=>resolve.json()
    .然后((数据)=>data.results.map((项目:SongFromITunes)=>filterData(项目));
    }
    });
    返回{filterData}
    }
    
    更新 我真的很好奇这背后的原因,因为我觉得钩子天生就与实例绑定在一起,可能很多人都希望
    这个
    可以在回调中使用。所以我在Vue discord上询问了一下,并得到了以下解释(感谢Vaage 9161):

    如果我们将安装程序中的生命周期挂钩绑定到实例,这只会导致混乱并鼓励反模式。 您可以选择options api或composition api。如果您选择composition api,则此
    上没有您感兴趣的内容。所有内容都包含在
    设置
    闭包中。 如果我们添加了它,typescript推断将更难实现,人们将开始结合使用options api

    今日讯息 不要将合成api和选项api混为一谈

    “每日信息”:确切地说,决定在项目中使用什么,并坚持下去!