Only if you use the syntax you showed, yes. An alternative would be to use the TList<T>.List property instead, which gives you somewhat more direct access to the internal array:
procedure TForm1.FormCreate(Sender: TObject);
var
...
vList: TList<TRecLine>;
vNode: PVirtualNode;
...
begin
...
vList.List[0].VirtualNode := vNode;
...
end;
Or, use the TList<T>.PList property instead, which is as bare-bones as you can get to the internal array:
type
TRecLine = record
...
end;
PRecLine = ^TRecLine;
procedure TForm1.FormCreate(Sender: TObject);
var
...
vList: TList<TRecLine>;
vNode: PVirtualNode;
...
begin
...
(PRecLine(vList.PList)+0{Index}).VirtualNode := vNode;
...
end;
Do note that System.TArray<T> (not to be confused with System.Generics.Collections.TArray<T>) has supported insert and concatenation operations since XE7. See String-Like Operations Supported on Dynamic Arrays and Dynamic Arrays in Delphi XE7.
VST doesn't care how you store your data, only that you should store a user-defined value inside each VST node so you can get back to your data given a node when needed.
The best way to do that would be to store an actual TRecLine pointer in the node, where that pointer points to an item in your TList/TArray. But, if you are going to be adding/removing items from your TList/TArray, then that gets dangerous since you will be invalidating stored pointers.
The next best option would be to store a TList/TArray index in each node instead, but then you have to worry about invalidating stored indexes.
The next best option might be to store a unique ID number in each TRecLine, and then store those IDs in each node, and look for them in your TList/TArray when needed, but then you get into performance issues having to re-iterate the TList/TArray all the time.
Certainly other options may exist, but what they are really depends on the design of your data and how you intend to use/manipulate it.