Vue 3.0 - first look

Finally got around to trying the new version of Vue. I'm not going to be objective in this article, I will just tell you my impressions while working with the new version, and also tell you how to install it and get started now.

Despite the release, Vue 3.0 is not yet ready for full production use. Router and Vuex are not yet ready to work with the new version, the Vue CLI installs the old version by default, not to mention third-party plugins and libraries whose authors have not had time to update them. This is the long-awaited and incomplete release we received.

Especially a lot of questions are raised by the new syntax, the so-called Composition API , which, fortunately, will not replace the completely familiar and beloved Options API. In favor of the new composition, we are offered a similar picture everywhere:

Comparison of code fragmentation in the old and new syntax
Comparison of code fragmentation in the old and new syntax

. , , - . , , TS . - , . . .

" " : React. , , , .

.

Vue 3, :

Vue 3

npm - :

npm install vue@next

node_modules. , . Vue CLI.

: CLI. :

npm install -g @vue/cli

- , yarn ( Vue React):

yarn global add @vue/cli

, , . , :

vue -V

@vue/cli 4.5.6.

:

vue create hello-vue

. :

Default (Vue 3 Preview) ([Vue 3] babel, eslint)

, :

cd hello-vue

. VScode :

code  .

Vue CLi . . main.js:

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

createApp, . . , , , - , . , .

HelloWorld.vue App.vue.

components Card.vue :

<template>
  <div>
    <img :src="imgUrl" alt="cat pic" />
    <h1>{{ catName }}</h1>
    <p>
      <i>{{ text }}</i>
    </p>
    <p>
      <b>{{ website }}</b>
    </p>
  </div>
</template>

<script>
export default {
  name: "Card",
  props: {
    id: String,
    name: String,
    text: String,
    website: String,
  },
  computed: {
    imgUrl() {
      return `https://robohash.org/${this.id}?set=set4&size=180x180`;
    },
    catName() {
      return this.name.replace(/[_.-]/gi, " ");
    },
  },
};
</script>

props. , . , , . computed. ? computed

<script>
import { computed } from "vue";
...

computed setup :

 setup(props) {
    const imgUrl = computed(
      () => `https://robohash.org/${props.id}?set=set4&size=180x180`
    );
    const catName = computed(() => props.name.replace(/[_.-]/g, " "));
    return {
      imgUrl,
      catName,
    };
  },

Setup props, .

, , robohash.org. . :

<style scoped>
div {
  width: 400px;
  height: 380px;
  position: relative;
  background: #ecf0f3;
  margin-bottom: 30px;
  padding: 30px 5px;
  border-radius: 32px;
  text-align: center;
  cursor: pointer;
  font-family: "Montserrat", sans-serif;
  font-size: 22px;
  font-weight: semibold;
  box-shadow: -6px -6px 10px rgba(255, 255, 255, 0.8),
    6px 6px 10px rgba(0, 0, 0, 0.2);
  color: #6f6cde;
}
</style>

App.vue. . :

<template>
  <div class="container">
    <Card
      v-for="cat in cats"
      :id="cat.id"
      :name="cat.username"
      :text="cat.company.catchPhrase"
      :key="cat.id"
      :website="cat.website"
    />
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
import Card from "./components/Card";

export default {
  name: "App",
  components: { Card },
  setup() {
    const cats = ref([]);
    const fetchCats = async () => {
      cats.value = await fetch(
        "https://jsonplaceholder.typicode.com/users"
      ).then((response) => response.json());
    };
    onMounted(fetchCats);
    return {
      cats,
    };
  },
};
</script>

<style>
body {
  background: #ecf0f3;
}
.container {
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-content: space-around;
  flex-wrap: wrap;
  padding: 30px 0px;
}
</style>

, :

ref onMounted

ref , setup(). -. ref . , , , . value , , :

cats.value = data

cats

onMounted mounted. setup , on. onMounted . , , .


, .

.

. ( ) . , . .




All Articles