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

[bug report] layout component. When modifying the jitter value passed to the El row component, the component does not update the column interval value correctly #1441

Closed
SorrowX opened this issue Feb 7, 2021 · 4 comments · Fixed by #1537
Labels
Project::Bug Something isn't working

Comments

@SorrowX
Copy link
Contributor

SorrowX commented Feb 7, 2021

Element Plus version

1.0.2-beta.31

OS/Browsers version

Microsoft Edge 版本 88.0.705.56 (官方内部版本) (64 位)

Vue version

3.0.5

Reproduction Link

https://jsfiddle.net/3gpamjny/6/

Steps to reproduce

  1. 打开https://jsfiddle.net/3gpamjny/6/ 网址运行
    2.点击修改‘修改gutter值’按钮
    3.el-row根元素正确更新,el-col的根元素未更新

What is Expected?

1.期望el-col根元素的样式padding-left和padding-right的值正确更新。

2.element-ui layout组件是正常的,因为col组件是通过递归获取父元素的gutter,而父元素的gutter是响应式值,对col组件的render watch实例进行了依赖收集,所以gutter值变化后,col组件能正常更新。其实element-ui layout组件也可以使用inject和provide来优化。

3.关于element-plus layout组件这个bug的修改,我下面提供下我的思路,希望可以参考下

a.这个bug的根本原因是

col.ts文件中

const gutter = inject('ElRow', 0)

const style = computed(() => {
  if (gutter) {
    return {
      paddingLeft: gutter / 2   'px',
      paddingRight: gutter / 2   'px',
    }
  }
  return {}
})

gutter值是非响应式值,导致style的值永远都是第一次求值完的值,所以才有这个bug。

b.解决方案一:

row.ts文件

setup(props, { slots }) {

const status = reactive({ gutter: props.gutter})
provide('status', status)  // 这里提供一个响应式值,在provide内部实现不会对status进行拷贝

// ...

return () => {
    status.gutter = props.gutter // 这里对响应式值进行赋值从而触发他收集的effect包装函数执行
    return h(
        props.tag,
        {
            class: [
                'el-row',
                props.justify !== 'start' ? `is-justify-${props.justify}` : '',
                props.align !== 'top' ? `is-align-${props.align}` : '',
                props.type === 'flex' ? 'el-row--flex' : '',
            ],
            style: style.value,
        },
        slots.default?.(),
    )
}

}

col.ts 文件

setup(props, { slots }) {

const status = inject('status', { gutter: 0 }) // 注入父组件提供的响应式数据

const style = computed(() => {
    const { gutter } = status // 对status.gutter求值,收集 computed effect包装函数

    if (gutter) {
        return {
            paddingLeft: gutter / 2   'px',
            paddingRight: gutter / 2   'px',
        }
    }
    return {}
})

// ...

}

这么改造完,就能解决这个问题。原理:父组件提供响应式值,子组件的计算属性依赖了该响应式值,从而当响应式发生变化后,计算属性下次求值才能得到最新值。

4.第一次提issue,如果格式不对,请删除。还有我想为element-plus尽一份力,不知道咋搞,头疼

What is actually happening?

1.实际上只有el-row的margin-left和margin-right的值正确更新了

@element-bot element-bot changed the title [Bug Report] Layout 布局组件,当修改传给el-row组件的gutter值时,组件并没有正确的更新分栏间隔的值 [bug report] layout component. When modifying the jitter value passed to the El row component, the component does not update the column interval value correctly Feb 7, 2021
@element-bot
Copy link
Member

Translation of this issue:

Element Plus version

1.0.2-beta.31

OS/Browsers version

Microsoft edge version 88.0.705.56 (official build) (64 bit)

Vue version

3.0.5

Reproduction Link

https://jsfiddle.net/3gpamjny/6/

Steps to reproduce

  1. Open https://jsfiddle.net/3gpamjny/6/ Website operation

  2. Click the "modify jitter value" button

  3. The root element of El row is updated correctly, but the root element of El col is not updated

What is Expected?

  1. Expect the styles of padding left and padding right of El col root element to be updated correctly.

  2. The element UI layout component is normal, because the col component obtains the parent element's jitter by recursion, and the parent element's jitter is a responsive value. The render watch instance of the col component is collected by dependency, so the col component can be updated normally after the jitter value changes. In fact, the element UI layout component can also be optimized by using inject and provide.

  3. About the modification of the bug of element plus layout component, I'll provide my ideas for reference

a. The root cause of this bug is
col.ts In the file

const gutter = inject('ElRow', 0)
const style = computed(() => {

if (gutter) {
return {

paddingLeft: gutter / 2 'px',
paddingRight: gutter / 2 'px',

}
}

return {}
})

The value of gutter is non responsive, so the value of style is always the value evaluated for the first time. That's why there is this bug.
b. Solution 1:

row.ts file
setup(props, { slots }) {

const status = reactive({ gutter: props.gutter })
Provide ('status', status) / / a response value is provided here. The internal implementation of provide will not copy the status

// ...
return () => {

status.gutter = props.gutter //Here, the response value is assigned to trigger the execution of the effect wrapper function he collects
return h(

props.tag ,
{

class: [
'el-row',

props.justify !== 'start' ? is-justify-${ props.justify } : '',
props.align !== 'top' ? is-align-${ props.align } : '',

props.type === 'flex' ? 'el-row--flex' : '',
],

style: style.value ,
},

slots.default? .(),
)

}
}

col.ts file
setup(props, { slots }) {

Const status = inject ('status', {gutter: 0}) / / inject the responsive data provided by the parent component
const style = computed(() => {

Const {gutter} = status / / Yes status.gutter Evaluate and collect the computed effect wrapper function
if (gutter) {

return {
paddingLeft: gutter / 2 'px',

paddingRight: gutter / 2 'px',
}

}
return {}

})
// ...

}
After this transformation, this problem can be solved. Principle: the parent component provides the response value, and the calculation property of the child component depends on the response value, so when the response is changed, the calculation property can be evaluated next time to get the latest value.

  1. If the format of issue is wrong, please delete it. And I want to do my part for element plus. I don't know what to do. I have a headache

What is actually happening?

  1. In fact, only the margin left and margin right values of El row are updated correctly

@Ryan2128
Copy link
Member

Ryan2128 commented Feb 7, 2021

Thanks, there is indeed a problem here, if you are interested in this, you can fork this repo, and open a pr after making changes, we will review and merge it.

@Ryan2128 Ryan2128 added the Project::Bug Something isn't working label Feb 7, 2021
@SorrowX
Copy link
Contributor Author

SorrowX commented Feb 7, 2021

@Ryan2128 of course, I'm very interested. I try my best to submit a pr.

@Ryan2128
Copy link
Member

Ryan2128 commented Feb 7, 2021

@Ryan2128 of course, I'm very interested. I try my best to submit a pr.

Thanks.

@Ryan2128 Ryan2128 mentioned this issue Feb 21, 2021
3 tasks
@Ryan2128 Ryan2128 mentioned this issue Mar 1, 2021
3 tasks
@github-actions github-actions bot locked and limited conversation to collaborators Dec 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Project::Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants