项目中由前端处理得到修改预览数据并在列表中展示,为了更好地体验添加分页,框架基于ant-design.
部分代码如下:
<a-spin>
<a-table :columns="columns" :dataSource="modifyData1" rowKey="id" :pagination="false" bordered></a-table>
<my-pagination v-if="total !== 0" :total="total" v-model="pageNum" :pageSize.sync="pageSize" @change="handlePageChange" @showSizeChange="showSizeChange"></my-pagination>
</a-spin>
正确代码:
<script>
import myPagination from '@/components/data/pagination'
export default {
name: 'example',
props: {
visible: {
type: Boolean,
default: false,
},
modifyData: {
type: Array,
},
},
components: {
myPagination,
},
data () {
return {
module: module, // 模块名
columns: [
...
...
],
modifyData1: [],
total: 0,
pageNum: 1,
pageSize: 10,
paginationData: [], // 前端分页的全量数据
}
},
watch: {
modifyData (val) {
this.modifyData1 = val // 新增 modifyData 的 watch,监听变更并同步到 modifyData1 上
},
visible (val) {
if (val) {
this.init()
}
},
},
methods: {
init () {
this.paginationData = this.modifyData1
this.total = this.paginationData.length
this.getData()
},
handlePageChange (pageNum, pageSize) {
this.pageNum = pageNum
this.pageSize = pageSize
this.getData()
},
showSizeChange (pageNum, pageSize) {
this.pageNum = pageNum
this.pageSize = pageSize
this.getData()
},
getData () {
this.modifyData1 = this.paginationData.filter((item, index) => { // 前端数据分页
return index >= (this.pageNum - 1) * this.pageSize && index < this.pageNum * this.pageSize
})
},
...
...
},
}
</script>
其中,modifyData 为父组件中处理后传到子组件的值,子组件拿到全量数据后进行分页处理,一开始的写法是直接处理modifyData,即:
<a-table :columns="columns" :dataSource="modifyData" rowKey="id" :pagination="false" bordered></a-table>
...
<script>
...
watch: {
visible (val) {
if (val) {
this.init()
}
},
},
methods: {
init () {
this.paginationData = this.modifyData
this.total = this.paginationData.length
this.getData()
},
...
getData () {
this.modifyData = this.paginationData.filter((item, index) => { // 数据分页
return index >= (this.pageNum - 1) * this.pageSize && index < this.pageNum * this.pageSize
})
},
...
</script>
浏览器报错:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “modifyData”
问题出现在子组件中 getData () 方法中,这里对 prop 中定义的 modifyData 变量进行了赋值操作,其值本应来自父组件传递,不倡导在子组件中对其做更改,也就是单向数据流。
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
解决方法:创建针对props属性的watch来同步组件外对props的修改
watch: {
modifyData (val) {
this.modifyData1 = val // 新增 modifyData 的 watch,监听变更并同步到 modifyData1 上
},
},