File tree 2 files changed +43
-2
lines changed
2 files changed +43
-2
lines changed Original file line number Diff line number Diff line change 1
- import { isReactive , reactive , shallowReactive } from '../../src/index'
1
+ import {
2
+ effect ,
3
+ isReactive ,
4
+ reactive ,
5
+ readonly ,
6
+ shallowReactive ,
7
+ } from '../../src/index'
2
8
import { renderList } from '../../src/helpers/renderList'
3
9
4
10
describe ( 'renderList' , ( ) => {
@@ -65,4 +71,31 @@ describe('renderList', () => {
65
71
const shallowReactiveArray = shallowReactive ( [ { foo : 1 } ] )
66
72
expect ( renderList ( shallowReactiveArray , isReactive ) ) . toEqual ( [ false ] )
67
73
} )
74
+
75
+ it ( 'should not allow mutation' , ( ) => {
76
+ const arr = readonly ( reactive ( [ { foo : 1 } ] ) )
77
+ expect (
78
+ renderList ( arr , item => {
79
+ ; ( item as any ) . foo = 0
80
+ return item . foo
81
+ } ) ,
82
+ ) . toEqual ( [ 1 ] )
83
+ expect (
84
+ `Set operation on key "foo" failed: target is readonly.` ,
85
+ ) . toHaveBeenWarned ( )
86
+ } )
87
+
88
+ it ( 'should trigger effect for deep mutations in readonly reactive arrays' , ( ) => {
89
+ const arr = reactive ( [ { foo : 1 } ] )
90
+ const readonlyArr = readonly ( arr )
91
+
92
+ let dummy
93
+ effect ( ( ) => {
94
+ dummy = renderList ( readonlyArr , item => item . foo )
95
+ } )
96
+ expect ( dummy ) . toEqual ( [ 1 ] )
97
+
98
+ arr [ 0 ] . foo = 2
99
+ expect ( dummy ) . toEqual ( [ 2 ] )
100
+ } )
68
101
} )
Original file line number Diff line number Diff line change 1
1
import type { VNode , VNodeChild } from '../vnode'
2
2
import {
3
3
isReactive ,
4
+ isReadonly ,
4
5
isShallow ,
5
6
shallowReadArray ,
6
7
toReactive ,
8
+ toReadonly ,
7
9
} from '@vue/reactivity'
8
10
import { isArray , isObject , isString } from '@vue/shared'
9
11
import { warn } from '../warning'
@@ -69,14 +71,20 @@ export function renderList(
69
71
if ( sourceIsArray || isString ( source ) ) {
70
72
const sourceIsReactiveArray = sourceIsArray && isReactive ( source )
71
73
let needsWrap = false
74
+ let isReadonlySource = false
72
75
if ( sourceIsReactiveArray ) {
73
76
needsWrap = ! isShallow ( source )
77
+ isReadonlySource = isReadonly ( source )
74
78
source = shallowReadArray ( source )
75
79
}
76
80
ret = new Array ( source . length )
77
81
for ( let i = 0 , l = source . length ; i < l ; i ++ ) {
78
82
ret [ i ] = renderItem (
79
- needsWrap ? toReactive ( source [ i ] ) : source [ i ] ,
83
+ needsWrap
84
+ ? isReadonlySource
85
+ ? toReadonly ( toReactive ( source [ i ] ) )
86
+ : toReactive ( source [ i ] )
87
+ : source [ i ] ,
80
88
i ,
81
89
undefined ,
82
90
cached && cached [ i ] ,
You can’t perform that action at this time.
0 commit comments