如何给开源项目提 PR,给 layui - vue 提了个 PR,已合并
Pull Request 介绍
- 贡献者请项目维护者“拉取”修改的软件内容(因此称为拉取请求),若此修改内容应该成为正式代码库的一部分,就需要合并拉取请求中提到的软件内容。
- 最常用的方式是“Fork + Pull”模式:如果要为拉取请求创建新分支,又没有仓库的写入权限,可以先对仓库 Fork,仓库参与者不必向仓库创建者申请提交权限,而是在自己的托管空间下建立仓库的派生(Fork)。
- 拉取请求只能在不同的两个分支之间打开,可以在创建拉取请求时指定要将更改合并到哪个分支。
创建拉取请求
- Fork 创建存储库分支。
- 进行修复。
- 创建拉取请求。
- 在存储库的主页“Branch(分支)”菜单中,选择包含提交的分支。
- 在文件列表上方,单击 “拉取请求”。
- 使用基础分支下拉菜单选择要向其合并更改的分支,然后使用比较分支下拉菜单选择进行了更改的主题分支。
- 为你的拉取请求输标题和说明。
- 要创建可供审查的拉取请求,请单击“创建拉取请求”。若要创建草稿拉取请求,请使用下拉列表并选择“创建草稿拉取请求”,然后单击“草稿拉取请求”。
-
创建拉取请求后,你可以请求特定人员审查你提议的更改。如果你是组织成员,还可以请求特定团队审查你的更改。
-
在存储库名称下,单击 “拉取请求”。
- 在拉取请求列表中,单击你想要请求特定人员或团队审查的拉取请求。
- 导航到右侧边栏中的“审查者”。
- 若要向建议的人员请求审查,请在“审查者”下其用户名旁,单击“请求” 。
- (可选)若要向建议人员以外的其他人请求审查,请单击“审查者”,然后单击下拉菜单中的姓名。
更改后,可以请求审查者重新审查你的拉取请求。导航到右侧边栏中的“审查者”,然后单击你想要其审查的审查者姓名旁边的 。
- 被请求的审查者或团队将收到你请求他们审查拉取请求的通知。如果你请求团队审查,并启用了代码评审分配,则会向特定成员发出请求,并且取消团队作为审查者。
- 审查拉取请求后,对仓库具有推送权限的任何人都可以完成合并。
合并拉取请求
- 在存储库名称下,单击 “Pull requests”。
- 在“Pull Requests(拉取请求)”列表中,单击要合并的拉取请求。
- 根据对仓库启用的合并选项,你可以:
- 单击“合并拉取请求”,将所有提交合并到基分支中。 如果未显示“合并拉取请求”选项,则单击合并下拉菜单,然后选择“创建合并提交” 。
- 单击合并下拉菜单,选择“压缩并合并”,然后单击“压缩并合并”按钮,将多个提交压缩为一个提交。
- 单击合并下拉菜单,选择“变基并合并”,然后单击“变基并合并”按钮,将多个提交变基为一个基分支。
- 如有提示,输入提交消息,或接受默认消息。
- 单击“确认合并”、“确认压缩并合并”,或“确认变基并合并” 。
- (可选)删除分支。这有助于仓库的分支列表保持整洁。
给 layui- vue 提了个 PR,已合并
青训营中我们团队做的是组件库项目。因为我负责的是 Pagination
和 Table
组件,但 Ant Design Vue 和 Element Plus 的表格组件都太复杂了,所以我参考的是较简单的 layui - vue。
Bug
由于开发测试完组件后,也需要写对应的组件演示文档。在写文档过程中,发现了 Table
组件演示文档中的一个 Bug:
可以看到,行内编辑图标首次点击无效,只能从上到下开启编辑、从下到上关闭编辑,点击其他行图标也只从首行开始编辑。出问题的代码:
<template>
<lay-table :columns="columns28" :data-source="dataSource28">
<template #username="{ data }">
<lay-input v-if="edingKeys[data.id]" :model-value="data.username" @input="changeUsername($event, data)">
<template #suffix>
<lay-icon type="layui-icon-close" style="right:10px;" v-if="edingKeys[data.id]" @click="deleteEdit(data.id)"></lay-icon>
</template>
</lay-input>
<span v-else>
{{ data.username }}
<lay-icon type="layui-icon-edit" style="position: absolute;right: 10px;" v-if="!edingKeys[data.id]" @click="editHandle(data.id)"></lay-icon>
</span>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const edingKeys = ref([])
const columns28 = [
{
title:"账户",
width:"200px",
key:"username",
customSlot: "username"
},{
title:"密码",
width: "300px",
key:"password"
},{
title:"性别",
key:"sex"
},{
title:"年龄",
width: "300px",
key:"age"
},{
title:"备注",
width: "180px",
key:"remark",
ellipsisTooltip: true
}
]
const dataSource28 = ref([
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '}
])
const editHandle = (key) => {
edingKeys.value.push(key);
}
const deleteEdit = (key) => {
edingKeys.value.splice(edingKeys.value.indexOf(key),1);
}
const changeUsername = (val, data) => {
dataSource28.value.forEach(element => {
if(element.id == data.id) {
element.username = val;
}
});
}
return {
edingKeys,
deleteEdit,
columns28,
editHandle,
dataSource28,
changeUsername,
}
}
}
</script>
上面代码在 lay-input
、lay-icon type="layui-icon-close"
、lay-icon type="layui-icon-edit"
这三个组件上使用 v-if
表达式来条件性地渲染元素时,条件分别为 edingKeys[data.id]
、edingKeys[data.id]
和 !edingKeys[data.id]
。响应式变量 edingKeys
初始化时是一个空数组,在点击行编辑图标时,由绑定的 editHandle
方法将当前行的 id
字段添加到数组中,然后由响应式对象 edingKeys
根据行的 id
字段动态改变上述三个条件表达式的值,从而动态渲染行的编辑状态。
问题出在:id
字段是数字类型字符串,而 在 JavaScript 中,可以同时使用字符串 arr["1"]
或数字 arr[1]
访问对象属性和数组元素。
例如,当点击第三行的编辑图标时,editHandle
方法会将 "3"
添加到数组中,此时 edingKeys
的值为 ["3"]
,数组中只有一个元素,所以只有 edingKeys[0]
的条件为真,而 edingKeys[1]
、edingKeys[2]
以后的值都为 undefined
,条件都为假,所以第一次点击任何行时都不会有反应。然后我们点击第四行的编辑图标,此时 editHandle
方法会将 "4"
添加到数组中,此时 edingKeys
的值为 ["3", "4"]
,只有 edingKeys[0]
、edingKeys[1]
的条件为真,而 edingKeys[2]
、edingKeys[3]
以后的值都为 undefined
,条件都为假。所以第一行变成了编辑状态,而不是第三行或第四行。
以此类推,继续点击将依次从从上到下开启编辑状态。当点击任意某个已经开启编辑状态的行上的关闭图标时,deleteEdit
方法会将当前行的 id
字段从 edingKeys
数组中删除,edingKeys
数组的长度将减一。所以会从 edingKeys
数组的长度减一索引处,即从 edingKeys[edingKeys.length-1]
开始取消编辑。继续点击任意关闭图标,将依次从下到上关闭行编辑状态。
解决方法
很简单,只需要把三个 v-if
表达式的条件 edingKeys[data.id]
、edingKeys[data.id]
和 !edingKeys[data.id]
改为 edingKeys.includes(data.id)
、edingKeys.includes(data.id)
和 !edingKeys.includes(data.id)
,includes()
方法用来判断一个数组是否包含一个指定的值。
但更完善的方法是在 editHandle
方法中将整个行数据而不是行的 id
字段添加到数组中,然后使用 edingKeys.includes(data)
、edingKeys.includes(data)
和 !edingKeys.includes(data)
来判断编辑状态。因为行的 id
字段如果不是唯一的,即多行的 id
字段值相同,会出现点击一行的编辑和关闭图标,将同时开启和关闭多行的编辑状态。每行的行数据却是唯一的。
<template>
<lay-table :columns="columns28" :data-source="dataSource28">
<template #username="{ data }">
<lay-input v-if="edingKeys.includes(data)" :model-value="data.username" @input="changeUsername($event, data)">
<template #suffix>
<lay-icon type="layui-icon-close" style="right:10px;" v-if="edingKeys.includes(data)" @click="deleteEdit(data)"></lay-icon>
</template>
</lay-input>
<span v-else>
{{ data.username }}
<lay-icon type="layui-icon-edit" style="position: absolute;right: 10px;" v-if="!edingKeys.includes(data)" @click="editHandle(data)"></lay-icon>
</span>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const edingKeys = ref([])
const columns28 = [
{
title:"账户",
width:"200px",
key:"username",
customSlot: "username"
},{
title:"密码",
width: "300px",
key:"password"
},{
title:"性别",
key:"sex"
},{
title:"年龄",
width: "300px",
key:"age"
},{
title:"备注",
width: "180px",
key:"remark",
ellipsisTooltip: true
}
]
const dataSource28 = ref([
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '}
])
const editHandle = (data) => {
edingKeys.value.push(data);
}
const deleteEdit = (data) => {
edingKeys.value.splice(edingKeys.value.indexOf(data),1);
}
const changeUsername = (val, data) => {
dataSource28.value.forEach(element => {
if(element.id == data.id) {
element.username = val;
}
});
}
return {
edingKeys,
deleteEdit,
columns28,
editHandle,
dataSource28,
changeUsername,
}
}
}
</script>
修复后的效果:
提了 PR
由于 layui 仓库在 gitee,GitHub 上面的仓库已经撤下了,所以在 gitee 上面提的 PR,gitee PR 操作比 GitHub 更加方便和简单,在 Fork 项目的主页点击 + Pull Request
按钮,然后选择分支,输入标题和说明即可。
目前 已合并。