The original link

Recently, the development of small programs has become more and more popular. As the entrance of extra services in each product line, it attracts a large number of users and developers with its lightweight, fast and powerful social chain. Development frameworks emerge one after another in the industry. Wepy, MPvue, Taro and so on are all developing in a faster and more powerful direction. There is a general trend of unifying H5, wechat, Alipay, Baidu and Toutiao.

This article aims at the MPVue framework as the basis to explore the map class small program development ideas, right to share and summarize. The author made use of the ability of MPvue + Tencent map to make a small program of subway route planning, which mainly provides the subway network map and tourism introduction of major cities in the world, among which the map and route planning of domestic cities are supported. It’s not complicated, but it’s a utility. Without further ado, here’s a taste:

Github source address: github.com/WarpPrism/S…

Run a screenshot

Here is a formal introduction to how to develop:

Mpvue introduction and project construction

Mpvue = miniProgram + VUE framework, in plain English, is to develop small programs with vUE framework. Mpvue was recently upgraded to version 2.x, which supports wechat, Alipay, Baidu and Toutiao. Compared with the traditional way, MPVUE development has the following advantages:

  • Radical componentized development capabilities: improved code reuse
  • Complete vue.js development experience
  • Convenient Vuex data management solution: Easy to build complex applications
  • Quick WebPack build mechanism: custom build strategy, hotReload during development
  • Support for using NPM external dependencies
  • Use vue-CLI command line tool vue.js to quickly initialize the project
  • H5 code conversion ability to compile into small program object code

In terms of personal experience, it is still very smooth, traditional Web application development seamlessly switch to small program development, basically zero threshold. Note the limitations of applets and their differences from Vue:

  • Applet style layout using relative pixels RPX
  • Part of the CSS selector doesn’t support, currently only support # id. | class | tag | tag, the tag | : : after: : before, so it is important to pay special attention to
  • For details, see mpvue.com/mpvue/#_3. Currently, there are many bugs in mpVue. For example, when a small application page is unloaded, the vue instance is not destroyed. The state must be manually reset at unLoad, etc
  • Mpvue encapsulates applets data objects, usually as$mpAt the beginning, such asevent.$mp.detail.targetEtc.
  • Applets are different from VUE components. Do not assume that all vUE components will work, such as slot, asynchronous components, and so on
  • Vue Store and WX localStorage should not be confused, choose different storage methods according to different needs
  • Don’t use VUE routing, use applets native navigation mechanism

We then set up the development environment and the MPvue scaffolding is out of the box:

# Global install VUE - CLI
Sudo permission is usually required$NPM install --global [email protected]Create a new project based on the MPvue-QuickStart template
# Newbie press Enter to select default
$ vue init mpvue/mpvue-quickstart my-project

# Install dependency, go you
$ cd my-project
$ npm install
$ npm run dev
Copy the code

Then, improve the file structure, add config, Store, mixins and other modules, as shown in the figure:

App. json is a special file for small programs, also need to improve:

{
  "pages": [
    "pages/citylist/main"."pages/citydetail/main"]."permission": {
    "scope.userLocation": {
      "desc": "Your location information will be used to display the effects of the applet location interface."}},"window": {
    "backgroundTextStyle": "light"."navigationBarBackgroundColor": "#eee"."navigationBarTitleText": "Global subway, all for you."."navigationBarTextStyle": "black"}}Copy the code

Then you can have fun writing Vue code, click a page, click another page, component, store, data-driven, whatever you like, it has.

Tencent map + small program

Focus on map access, Tencent map provides two docking entrance to small program, 1 is personalized map display, 2 is dedicated SDK, the two together to improve the map ecology of small program.

(1) Personality map display requires the developer to register and apply for the developer key, bind the small program in the management background, and then set the style of personality map to use:

<map
  id="citymap"
  name="citymap"
  :longitude="lng"
  :latitude="lat"
  :polyline="polyline"
	:markers="markers"
  scale="12"
  :subkey="YOUR_OWN_QQMAP_KEY"
  show-location
  show-compass
  enable-rotate
  style="width: 100%; height: 100%;"
