PageRouter is a component that manages named routes of pages in a declarative rather than imperative manner. A PageRow is managed imperatively (i.e. rather than declaring that a button takes you to the login page, it imperatively pushes a new instance of a login page component on click) and the PageRouter abstracts the imperative behavior of a PageRow into a more declarative API. A PageRouter is designed for the usecase of complex and randomly accessible page hierarchies.
For example, Discover, an appstore application navigates linearly for the most part, using a sidebar for non-linear navigation purposes: A listing of categories (/home) brings you to a listing of items (/apps(science)) brings you to a details page (/app(org.kde.ScienceApp)). Directly accessing the PageRow here works fine, as navigation needs aren't very complex.
In comparison, a theoretical appstore application could have much more complex navigation. On startup, it would check if you're logged in or not, and set the initial route to /login or /home accordingly. A user could either click through the interface, browsing available applications in a relatively linear manner /apps(games), then /app(org.kde.TetrisClone), or they could use a search field located on the home page, bringing them directly to /home/apps(games)/app(org.kde.TetrisClone). Or, an app store could be running a promotion, and the route would look like /home/promotions(BestGames2020)/app(org.kde.TetrisClone), bringing the user to the same page in a different hierarchy. A PageRow doesn't scale as nicely in this usecase, as there are a wide variety of pages in a hierarchy that can be navigated in a random order.
Handling of communicating between the parent PageRouter and the child Page is also abstracted in a nicer API—the Kirigami.PageRouter attached object is used for navigation instead of passing an id around, and its data property is used for data passing instead of pushing a page and setting a property on it.