The Italian champion benefited from an almost flawless lead-out from his Quick-Step team, who drove the front of the bunch in the peloton and dropped Viviani off in the final stretch to the line with his last men of Michael Mørkøv and Fabio Sabatini.
Viviani was then left to open up his sprint with just over 100m to go, with Sagan unable to come round him despite sitting on his wheel.
Nizzolo was also unable to match the speed of his compatriot and was just pipped to the line for second by world champion Sagan.
It's Viviani's 17th victory of the season in what has been his best year to date in his career after taking four stage victories at the Giro d'Italia in May.
Simon Yates (Mitchelton-Scott) holds on to the overall lead with his one second advantage over Alejandro Valverde (Movistar) in second place.
How it happened
The Vuelta a España peloton faced one of the flattest stages of the race on stage 10's 177km route from Salamanca to Bermillo de Sayago, with just the category three climb of Alto de Fermoselle to come with 147.9km gone.
That climb would be unlikely to stop the sprinters from making it to the flat run-in to the finish, while it was also unlikely that a breakaway would succeed on such a flat stage.
That didn't stop Jesus Ezquerra (Burgos-BH) getting away early, establishing a 1-50 gap alone to the peloton. There were several attacks by riders in the opening kilometres to try to bridge to him, with Richie Porte (BMC Racing) trying to get across with Tiago Machado (Katusha-Alpecin).
Porte soon sat back to be swallowed up by the bunch, while Machado made a big effort to get across, finally reaching the lone leader with around 140km to go.
Ezquerra and Machado established a maximum gap of around four minutes, but that steadily began to drop as the sprinters teams kept things in check on the front of the peloton.
The only real incident of not heading into the final 50km saw a crash between Jelle Wallays (Lotto-Soudal) and Simone Petilli (UAE Team Emirates), with the latter coming off worse as he was stretchered away by medical staff and forced to abandon the race.
On to the only climb and breakers only had around a minute on the peloton. The peloton then turned up the speed in final 35km, and eventually forced Ezquerra to relent and give up his breakaway effort, while Machado pushed on. The Portuguese didn't hold on for long though before he too was caught.
The was then a counter attack by Ezquerra's team-mate Diego Rubio with 20km, while notable riders including race leader Simon Yates and Nairo Quintana (Movistar) suffered punctures but were able to get back in within the final 15km.
With the race set for a sprint finish, Quick-Step did the bulk of the work driving on the front for Elia Viviani. They were able to stop Lukas Postlberger (Bora-Hansgrohe) from making a late solo attack, and set Viviani up for his final sprint where he was able to hold off Sagan and Nizzolo for his second victory of the Vuelta.
The Vuelta a España continues on Wednesday with a long stage for the riders with 208.7km from Mombuey to Luintra.
Vuelta a España 2018, stage 10: Salamanca. VIII Centenario Universidad de Salamanc to Fermoselle. Bermillo de Sayago (177k)
1 Elia Viviani (Ita) Quick-Step Floors, in 4-08-08
2 Peter Sagan (Svk) Bora-Hansgrohe
3 Giacomo Nizzolo (Ita) Trek-Segafredo
4 Nelson Andres Soto Martinez (Col) Caja Rural-Seguros RGA
5 Marc Sarreau (Fra) Groupama-FDJ
6 Danny van Poppel (Ned) LottoNL-Jumbo
7 Ivan Garcia (Esp) Bahrain-Merida
8 Jon Aberasturi Izaga (Esp) Euskadi Basque Country-Murias
9 Simone Consonni (Ita) UAE Team Emirates
10 Matteo Trentin (Ita) Mitchelton-Scott, all same time
Overall classification after stage 10
1 Simon Yates (GBr) Mitchelton-Scott, in 41-03-00
2 Alejandro Valverde (Esp) Movistar Team, at 1s
3 Nairo Quintana (Col) Movistar Team, at 14s
4 Emanuel Buchmann (Ger) Bora-Hansgrohe, at 16s
5 Ion Izagirre (Esp) Bahrain-Merida, at 17s
6 Tony Gallopin (Fra) AG2R La Mondiale, at 24s
7 Miguel Angel Lopez (Col) Astana Pro Team, at 27s
8 Rigoberto Uran (Col) EF Education First-Drapac, at 32s
9 Steven Kruijswijk (Ned) LottoNL-Jumbo, 43s
10 George Bennett (NZl) LottoNL-Jumbo, 48s
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1