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. Understanding that split (covered in Requirements and Running the App) is the single most important thing for getting it working.
Table of Contents
- Quick Start
- Requirements
- Installation
- Running the App
- Taking a Tour of the App
- Common Tasks
- Configuration You Can Change
- Troubleshooting
- Frequently Asked Questions
- Reference
1. Quick Start
If you already have a recent-enough Node.js toolchain and just want to see the app, run:
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.
Tip
npm run devpoints the app at the project's public demo backend atcangdu.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 and 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 releasesnpm installmay fail while buildingnode-sass. The Troubleshooting 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 asnvm.
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 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-elmlocally.
3. Installation
3.1 Clone and install dependencies
git clone https://github.com/bailicangdu/vue2-elm.git
cd vue2-elm
npm install
Expected output (abbreviated):
added N packages in Ms
Tip
Yarn is often smoother than npm for this older dependency tree because of its lockfile (
yarn.lockis committed to the repo):yarn
3.2 Verify the install
A successful install creates a node_modules/ directory and leaves the three runnable scripts
available:
npm run
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)
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 a404. 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:
-
Clone and start the backend in a separate terminal:
git clone https://github.com/bailicangdu/node-elm.git cd node-elm # follow node-elm's own README to install dependencies and start it -
In the vue2-elm terminal, start the front end in local mode:
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, built with Element UI. It is optional and only relevant if you want to administer thenode-elmdata.
4.3 Building for production (npm run build)
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 ownnpm run buildoverwrites it. When studying the code, readsrc/, notelm/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
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).
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-elmbackend, 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
# 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
- From Home, choose a city.
- On Msite, open any restaurant.
- Add one or more dishes to the cart.
- Tap the cart and proceed to Confirm Order.
- If prompted, log in (any username/password works against the demo backend).
- Choose or add a delivery address, set a remark, and submit.
- 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
buyCartkey (cart contents) and/oruser_idkey (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. Picknpm run dev(public backend) ornpm run local(local backend) and the correct hosts follow. Deeper configuration — the dev-server proxy targets and build paths — lives inconfig/index.jsand 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
{"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 atcangdu.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:
# start node-elm (see its README), then: npm run local -
Prevention: Always develop against a local
node-elminstance 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.jssets 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
gyp ERR! build error
Error: node-sass ... failed
-
Cause:
node-sasscompiles 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:
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
browserslistdata 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.
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, 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 |
The backend API that serves all data |
vue2-manage |
Element-UI admin console for the backend |