You are better off thinking that in Mathematica you can control when and if an expression evaluates or not. But, if it evaluates, it does it until it doesn't change any more. In this case, you can make expr either stay as is, or evaluate
expr->{v,u}->{{v1,v2}+{u1, u2}}->{{v1+u1, v2+u2}};
Actually, since your definition of expr is immediate (you used Set) it is actually stored as {{v1+u1, v2+u2}} already.
If you don't want that to happen, you have to change your design (for example, using a wrapper other than List for your vectors), or temporarily disable the definitions you want to hold.
For example, change your expr definition to a SetDelayed
expr := v + w; and now either block Plus (so it is no longer Listable while you distribute), or block your symbols
Block[{Plus}, Distribute@f[u, expr]] Block[{v, w}, Distribute@f[u, expr]] g[{u1, u2}, {v1, v2}] + g[{u1, u2}, {w1, w2}]
g[{u1, u2}, {v1, v2}] + g[{u1, u2}, {w1, w2}]