>
  <cover-view class="map-cover-view">
    <button class="explore-btn" type="primary" @tap="exploreCity">Check out the tour guide</button>
  </cover-view>
</map>
Copy the code

Map is the native component of the applet. The native component has the highest hierarchy outside the WebView rendering process, so no matter how much z-index is set to other components in the page, it cannot be overlaid on the native component. To put it plainly, the native component is provided by the wechat client, which does not belong to the built-in browser. Therefore, the small program provides cover-view and cover-image components specially, which can be covered on some of the native components. These two components are also native components, but the usage restrictions are different from the other native components.

I lost a lot of time because of this pit, sometimes the development tools can be used, but on the real machine components are completely messed up, so it is still a real machine debugging. For native components, don’t use too complex CSS, many of its CSS properties don’t support well.

Scale is used to draw lines on a map, polyline is used to mark points, show-location is used to show the user’s location, and show-compass is used to show the north point.

(2) Dedicated SDKS that currently provide these capabilities:

  • Search (options:Object) Location search, search for nearby POIS, such as “hotel”, “dining”, “entertainment”, “school”, etc
  • GetSuggestion (options:Object) is used to get the completion and prompt for input keywords to help users quickly enter keywords
  • ReverseGeocoder (Options :Object) provides conversion from coordinate to literal description of coordinate location. The input coordinates return geolocation information and a list of nearby POIS
  • Geocoder (Options :Object) provides the conversion from address description to the coordinates of the position, as opposed to the process of reverse address resolution
  • Direction (Options :Object) provides driving, walking, cycling, bus route planning capability
  • GetCityList () gets a list of cities across the country
  • GetDistrictByCityId (options:Object) Returns the district under the city using the city ID
  • CalculateDistance (options:Object) Calculates walking and driving distance from one point to multiple points

Let’s take public transport route planning as an example (the following code has been simplified) :

First, initialize the map SDK object

import config from '@/config'
import QQMapWX from '.. /.. /assets/lib/qqmap-wx-jssdk.js' // Use the uncompressed version of the code here
const QQMapSDK = new QQMapWX({
  key: config.qqMapKey || ' '
})
Copy the code

The second step, to obtain the starting and ending coordinates, and route query

// The coordinates are passed in from query on the previous page. The coordinates are floating point numbers, available through the Geocoder interface
this.fromLocation = {
  latitude: +query.from.split(', ') [0] | |- 1.longitude: +query.from.split(', ') [1] | |- 1
}

this.toLocation = {
  latitude: +query.to.split(', ') [0] | |- 1.longitude: +query.to.split(', ') [1] | |- 1
}

// query the map route
queryMapRoutine() {
  QQMapSDK.direction({
    mode: 'transit'.// 'transit'
    // The from parameter does not contain the default current address
    from: this.fromLocation,
    to: this.toLocation,
    success: (res) = > {
      console.log('Route planning results', res);
      let routes = res.result.routes;
      this.routes = routes.map(r= > {
				// For each route scheme, analyze it separately
        return this.parseRoute(r)
      })
      console.log('parsed routes'.this.routes)
    }
  })
}
Copy the code

The third step, route analysis, generate route description, etc

