My experience with Vue has been pretty mixed here, though. It's nice having everything in one file, sure, but it's also a pain having to create a new file whenever you want a new component. In JSX-based frameworks, I tend to start with a component in a file, then split it up into multiple components in one file, then finally into different components in different files as I'm going along - the same as I would do for normal Javascript functions. That's difficult to do in Vue, and I often find components tend to grow much larger and more unwieldy because it's easier to just add more to a single component than to split it into multiple components.
I also like the way CSS is built in, but I'm unconvinced that magic style scoping is all that helpful. I found myself fighting against it, and trying to remember the correct `::v-deep` incantation more often than I'd like. For me, the ideal abstraction here is CSS modules, where the class names are scoped, but the actual declarations behave like normal CSS. I never managed to get CSS modules to work with Vue, but we were stuck on Vue 2 for a long time, and that might have changed with more recent versions.
But I think that's the thing: there isn't really a clear "best in class" here. Different tools work for different people and in different contexts. You talk about the awfulness of CSS-in-JS, but last time I used it, I found it gave a really good balance between conventional CSS (albeit not in CSS format), while still being collocated with JS components. There are definitely downsides, but there are downsides in most of these solutions.