eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

Warn destructing attrs & slots

Open jd-solanki opened this issue 2 years ago • 12 comments

Please describe what the rule should do:

What category should the rule belong to?

[ ] Enforces code style (layout) [x] Warns about a potential error (problem) [ ] Suggests an alternate way of doing something (suggestion) [ ] Other (please specify:)

Provide 2-3 code examples that this rule should warn about:

setup(props, { attrs, slots }) {
  const { slotFoo, slotBar } = slots
  const { id, hidden } = attrs
}

Additional context According to vue docs, destructured attrs & slots aren't reactive. Hence, we should not destructure them in setup function.

attrs and slots are stateful objects that are always updated when the component itself is updated. This means you should avoid destructuring them and always reference properties as attrs.x or slots.x. Also note that, unlike props, the properties of attrs and slots are not reactive.

EDIT: Sample code updated, Thanks @FloEdelmann

jd-solanki avatar Sep 09 '22 10:09 jd-solanki

I think your example code is fine. But this would not be:

setup(props, { attrs, slots }) {
  const { slotFoo, slotBar } = slots
  const { id, hidden } = attrs
}

FloEdelmann avatar Sep 09 '22 11:09 FloEdelmann

Oh, Yes. I totally misunderstood that.

docs are pointing to not destructure the attrs & slots. I thought it destructing the ctx. Silly me.

Do we have eslint rule for it.

I will update the sample code.

jd-solanki avatar Sep 09 '22 11:09 jd-solanki

We have a similar rule: https://eslint.vuejs.org/rules/no-setup-props-destructure.html

Maybe it could be modified to also check attrs and slots.

FloEdelmann avatar Sep 09 '22 12:09 FloEdelmann

Related to #1949.

FloEdelmann avatar Sep 09 '22 12:09 FloEdelmann

Hmm... I don't think attrs and slots are reactive, destructured or not.

So they should be used more carefully. I find it difficult to check well.

For example, use onBeforeUpdate to handle:

setup(props, { attrs, slots }) {
  let { slotFoo, slotBar } = slots
  let { id, hidden } = attrs
  // ...
  onBeforeUpdate(() => {
    ;({ slotFoo, slotBar } = slots)
    ;({ id, hidden } = attrs)
    // ...
  })
}

Using destructuring, but I don't think the above is wrong.

ota-meshi avatar Sep 12 '22 06:09 ota-meshi

I don't think attrs and slots are reactive

They are stateful as mentioned in docs

jd-solanki avatar Sep 12 '22 06:09 jd-solanki

Yes. In other words, the example code you provided is neither right nor wrong. Even with destructuring, it will probably behave correctly depending on how the value of is handled.

setup(props, { attrs, slots }) {
   const { slotFoo, slotBar } = slots
   const { id, hidden } = attrs
}

What would your proposed rule check for?

ota-meshi avatar Sep 12 '22 06:09 ota-meshi

What would your proposed rule check for?

It will assure that we don't destructure the attrs & slots.

In my lib anu-vue I previously had this destructuring which was causing reactivity lost.

E.g. If I pass type attribute as ref and change it via button click then its type value doesn't get updated from text to password.

Thanks.

jd-solanki avatar Sep 12 '22 06:09 jd-solanki

Did you fix it? I think the attrs.id of the main branch is still lost in reactivity.

https://github.com/jd-solanki/anu/blob/6796c843812cb9ec3cd1e0cd337866df40967439/packages/anu-vue/src/components/base-input/ABaseInput.tsx#L24

ota-meshi avatar Sep 12 '22 06:09 ota-meshi

I think the attrs.id of the main branch is still lost in reactivity

Let me check

jd-solanki avatar Sep 12 '22 08:09 jd-solanki

Below code in my playground is working fine on main branch:

<script lang="ts" setup>
import { ref } from "vue";

const inputType = ref("password");
const toggleType = () => {
  console.log("clicked");
  inputType.value = inputType.value === "text" ? "password" : "text";
};
</script>

<template>
    <AInput :type="inputType" modelValue="text"></AInput>
    <ABtn @click="toggleType">Toggle type</ABtn>
</template>

It is working fine: chrome-capture-2022-8-12

Now even docs is confusing me 🤣

It states attrs & slots "stateful objects". Moreover, there's also "properties of attrs and slots are not reactive".

IG someone better than me needs to comment on this or I should try this in SFC playground.

jd-solanki avatar Sep 12 '22 09:09 jd-solanki

Can you provide a SFC playground link to try out your components?

ota-meshi avatar Sep 12 '22 11:09 ota-meshi