This part of StructArrays is less known, but works fine:
julia> foo = StructArray([Foo(SubFoo(1, 2, 3), 1), Foo(SubFoo(1, 2, 3), 2)]; unwrap=T -> fieldcount(T) > 0)
2-element StructArray(StructArray(::Vector{Int64}, ::Vector{Int64}, ::Vector{Int64}), ::Vector{Int64}) with eltype Foo{Int64}:
Foo{Int64}(SubFoo{Int64}(1, 2, 3), 1)
Foo{Int64}(SubFoo{Int64}(1, 2, 3), 2)
julia> foo.a.x
2-element Vector{Int64}:
1
1
And just in case you need something even fancier:
julia> using AccessorsExtra, SplitApplyCombine
julia> ax = mapview(@optic(_.a.x + 10), foo)
2-element <...>:
11
11
julia> ax[1] = 0
0
julia> foo
2-element <...>:
Foo{Int64}(SubFoo{Int64}(-10, 2, 3), 1)
Foo{Int64}(SubFoo{Int64}(1, 2, 3), 2)
Works with all arrays including Base Vectors.