// Parse route, including distance, time, description, route, ParseRoute (route) {let result = {} // Start time result.setoutTime = formatTime(new Date()) result.distance = route.distance < 1000 ? ${route.distance} m ':' ${(route.distance / 1000).tofixed (2)} km 'result.duration = route.duration < 60? '${route.duration} minutes' : Duration % 60} min 'result.desc = [] ${route.duration % 60} min' result.desc = [] Steps. ForEach (step => {// if (step.mode == 'WALKING' && step.distance > 0) {// Result.desc.push (' walk ${step-.distance} m ') //} if (step-.mode == 'TRANSIT' && step-.lines [0]) {let line = Line [0] if (line.vehicle == 'BUS') line.title = 'BUS' -${line.title} 'if (line.vehicle == 'RAIL') line.title = 'RAIL' Result.desc.push (' ${line.title}: ${line.geton.title} - > ${line.getoff. Title}, via ${line.station_count}. ')}}) result.polyline = [] result.points = [] result.points = [] i < route.steps.length; i++) { let step = route.steps[i] let polyline = this.getStepPolyline(step) if (polyline) { result.points = Result. The points. The concat (polylines. Points) result. Polylines. Push (polylines)}} / / tag line as a whole according to coordinate this. GetStepPolyline. ColorIndex =  0 let midPointIndex = Math.floor(result.points.length / 2) result.latitude = result.points[midPointIndex].latitude Result.points [0] let startPoint = result.points[0] let endPoint = result.points[0 result.points[result.points.length - 1] result.markers = [ { iconPath: this.startIcon, id: 0, latitude: Startpoint.latitude, longitude: startPoint.longitude, width: 28, height: 28, zIndex: -1, Anchor: {x: 0.5, y: 1} }, { iconPath: this.endIcon, id: 1, latitude: endPoint.latitude, longitude: endPoint.longitude, width: 28, height: 28, zIndex: -1, Anchor: {x: 0.5, y: 1}}] return result},Copy the code

Fourth, the getStepPolyline function gets the polyline for each step of the route

getStepPolyline(step) {
	let coors = [];
	// Random color
  let colorArr = ['#1aad19'.'#10aeff'.'#d84e43']
  let _dottedLine = true
  if (step.mode == 'WALKING' && step.polyline) {
    coors.push(step.polyline);
    _dottedLine = false
  } else if (step.mode == 'TRANSIT' && step.lines[0].polyline) {
    coors.push(step.lines[0].polyline);
  } else {
    return null
  }
  // Coordinate decompression (return point string coordinates, compressed by forward difference)
  let kr = 1000000;
  for (let i = 0 ; i < coors.length; i++){
    for (let j = 2; j < coors[i].length; j++) {
      coors[i][j] = Number(coors[i][j - 2]) + Number(coors[i][j]) / kr; }}// Define a new array to merge the arrays in coors into one array
  let coorsArr = [];
  let _points = [];
  for (let i = 0 ; i < coors.length; i ++){
    coorsArr = coorsArr.concat(coors[i]);
  }
  // Place the extracted coordinates in the string array _points
  for (let i = 0; i < coorsArr.length; i += 2) {
    _points.push({ latitude: coorsArr[i], longitude: coorsArr[i + 1]})}if (!this.getStepPolyline.colorIndex) {
    this.getStepPolyline.colorIndex = 0
  }
  let colorIndex = this.getStepPolyline.colorIndex % colorArr.length
	this.getStepPolyline.colorIndex++
	// Final polyline result
  let polyline = {
    width: 7.points: _points,
    color: colorArr[colorIndex],
    dottedLine: _dottedLine,
    arrowLine: true.// Lines with arrows. Developer tools do not support this property yet
    borderColor: '#fff'.borderWidth: 1
  }
  return polyline
}
Copy the code

Finally, binding to the map and exporting, we get something like this:

Guangzhou Railway Station -> Guangzhou Tower, 9.88km 30 minutes Metro Line 5 guangzhou Railway Station -> Zhujiang New Town, 7 stops metro Line 3 Zhujiang New Town -> Guangzhou Tower, 1 stopCopy the code

This allows us to do a simple route planning function using the direction interface, and then bind the generated data to the map component. A simple little program, isn’t it? Of course, if you want to do better, call other similar interfaces and refine the details over time.

<map
  id="citymap"
  name="citymap"
  :latitude="currentRoute.latitude"
  :longitude="currentRoute.longitude"
  :polyline="currentRoute.polyline"
  :markers="currentRoute.markers"
  scale="12"
  :subkey="qqMapKey"
  show-location
  show-compass
  enable-rotate
  style="width: 100%; height: 100%;"
></map>
Copy the code

More implementation please refer to the source code and small procedures themselves, if it helps you, you can star support.

other

There is also a web application for piano teaching, published on Gitee Page

crystalworld.gitee.io/qpiano/#/

Interested friends can see, after the time I will make up the development tutorial and source code, another to share.

Introduction to the article portal: juejin.cn/post/684490…