Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When i use setup function in vue2 project i get some error in console #693

Closed
BABA983 opened this issue May 10, 2021 · 8 comments · Fixed by #737
Closed

When i use setup function in vue2 project i get some error in console #693

BABA983 opened this issue May 10, 2021 · 8 comments · Fixed by #737
Labels
bug Something isn't working needs reproduction We need a runnable reproduction from the OP

Comments

@BABA983
Copy link

BABA983 commented May 10, 2021

<script lang="ts">
import {
  defineComponent,
  ref,
  reactive,
  computed,
  onActivated,
  getCurrentInstance,
  ComponentInternalInstance,
  onBeforeMount,
  onMounted,
  SetupContext
} from '@vue/composition-api';
import DownloadDialog from '@/components/dialog/downloadDialog.vue';
import EmptyList from '@/components/emptyList/index.vue';
import Pagination from '@/components/Pagination/index.vue';
import ProtocolViewer from '@/components/protocolViewer/index.vue';
import * as dateUtil from '@/utils/dateUtil';
import { isPositiveNum } from '@/utils/formValidate';
import { clearObjectValue } from '@/utils/utils';
// import { Component, Ref, Vue } from 'vue-property-decorator';
import agreementMixin from '../composables/agreement.js';

interface IBillStatusItem {
  name: string;
  value: string;
}

export default defineComponent({
  components: { EmptyList, ProtocolViewer, DownloadDialog, Pagination },
  data() {
    return {};
  },
  setup(props: any, context: SetupContext) {
    let hasData = ref(false),
      billStatus: Array<IBillStatusItem> = reactive([]),
      form = reactive({
        billCode: '',
        billMaxMoney: '',
        billMinMoney: '',
        maturityDate: [],
        outputDate: [],
        inputName: '',
        outputName: '',
        queryType: ''
      }),
      pageSize = ref(10),
      pageNum = ref(1),
      total = ref(0),
      list: any = ref([]),
      blockHeight = ref(0),
      maturityStartDate = computed(() => {
        return form.maturityDate && form.maturityDate[0]
          ? dateUtil.getValueOfDateStart(form.maturityDate[0])
          : '';
      }),
      maturityEndDate = computed(() => {
        return form.maturityDate && form.maturityDate[1]
          ? dateUtil.getValueOfDateEnd(form.maturityDate[1])
          : '';
      }),
      outputStartDate = computed(() => {
        return form.outputDate && form.outputDate[0]
          ? dateUtil.getValueOfDateStart(form.outputDate[0])
          : '';
      }),
      outputEndDate = computed(() => {
        return form.outputDate && form.outputDate[1]
          ? dateUtil.getValueOfDateEnd(form.outputDate[1])
          : '';
      }),
      { proxy } = getCurrentInstance() as ComponentInternalInstance;
    const getList = async () => {
        console.log('getList');
      },
      resetSearch = () => {
        // some logic
      },
      exportExcel = () => {
        // some logic
      };

    onBeforeMount(() => {
      console.log('beforeMount')
    });
    onMounted(() => {
      console.log('mounted!');
    });
    onActivated(async () => {
      getList();
    });

    return {
      hasData,
      billStatus,
      form,
      pageSize,
      pageNum,
      total,
      list,
      blockHeight,
      maturityStartDate,
      proxy,
      ...agreementMixin(),
      getList,
      resetSearch,
      exportExcel
    };
  }
});
</script>

it show this error in console
image

and if my getList,resetSearch,exportExcel these 3 function return at the end.Vue will warn

 return {
      ...
      getList,
      resetSearch,
      exportExcel
    };
  }

image

but if i put them at the beginning like this,it will be fine

      return {
         getList,
         resetSearch,
         exportExcel
         ...
         ...agreementMixin
}

but the [Vue warn]: Error in data(): "TypeError: Cannot use 'in' operator to search for '__ob__' in undefined" error still show up in the console
image

