Vue
Quick start
Warning
Supported Vue version: 3 or higher
Connecting via top-level-await
<!DOCTYPE html>
<html>
<head>
<!-- Replace YOUR_API_KEY with the real key -->
<script src="https://api-maps.yandex.ru/v3/?apikey=YOUR_API_KEY&lang=en_US"></script>
<script type="module" src="index.ts"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
import {createApp} from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
<script lang="ts" setup>
import {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker} from './lib/ymaps3';
import type {YMapLocationRequest} from 'ymaps3';
const LOCATION: YMapLocationRequest = {
center: [37.588144, 55.733842],
zoom: 9
};
</script>
<template>
<div style="width: 600px; height: 400px">
<YMap :location="LOCATION">
<YMapDefaultSchemeLayer />
<YMapDefaultFeaturesLayer />
<YMapMarker :coordinates="[37.588144, 55.733842]" :draggable="true">
<section>
<h1>You can drag this header</h1>
</section>
</YMapMarker>
</YMap>
</div>
</template>
import * as Vue from 'vue';
const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]);
export const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
export const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapMarker} = vuefy.module(ymaps3);
{
"compilerOptions": {
"target": "es2017",
"lib": ["dom", "dom.iterable", "esnext"],
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"typeRoots": ["./node_modules/@types", "./node_modules/@yandex/ymaps3-types"],
"paths": {
"ymaps3": ["./node_modules/@yandex/ymaps3-types"]
}
}
}
{
"type": "module",
"scripts": {
"dev": "vite"
},
"devDependencies": {
"@yandex/ymaps3-types": "^0.0.17",
"vue": "^3.4.21",
"@vitejs/plugin-vue": "^5.0.4",
"typescript": "^4.9.5",
"vite": "^5.2.8"
}
}
import {defineConfig} from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js'
}
}
});
Set dependencies and run a local server:
npm install
npm run dev
Open the app
Specifics
-
Specify the
type="module"attribute in the "script" tag that loads the compiled project JS to enable ECMAScript Modules (ESM) and top-level-await support:<script type="module" src="index.ts"></script> -
In
package.json, add a dev dependency on the@yandex/ymaps3-typespackage.We recommend installing the latest version:
npm i --save-dev @yandex/ymaps3-types@latest -
In
tsconfig.json, setcompilerOptions.typeRootswith a list of paths to type files. Add a path to the@yandex/ymaps3-typespackage there to make theymaps3namespace with types appear in the global scope.Note
The
ymaps3namespace contains all the class types provided by the JS API, but they are not available in the runtime environment untilymaps3.readyis resolved. -
In
tsconfig.json, setcompilerOptions.paths, informing the TS compiler that the contents of the importedymaps3package should be searched for at the specified path. This enables you to import types in project files as if they were located not at@yandex/ymaps3-types, but in theymaps3package:import type {YMapLocationRequest} from 'ymaps3';All types must be imported from the root.
The internal structure isn't guaranteed and can change over time.
-
In
tsconfig.json, for top-level-await to operate correctly, thecompilerOptions.moduleparameter must be set to one of the following values:es2022,esnext,system, orpreserve. ThecompilerOptions.targetparameter must be set toes2017or higher. -
In
vite.config.ts, setresolve.aliasto use the "complete" Vue build (vue/dist/vue.esm-bundler.js). This is necessary forymaps3of Vue components to work correctly. -
Each object in the JS API has a Vue analog. To use the Vue API version, connect the
@yandex/ymaps3-vuefymodule. Inlib/ymaps3.ts, wait until the JS API and Vuefy module are fully loaded and then export the necessary map components so that they can be used in other parts of the project:import * as Vue from 'vue'; const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]); export const vuefy = ymaps3Vue.vuefy.bindTo(Vue); export const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer} = vuefy.module(ymaps3); -
The use of top-level-await in
lib/ymaps3.tsguarantees thatymaps3.readyandymaps3.import('@yandex/ymaps3-vuefy')are executed before the map components are imported, allowing any JS API objects to be used as Vue components synchronously:<YMap :location="LOCATION"> <YMapDefaultSchemeLayer /> <YMapDefaultFeaturesLayer /> ... </YMap>
Specifying input parameters for custom classes
Vue components require explicit declaration of input parameters so that Vue knows which of them should be considered additional attributes.
For basic objects from the ymaps3 namespace, input parameters are determined by default and no additional actions are required.
If you are a developer who creates custom classes (for example, as part of a separate package), you can determine which input parameters will be contained in the component. Determining props supports Vue format. Fro example, custom YMapSomeClass:
type YMapSomeClassProps = {
id: string;
counter?: number;
};
export class YMapSomeClass extends ymaps3.YMapComplexEntity<YMapSomeClassProps> {
static [ymaps3.optionsKeyVuefy] = {props: ['id', 'counter']};
//...
}
In addition to an array of strings, you can also use object syntax:
export class YMapSomeClass extends ymaps3.YMapComplexEntity<YMapSomeClassProps> {
static [ymaps3.optionsKeyVuefy] = {
props: {
id: String,
counter: Number
}
};
//...
}
or with input parameter validation:
export class YMapSomeClass extends ymaps3.YMapComplexEntity<YMapSomeClassProps> {
static [ymaps3.optionsKeyVuefy] = {
props: {
id: {type: String, required: true},
counter: {type: Number, required: false}
}
};
//...
}
Specifying input parameters when using third-party packages
If developers of third-party packages have not determined input parameters for their classes, you can specify them yourself when calling vuefy by passing them as a second argument:
const ymaps3Vue = await ymaps3.import('@yandex/ymaps3-vuefy');
const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
const {YMapSomeClass as YMapSomeClassV} = vuefy.module(
{YMapSomeClass},
{
YMapSomeClass: ['id', 'counter'] // props for the YMapSomeClass class
}
);
The object syntax and validations shown above are supported in a similar way.
Custom implementations of ymaps3.YMapEntity objects for Vue
When the standard conversion is insufficient, use the ymaps3.overrideKeyVuefy key to specify your implementation for vuefy:
type YMapSomeClassProps = {
id: string;
counter?: number;
};
/* ymaps3.YMapEntity object */
export class YMapSomeClass extends ymaps3.YMapComplexEntity<YMapSomeClassProps> {
static [ymaps3.overrideKeyVuefy] = YMapSomeClassVuefyOverride;
//...
}
YMapSomeClassVuefyOverride is a method that must return a Vue component. It gets the base class, declared props, and an object with Vue and vuefy (if their methods are required) as parameters. The example below shows the creation of the YMapSomeClassV wrapper with additional logic around the component that was obtained using the base vuefy method:
export const YMapSomeClassVuefyOverride: CustomVuefyFn<YMapSomeClass> = (
YMapSomeClassI, // base YMapSomeClass
props, // declared input parameters
{vuefy, Vue}
) => {
// Standard vuefy method
const YMapSomeClassVuefied = vuefy.entity(YMapSomeClassI, props);
const YMapSomeClassV = Vue.defineComponent({
props,
name: 'YMapSomeClassV',
components: {YMapSomeClassVuefied},
setup() {
// additional logic for custom implementation
},
template: `<YMapSomeClassVuefied v-bind="$props" ... />`
});
return YMapSomeClassV;
};
the resulting component can be used in the app:
const ymaps3Vue = await ymaps3.import('@yandex/ymaps3-vuefy');
const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
const YMapSomeClassV = vuefy.entity(YMapSomeClass);
const app = createApp({
components: {YMapSomeClassV},
template: `<YMapSomeClassV id="some_id" />`
});
app.mount('#app');