Vue is introducing support for declarative UI syntax, bringing it closer to mobile development patterns seen in Kotlin and Swift. This new approach moves away from traditional HTML templates, offering a more modern, type-safe way to build user interfaces.

The Evolution

Traditional Vue templates use HTML:

<template>
  <div class="container">
    <h1>{{ title }}</h1>
    <button @click="handleClick">Click me</button>
  </div>
</template>

The new declarative syntax is more similar to SwiftUI or Jetpack Compose:

<script setup>
import { View, Text, Button } from "vue-declarative";

const title = ref("Hello World");

function handleClick() {
  console.log("Clicked!");
}
</script>

<template>
  <View class="container">
    <Text>{{ title }}</Text>
    <Button onPress="{handleClick}">Click me</Button>
  </View>
</template>

Key Benefits

1. Type Safety

The declarative syntax provides better TypeScript support:

<View>
  <Text
    fontSize={16} // TypeScript knows this is a number
    color="blue" // TypeScript validates color values
  >
    Hello
  </Text>
</View>

2. Component Composition

Easier component composition similar to React or SwiftUI:

<script setup>
import { View, Text, Image } from "vue-declarative";

const Card = ({ title, image }) => (
  <View class="card">
    <Image src={image} />
    <Text>{title}</Text>
  </View>
);
</script>

3. Better Mobile Support

The syntax is more aligned with mobile development patterns, making it easier to share code between web and mobile:

// Works similarly on web and mobile
<View>
  <Text>Cross-platform component</Text>
</View>

Comparison with Other Frameworks

SwiftUI (iOS)

VStack {
  Text("Hello")
  Button("Click") {
    handleClick()
  }
}

Jetpack Compose (Android)

Column {
  Text("Hello")
  Button(onClick = { handleClick() }) {
    Text("Click")
  }
}

New Vue Syntax

<View>
  <Text>Hello</Text>
  <Button onPress={handleClick}>Click</Button>
</View>

Migration Path

Vue provides a gradual migration path:

  1. Start with new components: Use declarative syntax for new components
  2. Gradual conversion: Convert existing components over time
  3. Coexistence: Both syntaxes can coexist in the same project

Example: Building a Todo App

Traditional Vue

<template>
  <div class="todo-app">
    <input v-model="newTodo" @keyup.enter="addTodo" />
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        {{ todo.text }}
        <button @click="removeTodo(todo.id)">Delete</button>
      </li>
    </ul>
  </div>
</template>

Declarative Syntax

<script setup>
import { View, TextInput, List, ListItem, Button } from 'vue-declarative'

const newTodo = ref('')
const todos = ref([])

function addTodo() {
  todos.value.push({ id: Date.now(), text: newTodo.value })
  newTodo.value = ''
}

function removeTodo(id) {
  todos.value = todos.value.filter(t => t.id !== id)
}
</script>

<template>
  <View class="todo-app">
    <TextInput
      v-model={newTodo}
      onSubmit={addTodo}
      placeholder="Add a todo"
    />
    <List>
      <ListItem
        v-for="todo in todos"
        :key="todo.id"
      >
        <Text>{todo.text}</Text>
        <Button onPress={() => removeTodo(todo.id)}>
          Delete
        </Button>
      </ListItem>
    </List>
  </View>
</template>

Performance Considerations

The declarative syntax can offer performance benefits:

  1. Better tree-shaking: Unused components are easier to eliminate
  2. Optimized rendering: More predictable component updates
  3. Smaller bundle size: More efficient code generation

When to Use

Consider the declarative syntax when:

  • Building new projects
  • Targeting mobile platforms
  • Needing better TypeScript support
  • Working with design systems
  • Building component libraries

Stick with traditional templates when:

  • Maintaining legacy codebases
  • Team is more familiar with HTML
  • Working with existing Vue 2 projects

Conclusion

Vue’s new declarative UI syntax represents an evolution towards more modern, type-safe, and mobile-friendly development patterns. While it’s not a replacement for traditional templates, it offers developers more options and brings Vue closer to the patterns used in native mobile development.

This change makes Vue more versatile and positions it well for cross-platform development scenarios.