# vue2-elm User Guide

**vue2-elm** is a complete, mobile-first single-page application (SPA) that recreates the
shopping experience of the Chinese food-delivery platform **饿了么 (Ele.me)**. It was built
with **Vue 2, Vuex, and Vue Router** as a real-world learning project: rather than a toy demo,
it implements a full ordering journey — locating your city, browsing nearby restaurants,
filtering and sorting them, adding dishes to a cart, managing addresses, and placing an order —
across roughly **45 screens**.

This guide is written for the people who actually *use* this repository: developers and
students who want to run the app locally, click through every feature, and study how a
non-trivial Vue 2 application is put together. Because vue2-elm is a front-end learning
project (not an officially operated store), you will not pay for real food here — but every
interaction up to the payment step is fully functional against its companion backend.

> [!NOTE]
> vue2-elm is the **front end only**. All of its data — cities, restaurants, menus, login,
> orders — is served by a separate backend project, [`node-elm`](https://github.com/bailicangdu/node-elm).
> Understanding that split (covered in [Requirements](#2-requirements) and
> [Running the App](#4-running-the-app)) is the single most important thing for getting it working.

---

## Table of Contents

1. [Quick Start](#1-quick-start)
2. [Requirements](#2-requirements)
3. [Installation](#3-installation)
4. [Running the App](#4-running-the-app)
5. [Taking a Tour of the App](#5-taking-a-tour-of-the-app)
6. [Common Tasks](#6-common-tasks)
7. [Configuration You Can Change](#7-configuration-you-can-change)
8. [Troubleshooting](#8-troubleshooting)
9. [Frequently Asked Questions](#9-frequently-asked-questions)
10. [Reference](#10-reference)

---

## 1. Quick Start

If you already have a recent-enough Node.js toolchain and just want to see the app, run:

```bash
git clone https://github.com/bailicangdu/vue2-elm.git
cd vue2-elm
npm install          # or: yarn
npm run dev
```

Then open the dev server in **Chrome**, switch on **device (mobile) emulation**, and navigate
to the app. The layout is designed for a phone-sized viewport, so a desktop window will look
stretched and broken until you emulate a mobile device.

> [!IMPORTANT]
> vue2-elm uses a **rem-based mobile layout** calibrated to a 320 px-wide screen. You *must*
> view it in a mobile viewport (Chrome DevTools → Toggle device toolbar, `Ctrl+Shift+M`) to see
> it render correctly. See [The app looks huge / broken on desktop](#error-the-app-looks-huge-or-stretched-on-a-desktop-browser).

> [!TIP]
> `npm run dev` points the app at the project's **public demo backend** at `cangdu.org`. That
> shared server is community-run and is frequently offline. If restaurant lists never load, that
> is almost always the cause — see [Running against your own backend](#42-running-against-your-own-backend-npm-run-local)
> and [Troubleshooting](#8-troubleshooting).

---

## 2. Requirements

### 2.1 Software

| Requirement | Version | Why |
|---|---|---|
| **Node.js** | `>= 6.0.0` recommended (`package.json` declares `>= 4.0.0`) | The source uses ES6/7 syntax that older Node cannot run. |
| **npm** | `>= 3.0.0` | Declared in `package.json` `engines`. |
| **Yarn** | Optional | The README recommends Yarn as an alternative to npm for installing dependencies. |
| **Browser** | Chrome (mobile emulation) | The UI is a phone layout; Chrome's device mode is the documented way to view it. |

> [!WARNING]
> This project dates from the Node 6 / webpack 1 era (the author developed it on Node 6.10.0).
> It depends on `node-sass`, which compiles native code tied to your Node version. On modern
> Node releases `npm install` may fail while building `node-sass`. The
> [Troubleshooting](#error-npm-install-fails-while-building-node-sass) section explains how to
> work around this; the most reliable fix is to use a Node version from that era via a version
> manager such as `nvm`.

### 2.2 The companion backend

vue2-elm cannot show any data on its own. Every screen calls an HTTP API. You have two options
for where those calls go:

| Option | Command | Backend | Best for |
|---|---|---|---|
| **Public demo backend** | `npm run dev` | The author's hosted server at `cangdu.org` | A quick look, when the server is up |
| **Your own local backend** | `npm run local` | [`node-elm`](https://github.com/bailicangdu/node-elm) running on your machine | Reliable, offline-capable development |

> [!NOTE]
> If you only want to study the **front-end code**, you do not strictly need a backend at all —
> you just won't see live data. To experience the full ordering flow, run `node-elm` locally.

---

## 3. Installation

### 3.1 Clone and install dependencies

```bash
git clone https://github.com/bailicangdu/vue2-elm.git
cd vue2-elm
npm install
```

Expected output (abbreviated):

```text
added N packages in Ms
```

> [!TIP]
> Yarn is often smoother than npm for this older dependency tree because of its lockfile
> (`yarn.lock` is committed to the repo):
>
> ```bash
> yarn
> ```

### 3.2 Verify the install

A successful install creates a `node_modules/` directory and leaves the three runnable scripts
available:

```bash
npm run
```

```text
Lifecycle scripts included in elm:
Available via `npm run-script`:
  dev
  local
  build
```

These three scripts are the entire command surface of the project — there are no CLI flags or
subcommands beyond them.

---

## 4. Running the App

vue2-elm exposes exactly three npm scripts. Two run a development server; one produces a
production build.

| Script | Command | What it does |
|---|---|---|
| **dev** | `npm run dev` | Starts the webpack dev server pointed at the **public** `cangdu.org` backend. |
| **local** | `npm run local` | Starts the webpack dev server expecting a **local** `node-elm` backend. |
| **build** | `npm run build` | Compiles an optimized production bundle into the `elm/` directory. |

### 4.1 Running against the public backend (`npm run dev`)

```bash
npm run dev
```

The dev server starts and serves the app. Open it in Chrome, enable device emulation, and you
should land on the **home (city selection)** screen.

> [!CAUTION]
> The public backend is a shared, community-maintained server. When it is down (a recurring
> situation reported repeatedly in the project's issues), the app loads but every data request
> fails — typically with a `{"name":"ERROR_DATA","message":"获取数据失败"}` response or a `404`.
> This is not a bug in your setup. Switch to a local backend (below).

### 4.2 Running against your own backend (`npm run local`)

For reliable development, run the companion backend yourself:

1. Clone and start the backend in a separate terminal:

   ```bash
   git clone https://github.com/bailicangdu/node-elm.git
   cd node-elm
   # follow node-elm's own README to install dependencies and start it
   ```

2. In the vue2-elm terminal, start the front end in **local** mode:

   ```bash
   npm run local
   ```

Now the front end talks to your local `node-elm` instance instead of `cangdu.org`, so data
loads regardless of whether the public demo server is up.

> [!NOTE]
> The author also publishes an admin/management console for the same backend,
> [`vue2-manage`](https://github.com/bailicangdu/vue2-manage), built with Element UI. It is
> optional and only relevant if you want to administer the `node-elm` data.

### 4.3 Building for production (`npm run build`)

```bash
npm run build
```

This compiles the app into the `elm/` folder (`elm/index.html` plus hashed assets under
`elm/static/`). The contents of `elm/` are a ready-to-host static site — copy them to any web
server and the app will run.

> [!IMPORTANT]
> The committed `elm/` directory in the repository is a **pre-built snapshot** of the app, not
> source code. Your own `npm run build` overwrites it. When studying the code, read `src/`, not
> `elm/static/js/*.js` (those are minified bundles).

---

## 5. Taking a Tour of the App

The best way to understand vue2-elm is to walk its ordering journey the way a customer would.
Each screen below corresponds to a route and a page component; the journey is the heart of what
the project demonstrates.

### 5.1 The customer journey at a glance

```text
Home (pick a city)
   └─► Msite (restaurants near you)
          ├─► Food (filter & sort restaurants)
          └─► Shop (menu + cart for one restaurant)
                 └─► Confirm Order (address, remark, invoice, validation)
                        └─► Order placed ──► Orders list ──► Order detail
```

Alongside this main flow are account screens (login, profile, addresses) and "wallet" screens
(red packets, coupons, balance, points, VIP card).

### 5.2 Home — choose your city

The first screen shows your **guessed current city** (located automatically by the backend),
a list of **hot cities**, and an alphabetically grouped list of **all cities**. Tapping the
`ele.me` logo reloads the page.

- Tap your city to continue to the restaurant list.
- If the auto-detected city is wrong, pick the correct one from the lists.

### 5.3 Msite — browse nearby restaurants

The **Msite** screen is the app's main storefront. It shows:

- A header with your current address (resolved from your location) and a search entry point.
- A swipeable grid of **food categories** (fast food, snacks, desserts, etc.).
- A scrolling **list of nearby restaurants**, each with rating, monthly sales, delivery fee,
  minimum order, distance, and estimated delivery time.

Scroll to the bottom and more restaurants load automatically (infinite scroll). A
**back-to-top** button appears after you scroll down far enough.

> [!TIP]
> If the restaurant list stays empty but a loading skeleton keeps showing, the backend isn't
> returning data. Check that your backend is reachable (see [Troubleshooting](#8-troubleshooting)).

### 5.4 Food — filter and sort

From a food category you reach the **Food** screen, which lets you refine the restaurant list by:

- **Sort order** — distance, sales volume, rating, and more.
- **Delivery mode** — e.g. platform delivery vs. merchant delivery.
- **Restaurant attributes / activities** — promotions, "on-time guarantee," brand, and similar
  filters.

The list re-queries and re-renders as you change filters.

### 5.5 Search — find a restaurant or dish

From the header search icon you can search restaurants and dishes near your location by keyword.

### 5.6 Shop — menu, dish details, and the cart

The **Shop** screen is the most interactive part of the app:

- A restaurant header with rating, sales, notices, and activities.
- A two-column **menu**: food categories on the left, dishes on the right.
- Each dish has an **add (+)** control; dishes with multiple **specifications** prompt you to
  choose a spec first.
- A floating **cart** at the bottom totals your selection and the delivery fee.

Adding and removing dishes updates the cart instantly. Your cart is **saved in the browser**,
so it survives a page refresh.

You can also open:

- **Food detail** — a single dish's details and reviews.
- **Shop detail** — full restaurant info, ratings list (filterable by tag), and
  **shop safety / certification** info.

### 5.7 Login — sign in or auto-register

Many actions (placing an order, viewing your profile) require you to be signed in. The
**Login** screen offers two modes:

| Mode | Fields | Notes |
|---|---|---|
| **Account login** (default) | Username, password, image captcha | The default screen. Click the captcha image to refresh it. |
| **SMS login** | Phone number, SMS code | Request a 6-digit code, then sign in with it. |

> [!NOTE]
> Against the demo/`node-elm` backend, **accounts you've never used are created automatically
> on first login** — the on-screen hint reads *"未注册过的账号，登录时将自动注册"* ("unregistered
> accounts are registered automatically at login"). The account-login form even invites you to
> type anything for the username and password. This is intentional for a learning backend; do
> not treat it as a real authentication system.

### 5.8 Confirm Order — the checkout flow

After building a cart and signing in, **Confirm Order** gathers everything needed to place an
order:

- **Choose / add a delivery address** (with nested screens to search for and add new addresses).
- **Order remark** — pick from quick remarks or type your own.
- **Invoice** — choose an invoice title if you want one.
- **User validation** — when the backend requires it, confirm an order verification code.

Submitting places the order and takes you to the order result.

> [!IMPORTANT]
> **Payment is intentionally not implemented.** vue2-elm lets you place an order but stops at
> the payment step. The countdown "go to pay" control deliberately shows the message
> *"暂不开放支付接口"* ("payment interface not open yet"). This is by design — the project's
> feature list marks payment as the one unfinished item. You can complete the entire flow up to,
> but not through, paying.

### 5.9 Orders, profile, and wallet screens

- **Order list / Order detail** — review past orders and drill into a single order's snapshot.
- **Profile** — your account info, avatar upload, username editing, and address book
  (add / edit / delete addresses).
- **Service center** — help topics and question details.
- **Wallet-style screens** — **red packets** (`benefit`: coupons, exchange, history,
  referral), **balance**, **points**, and **VIP card** (purchase and usage, with descriptions).
- **Find** and **Download** — discovery and an app-download promo screen.

---

## 6. Common Tasks

Recipes for the things you'll most often do while exploring or studying the app.

### 6.1 See the app with working data, reliably

```bash
# Terminal 1 — backend
git clone https://github.com/bailicangdu/node-elm.git
cd node-elm
# install + start per node-elm's README

# Terminal 2 — front end
cd vue2-elm
npm run local
```

This is the recommended setup: it does not depend on the public demo server being online.

### 6.2 Place a complete (unpaid) order end-to-end

1. From **Home**, choose a city.
2. On **Msite**, open any restaurant.
3. Add one or more dishes to the cart.
4. Tap the cart and proceed to **Confirm Order**.
5. If prompted, **log in** (any username/password works against the demo backend).
6. Choose or add a **delivery address**, set a remark, and submit.
7. Observe the order result. (You cannot pay — that step is disabled by design.)

### 6.3 Reset your cart or session

Your cart and login are stored in the browser's **localStorage**. To start fresh:

- Open Chrome DevTools → **Application** → **Local Storage** → select the site.
- Delete the `buyCart` key (cart contents) and/or `user_id` key (saved login), or click
  **Clear** to wipe everything.
- Refresh the page.

### 6.4 View on a real phone (same network)

When running the dev server, you can open the app on a phone connected to the same network by
visiting your computer's LAN IP and the dev server's port in the phone's browser. Because the
layout is mobile-native, it will look correct on a real device without emulation.

---

## 7. Configuration You Can Change

vue2-elm has very little user-facing configuration — almost everything is driven by the chosen
npm script. The one file worth knowing about is `src/config/env.js`, which selects the API and
image hosts per environment.

| Setting | File | Meaning |
|---|---|---|
| `baseUrl` | `src/config/env.js` | Base URL for API calls. Empty in development (requests are proxied); `//elm.cangdu.org` in production builds. |
| `imgBaseUrl` | `src/config/env.js` | Base URL for images. `/img/` in development; `//elm.cangdu.org/img/` in production. |
| `routerMode` | `src/config/env.js` | Routing mode. Set to `hash`, so URLs look like `…/#/msite`. |

> [!NOTE]
> You normally do not edit `env.js`. Pick `npm run dev` (public backend) or `npm run local`
> (local backend) and the correct hosts follow. Deeper configuration — the dev-server proxy
> targets and build paths — lives in `config/index.js` and is covered in the **Admin Guide**.

---

## 8. Troubleshooting

Each entry below pairs a symptom with its cause and fix. The first two are by far the most
common and account for the majority of "it doesn't work" reports.

### Error: `获取数据失败` / `ERROR_DATA` / restaurants never load / `404`

```text
{"name":"ERROR_DATA","message":"获取数据失败"}
```

- **Cause:** The backend the app is calling is unreachable or returning errors. With
  `npm run dev`, that backend is the shared public server at `cangdu.org`, which is frequently
  offline. This exact symptom is reported many times in the project's issue tracker
  ("接口挂了", "后端服务挂了", "访问接口404").
- **Solution:** Run your own backend and use local mode:

  ```bash
  # start node-elm (see its README), then:
  npm run local
  ```

- **Prevention:** Always develop against a local `node-elm` instance rather than the public
  demo server.

### Error: the app looks huge or stretched on a desktop browser

- **Cause:** The layout uses **rem units** sized for a 320 px-wide mobile screen
  (`src/config/rem.js` sets the root font size from the viewport width). A full-width desktop
  window makes every element oversized.
- **Solution:** Open Chrome DevTools and toggle the **device toolbar** (`Ctrl+Shift+M` /
  `Cmd+Shift+M`), then choose a phone preset. The layout snaps into place.
- **Prevention:** Always preview in mobile emulation, or on an actual phone.

### Error: `npm install` fails while building `node-sass`

```text
gyp ERR! build error
Error: node-sass ... failed
```

- **Cause:** `node-sass` compiles a native binary bound to your Node version. On Node releases
  newer than the project targets, the prebuilt binary is unavailable and the source build can
  fail (reported in the issues as persistent sass install problems).
- **Solution:** Use a Node version from the project's era with a version manager:

  ```bash
  nvm install 8
  nvm use 8
  rm -rf node_modules
  npm install      # or: yarn
  ```

- **Prevention:** Pin your Node version (e.g. with an `.nvmrc`) when working on this project.

### Error: `Browserslist: caniuse-lite is outdated` / `browserslist@1.7.7` warning

- **Cause:** The toolchain is old enough that its `browserslist` data is stale (reported as
  issue #434). It is a **warning**, not a failure.
- **Solution:** You can usually ignore it. The build still completes.
- **Prevention:** None needed for a learning checkout; the warning is cosmetic.

### Error: page is blank after switching cities or routes

- **Cause:** Most page data is fetched on navigation. If the backend is unreachable, the page
  shell renders but stays empty.
- **Solution:** Confirm the backend is up (see the first entry) and that you are signed in for
  account-only screens.
- **Prevention:** Use local mode and log in before exploring profile/order screens.

### Error: login captcha image is broken

- **Cause:** The captcha image is fetched from the backend; if the backend is down, the image
  fails to load.
- **Solution:** Tap **"看不清，换一张"** ("can't read it, change it") to refetch, after confirming
  the backend is reachable.
- **Prevention:** Run against a working backend.

---

## 9. Frequently Asked Questions

**Q: Can I actually order food with this?**
No. vue2-elm is a front-end **learning project** that clones the Ele.me experience. It is not
affiliated with Ele.me, and **payment is intentionally disabled**. You can browse, build a cart,
and place an (unpaid) order to study the flow, but no real transaction occurs.

**Q: Why is the screen empty / why won't restaurants load?**
Almost always because the backend is unreachable. With `npm run dev` you depend on the public
`cangdu.org` server, which is often offline. Run `node-elm` locally and use `npm run local`.

**Q: What's the difference between `npm run dev` and `npm run local`?**
`npm run dev` points the app at the public demo backend; `npm run local` points it at a
`node-elm` backend you run yourself. Use `local` for reliable development.

**Q: Do I need the backend at all?**
Only to see live data and exercise the full flow. To read and study the front-end source, you
don't need it running — the app will simply show no data.

**Q: Which browser should I use?**
Chrome with mobile/device emulation. The layout is built for a phone-sized viewport.

**Q: I can't log in / what credentials do I use?**
Against the demo backend, unknown accounts are auto-registered on first login. Type any
username/password (and the on-screen captcha) and you'll be signed in.

**Q: My cart disappeared / how is it stored?**
The cart lives in the browser's `localStorage` under `buyCart`, and your login under `user_id`.
Clearing site data or those keys resets the cart/session.

**Q: `npm install` keeps failing — what now?**
The usual culprit is `node-sass` versus your Node version. Switch to an older Node (e.g. via
`nvm use 8`), delete `node_modules`, and reinstall. See
[Troubleshooting](#error-npm-install-fails-while-building-node-sass).

**Q: Is there an English version of the project's own notes?**
Yes — the repository ships both `README.md` (Chinese) and `README-en.md` (English).

**Q: Can I deploy what `npm run build` produces?**
Yes. The build outputs a static site into `elm/`; host that folder on any static web server.

**Q: Is there a backend admin UI?**
Yes — [`vue2-manage`](https://github.com/bailicangdu/vue2-manage), an optional Element-UI
console for the `node-elm` data.

---

## 10. Reference

### 10.1 npm scripts

| Script | Command | Purpose |
|---|---|---|
| `dev` | `npm run dev` | Dev server → public `cangdu.org` backend |
| `local` | `npm run local` | Dev server → local `node-elm` backend |
| `build` | `npm run build` | Production build into `elm/` |

### 10.2 Main screens and routes

The app uses **hash routing**, so every route is reached as `…/#/<path>`.

| Screen | Route | Purpose |
|---|---|---|
| Home | `/home` | Choose a city |
| City | `/city/:cityid` | Selected-city entry |
| Msite | `/msite` | Nearby restaurant list |
| Food | `/food` | Filter & sort restaurants |
| Search | `/search/:geohash` | Search restaurants/dishes |
| Shop | `/shop` | Restaurant menu + cart |
| Food detail | `/shop/foodDetail` | Single dish detail |
| Shop detail | `/shop/shopDetail` | Restaurant info & ratings |
| Login | `/login` | Sign in / auto-register |
| Confirm Order | `/confirmOrder` | Checkout (address, remark, invoice) |
| Order list | `/order` | Past orders |
| Order detail | `/order/orderDetail` | One order's snapshot |
| Profile | `/profile` | Account, avatar, addresses |
| Forget | `/forget` | Reset password |
| Service | `/service` | Help center |
| Benefit | `/benefit` | Red packets, coupons, referral |
| Balance | `/balance` | Account balance |
| Points | `/points` | Loyalty points |
| VIP card | `/vipcard` | VIP card purchase & usage |
| Find | `/find` | Discovery |
| Download | `/download` | App-download promo |

### 10.3 Technology stack

| Layer | Technology |
|---|---|
| Framework | Vue 2 |
| State management | Vuex 2 |
| Routing | Vue Router 2 (hash mode) |
| Build tool | webpack 1 + Babel (ES6/7) |
| Styles | Sass (SCSS), Flexbox, rem layout |
| Data fetching | `fetch` (with XHR fallback) |
| Scrolling/UX | better-scroll, fastclick, Swiper, SVG icons |

### 10.4 Browser storage keys

| Key | Contents |
|---|---|
| `buyCart` | Your current shopping cart (per restaurant) |
| `user_id` | Your signed-in user id |

### 10.5 Related projects

| Project | Role |
|---|---|
| [`node-elm`](https://github.com/bailicangdu/node-elm) | The backend API that serves all data |
| [`vue2-manage`](https://github.com/bailicangdu/vue2-manage) | Element-UI admin console for the backend |

---

_Generated June 2026 from bailicangdu/vue2-elm at b85ff02. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
