You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js 2.6.14中如何在setup()内访问data()中的属性?

问题解决:Vue 2.6.14中setup无法传入data里的form.style到vue-query查询函数

你遇到的核心问题是Vue 2的composition-api中,setup函数内无法直接通过this访问选项式API里的data属性——setup的执行时机早于组件实例初始化完成,且它本身没有绑定组件的this上下文,所以this.form.style根本取不到正确的值。

下面给两种可行的解决方式:


方式一:通过getCurrentInstance访问组件实例

借助@vue/composition-api提供的getCurrentInstance方法获取组件实例,进而访问data中的form.style,同时要确保查询的依赖项能被vue-query正确追踪:

<script lang="ts">
import { useQuery, getCurrentInstance } from '@vue/composition-api';
import type { ComponentInstance } from '@vue/composition-api';

const fetchRandomImg = async (style: FormType["style"]) => {
  const params = new URLSearchParams();

  if (style.type === "grayscale") {
    params.append("grayscale", "");
  } else if (style.type === "blur") {
    params.append("blur", style.blurValue.toString());
  }

  const response = await fetch(
    `https://picsum.photos/150?${params.toString()}`
  );

  const blob = await response.blob();
  return URL.createObjectURL(blob);
};

export default Vue.extend({
  data() {
    return {
      form: {
        style: {
          type: "normal",
          blurValue: 1
        },
        // ...其他属性
      }
    }
  },
  setup() {
    // 获取组件实例
    const instance = getCurrentInstance() as ComponentInstance;
    // 通过实例访问data中的form.style
    const formStyle = instance.proxy?.form.style;

    const { data: randomImg, refetch: refetchRandomImg } = useQuery(
      // 把style的关键属性作为查询键,确保变化时触发重查
      ["randomImage", formStyle.type, formStyle.blurValue],
      () => fetchRandomImg(formStyle),
      {
        refetchOnWindowFocus: false,
      }
    );

    return { randomImg, refetchRandomImg };
  },
})
</script>

注意:查询键不能直接传入对象(form.style),因为对象的引用变化才会触发重查,而修改对象内部属性不会触发。所以建议把对象的具体属性值作为查询键的一部分,比如type和blurValue,这样当这些值变化时,vue-query会自动重新发起请求。


方式二:将form.style移到setup中用reactive定义

更符合组合式API的写法是把响应式数据直接定义在setup里,避免选项式和组合式API混合带来的上下文问题:

<script lang="ts">
import { useQuery, reactive } from '@vue/composition-api';

const fetchRandomImg = async (style: FormType["style"]) => {
  // 原fetch逻辑不变
  const params = new URLSearchParams();

  if (style.type === "grayscale") {
    params.append("grayscale", "");
  } else if (style.type === "blur") {
    params.append("blur", style.blurValue.toString());
  }

  const response = await fetch(
    `https://picsum.photos/150?${params.toString()}`
  );

  const blob = await response.blob();
  return URL.createObjectURL(blob);
};

export default Vue.extend({
  setup() {
    // 用reactive定义响应式的form数据
    const form = reactive({
      style: {
        type: "normal",
        blurValue: 1
      },
      // ...其他属性
    });

    const { data: randomImg, refetch: refetchRandomImg } = useQuery(
      // 同样用具体属性作为查询键
      ["randomImage", form.style.type, form.style.blurValue],
      () => fetchRandomImg(form.style),
      {
        refetchOnWindowFocus: false,
      }
    );

    // 把form也返回,供模板使用
    return { randomImg, refetchRandomImg, form };
  },
})
</script>

这种写法更清晰,响应式依赖追踪也更可靠,推荐优先使用。


内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 03:05:16