@pikax pikax added bug Something isn't working needs reproduction We need a runnable reproduction from the OP labels May 10, 2021
@pikax
Copy link
Member

pikax commented May 10, 2021

Do you mind provide a repository with reproducible code?

The code you provided relies heavily on code that's not provided.

@BABA983
Copy link
Author

BABA983 commented May 11, 2021

Do you mind provide a repository with reproducible code?

The code you provided relies heavily on code that's not provided.
@pikax
sry,these code not comes from my own project.
But i use vue-cli create an vue2 project with the v4.5.10 and the error still show up in the console
image
and i put the code snippets in this project vue2-composition-test

This is my first time new an issue,dont know too much about the issue standard so the reply looks a little messy.

My english is so bad :( . I hope this can help <3

xinpingwang added a commit to xinpingwang/vue-composition-api-setup that referenced this issue May 11, 2021
@xinpingwang
Copy link

xinpingwang commented May 11, 2021

I created a repo to reproduce this issue, this issue is cause by the flowing code:

import { getCurrentInstance } from '@vue/composition-api'

export default {
  name: 'App',
  setup() {
    const { proxy } = getCurrentInstance()
    return { proxy }
  }
}

@ygj6
Copy link
Member

ygj6 commented May 12, 2021

@SKADaddy Use it like below, will work fine.

import { getCurrentInstance, onMounted } from '@vue/composition-api'

export default {
  name: 'App',
  setup() {
    let proxy
    onMounted(() => {
            proxy = getCurrentInstance()
          })
    return { proxy }
  }
}

@BABA983
Copy link
Author

BABA983 commented May 12, 2021

@xinpingwang if destruct the proxy from getCurrentInstance() will cause the problem, how can i access the function which on the Vue prototype

@xinpingwang
Copy link

@SKADaddy Don't know how you want to use the proxy. In my sense:

  1. if you want to use function on Vue prototype inner setup function, you do not need to return it;
  2. if you have other option like methods or lifecycle hooks, you can you this inner that function.

@BABA983
Copy link
Author

BABA983 commented May 13, 2021

@ygj6 but if i want to use proxy in beforeCreate or created hook like vue2, how can i achieve that.I watch the document it said setup function replace beforeCreate and create

@xinpingwang
Copy link

xinpingwang commented May 13, 2021

I tracked the call stack, and find the the cause of this issue.

the returned proxy has a _renderProxy prop, which is a Proxy instance defined in Vue, with getHandler.

and inner initSetup will goes into call hasReactiveArrayChild at line 128

Object.keys(bindingObj).forEach((name) => {
let bindingValue: any = bindingObj[name]
if (!isRef(bindingValue)) {
if (!isReactive(bindingValue)) {
if (isFunction(bindingValue)) {
bindingValue = bindingValue.bind(vm)
} else if (!isObject(bindingValue)) {
bindingValue = ref(bindingValue)
} else if (hasReactiveArrayChild(bindingValue)) {
// creates a custom reactive properties without make the object explicitly reactive
// NOTE we should try to avoid this, better implementation needed
customReactive(bindingValue)
}
} else if (isArray(bindingValue)) {
bindingValue = ref(bindingValue)
}
}
asVmProperty(vm, name, bindingValue)
.

then hasReactiveArrayChild will check if _renderProxy isRaw.

if (!isPlainObject(target) || isRaw(target)) {

inner isRaw will try to get __ob__ and __ob__.__raw__ of _renderProxy.

export function isRaw(obj: any): boolean {
return Boolean(obj?.__ob__ && obj.__ob__?.__raw__)
}

since _renderProxy is a Proxy instance, then getHandler called. but _renderProxy.$data is undefined, error occurs.

https://github.com/vuejs/vue/blob/0603ff695d2f41286239298210113cbe2b209e28/src/core/instance/proxy.js#L68-L76

Don't this issue should fix in vuejs/vue or this project.

@pikax Any suggestion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs reproduction We need a runnable reproduction from the OP
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants