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
(1) expr -> (2) {v,w} -> (3) {{v1,v2}+{w1, w2}} -> (4) {{v1+w1, v2+w2}};
Actually, since your definition of expr is immediate (you used Set) it is actually stored as {{v1+w1, v2+w2}} 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 the distributibity to work, the evaluation must stop at step (2) or (3)
Change your expr definition to a SetDelayed
expr := v + w; and now either block Plus so it is no longer Listable while you distribute (step (3) ), or block your symbols (step (2) )
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}]
g[{u1, u2}, {v1, v2}] + g[{u1, u2}, {w1, w2}] g[{u1, u2}, {v1, v2}] + g[{u1, u2}, {w1, w2}]