├── .babelrc ├── .editorconfig ├── .gitignore ├── README.md ├── dist ├── vue2-googlemap.js └── vue2-googlemap.js.map ├── index.html ├── package-lock.json ├── package.json ├── src ├── app.vue ├── lib │ ├── components │ │ ├── googlemap-circle.vue │ │ ├── googlemap-infoWindow.vue │ │ ├── googlemap-marker.vue │ │ ├── googlemap-polygon.vue │ │ ├── googlemap-polyline.vue │ │ ├── googlemap-rectangle.vue │ │ └── googlemap.vue │ ├── googlemapLoader.js │ └── index.js └── main.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-3" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | yarn-error.log 5 | 6 | # Editor directories and files 7 | .idea 8 | *.suo 9 | *.ntvs* 10 | *.njsproj 11 | *.sln 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue2-googlemap 2 | 3 | > 基于 Vue 2.x 和google地图的地图组件 4 | 5 | ## Install 6 | 7 | ``` bash 8 | npm install -S vue2-googlemap 9 | ``` 10 | 11 | ## Usage 12 | 13 | ``` javascript 14 | import Vue from 'vue'; 15 | import vueGooglemap from 'vue2-googlemap'; 16 | 17 | Vue.use(vueGooglemap); 18 | 19 | /* 20 | The api key is required. 21 | If you want to ignore the browser's language setting, you can set the language parameter. 22 | Suggest to use the release version. v=3 by default. 23 | */ 24 | vueGooglemap.initGooglemap({ 25 | key: 'your GOOGLE_MAPS_API_KEY', 26 | language: 'zh-CN', 27 | v: '3', 28 | }) 29 | ``` 30 | 31 | ## Components 32 | 33 | ### Map 34 | ``` javascript 35 | 36 | ``` 37 | ### Marker 38 | ``` javascript 39 | 40 | ``` 41 | ### infoWindow 42 | ``` javascript 43 | 44 | ``` 45 | ### Circle 46 | ``` javascript 47 | 48 | ``` 49 | ### Rectangle 50 | ``` javascript 51 | 52 | ``` 53 | ### Polyline 54 | ``` javascript 55 | 56 | ``` 57 | ### Polygon 58 | ``` javascript 59 | 60 | ``` 61 | ## License 62 | 63 | This project is covered under the MIT License. Feel free to use it wherever you like. 64 | -------------------------------------------------------------------------------- /dist/vue2-googlemap.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("vueGooglemap",[],t):"object"==typeof exports?exports.vueGooglemap=t():e.vueGooglemap=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=9)}([function(e,t){e.exports=function(e,t,n,i,r,o){var a,s=e=e||{},c=typeof e.default;"object"!==c&&"function"!==c||(a=e,s=e.default);var l="function"==typeof s?s.options:s;t&&(l.render=t.render,l.staticRenderFns=t.staticRenderFns,l._compiled=!0),n&&(l.functional=!0),r&&(l._scopeId=r);var u;if(o?(u=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),i&&i.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(o)},l._ssrRegister=u):i&&(u=i),u){var p=l.functional,f=p?l.render:l.beforeCreate;p?(l._injectStyles=u,l.render=function(e,t){return u.call(t),f(e,t)}):l.beforeCreate=f?[].concat(f,u):[u]}return{esModule:a,exports:s,options:l}}},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",function(){return l}),n.d(t,"b",function(){return c});var r=Object.assign||function(e){for(var t=1;tn.parts.length&&(i.parts.length=n.parts.length)}else{for(var a=[],r=0;r { if (vueGoogleMap.installed) return;\n// components.forEach(c => { vue.component(c.name, c) })\n// vueGoogleMap.installed = true; }\n\nif (typeof window !== 'undefined' && window.Vue) {\n window.Vue.use(vueGoogleMap);\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (vueGoogleMap);\n\n/***/ }),\n/* 10 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_googlemap_vue__ = __webpack_require__(2);\n/* unused harmony namespace reexport */\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_f52e03d6_hasScoped_false_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_googlemap_vue__ = __webpack_require__(16);\nfunction injectStyle (ssrContext) {\n __webpack_require__(11)\n}\nvar normalizeComponent = __webpack_require__(0)\n/* script */\n\n\n/* template */\n\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_googlemap_vue__[\"a\" /* default */],\n __WEBPACK_IMPORTED_MODULE_1__node_modules_vue_loader_lib_template_compiler_index_id_data_v_f52e03d6_hasScoped_false_buble_transforms_node_modules_vue_loader_lib_selector_type_template_index_0_googlemap_vue__[\"a\" /* default */],\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (Component.exports);\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n// style-loader: Adds some css to the DOM by adding a \n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-marker.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-polyline.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-polygon.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-circle.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-rectangle.vue","\n\n\n\n\n// WEBPACK FOOTER //\n// src/lib/components/googlemap-infoWindow.vue","import {initGooglemap} from './googlemapLoader.js';\nimport googlemap from './components/googlemap.vue';\nimport marker from './components/googlemap-marker.vue';\nimport polyline from './components/googlemap-polyline.vue';\nimport polygon from './components/googlemap-polygon.vue';\nimport circle from './components/googlemap-circle.vue';\nimport rectangle from './components/googlemap-rectangle.vue';\nimport infoWindow from './components/googlemap-infoWindow.vue';\n\nconst components = [\n googlemap,\n marker,\n polyline,\n polygon,\n circle,\n rectangle,\n infoWindow\n];\n\nconst vueGoogleMap = {\n initGooglemap,\n components,\n installed: false,\n install(vue) {\n if (vueGoogleMap.installed) \n return;\n components.forEach(c => {\n vue.component(c.name, c)\n })\n vueGoogleMap.installed = true;\n }\n}\n\n// vueGoogleMap.install = (vue) => { if (vueGoogleMap.installed) return;\n// components.forEach(c => { vue.component(c.name, c) })\n// vueGoogleMap.installed = true; }\n\nif (typeof window !== 'undefined' && window.Vue) {\n window\n .Vue\n .use(vueGoogleMap);\n}\n\nexport default vueGoogleMap;\n\n\n// WEBPACK FOOTER //\n// ./src/lib/index.js","function injectStyle (ssrContext) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-f52e03d6\\\",\\\"scoped\\\":false,\\\"hasInlineConfig\\\":false}!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./googlemap.vue\")\n}\nvar normalizeComponent = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./googlemap.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./googlemap.vue\"\n/* template */\nimport __vue_template__ from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-f52e03d6\\\",\\\"hasScoped\\\":false,\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./googlemap.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/lib/components/googlemap.vue\n// module id = 10\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a 136 | -------------------------------------------------------------------------------- /src/lib/googlemapLoader.js: -------------------------------------------------------------------------------- 1 | const DEFAULT_CONFIG = { 2 | key: null, 3 | v: '3', 4 | language: null, 5 | callback: 'googleMapInit' 6 | } 7 | 8 | class GoogleMapLoader { 9 | constructor(config) { 10 | this.config = { 11 | ...DEFAULT_CONFIG, 12 | ...config 13 | }; 14 | this._window = window; 15 | this._document = document; 16 | this._scriptLoaded = false; 17 | } 18 | load() { 19 | if (this._window.google) 20 | return Promise.resolve(); 21 | if (this._scriptLoadingPromise) 22 | return this._scriptLoadingPromise; 23 | 24 | const script = this 25 | ._document 26 | .createElement('script'); 27 | script.type = 'text/javascript'; 28 | script.async = true; 29 | script.defer = true; 30 | script.src = this.getSrc(); 31 | 32 | this._scriptLoadingPromise = new Promise((resolve, reject) => { 33 | this._window['googleMapInit'] = () => { 34 | return resolve(); 35 | } 36 | script.onerror = (error) => reject(error); 37 | }) 38 | this 39 | ._document 40 | .head 41 | .appendChild(script); 42 | return this._scriptLoadingPromise; 43 | } 44 | 45 | getSrc() { 46 | const params = ['key', 'v', 'language', 'callback']; 47 | 48 | const keys = Object 49 | .keys(this.config) 50 | .filter(k => params.indexOf(k) !== -1) 51 | .filter(k => this.config[k] !== null) 52 | .map(k => ({key: k, value: this.config[k]})) 53 | .map(o => `${o.key}=${o.value}`) 54 | .join('&') 55 | return `https://maps.googleapis.com/maps/api/js?${keys}` 56 | } 57 | } 58 | 59 | let instance = null; 60 | export const initGooglemap = (config) => { 61 | if (instance) 62 | return; 63 | instance = new GoogleMapLoader(config); 64 | instance.load(); 65 | } 66 | export {instance} -------------------------------------------------------------------------------- /src/lib/index.js: -------------------------------------------------------------------------------- 1 | import {initGooglemap} from './googlemapLoader.js'; 2 | import googlemap from './components/googlemap.vue'; 3 | import marker from './components/googlemap-marker.vue'; 4 | import polyline from './components/googlemap-polyline.vue'; 5 | import polygon from './components/googlemap-polygon.vue'; 6 | import circle from './components/googlemap-circle.vue'; 7 | import rectangle from './components/googlemap-rectangle.vue'; 8 | import infoWindow from './components/googlemap-infoWindow.vue'; 9 | 10 | const components = [ 11 | googlemap, 12 | marker, 13 | polyline, 14 | polygon, 15 | circle, 16 | rectangle, 17 | infoWindow 18 | ]; 19 | 20 | const vueGoogleMap = { 21 | initGooglemap, 22 | components, 23 | installed: false, 24 | install(vue) { 25 | if (vueGoogleMap.installed) 26 | return; 27 | components.forEach(c => { 28 | vue.component(c.name, c) 29 | }) 30 | vueGoogleMap.installed = true; 31 | } 32 | } 33 | 34 | // vueGoogleMap.install = (vue) => { if (vueGoogleMap.installed) return; 35 | // components.forEach(c => { vue.component(c.name, c) }) 36 | // vueGoogleMap.installed = true; } 37 | 38 | if (typeof window !== 'undefined' && window.Vue) { 39 | window 40 | .Vue 41 | .use(vueGoogleMap); 42 | } 43 | 44 | export default vueGoogleMap; -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './app.vue' 3 | import VueGooglemap from './lib' 4 | 5 | Vue.use(VueGooglemap) 6 | 7 | VueGooglemap.initGooglemap({ 8 | key: 'AIzaSyCqfHjvG4-rHVTfbpfHgHZwG168utagTu4' 9 | }) 10 | 11 | /* eslint-disable no-new */ 12 | new Vue({ 13 | el: '#app', 14 | components: { App }, 15 | template: '' 16 | }) 17 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/lib/index.js', 6 | // entry: './src/main.js', 7 | output: { 8 | path: path.resolve(__dirname, './dist'), 9 | publicPath: '/dist/', 10 | filename: 'vue2-googlemap.js', 11 | library: 'vueGooglemap', 12 | libraryTarget: 'umd', 13 | umdNamedDefine: true, 14 | }, 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.css$/, 19 | use: ['vue-style-loader', 'css-loader'] 20 | }, { 21 | test: /\.vue$/, 22 | loader: 'vue-loader', 23 | options: { 24 | loaders: {} 25 | // other vue-loader options go here 26 | } 27 | }, { 28 | test: /\.js$/, 29 | loader: 'babel-loader', 30 | exclude: /node_modules/ 31 | }, { 32 | test: /\.(png|jpg|gif|svg)$/, 33 | loader: 'file-loader', 34 | options: { 35 | name: '[name].[ext]?[hash]' 36 | } 37 | } 38 | ] 39 | }, 40 | resolve: { 41 | alias: { 42 | 'vue$': 'vue/dist/vue.esm.js' 43 | }, 44 | extensions: ['*', '.js', '.vue', '.json'] 45 | }, 46 | devServer: { 47 | historyApiFallback: true, 48 | noInfo: true, 49 | overlay: true 50 | }, 51 | performance: { 52 | hints: false 53 | }, 54 | devtool: '#eval-source-map' 55 | } 56 | 57 | if (process.env.NODE_ENV === 'production') { 58 | module.exports.devtool = '#source-map' 59 | // http://vue-loader.vuejs.org/en/workflow/production.html 60 | module.exports.plugins = (module.exports.plugins || []).concat([ 61 | new webpack.DefinePlugin({ 62 | 'process.env': { 63 | NODE_ENV: '"production"' 64 | } 65 | }), 66 | new webpack 67 | .optimize 68 | .UglifyJsPlugin({ 69 | sourceMap: true, 70 | compress: { 71 | warnings: false 72 | } 73 | }), 74 | new webpack.LoaderOptionsPlugin({minimize: false}) 75 | ]) 76 | } 77 | --------------------------------------------------------------------------------