Ember博客应用 #
一、项目概述 #
1.1 功能需求 #
- 文章列表展示
- 文章详情查看
- 文章创建/编辑
- 文章删除
- 用户认证
- 评论功能
1.2 技术栈 #
- Ember.js 5.x
- Ember Data
- Ember CLI
- Mirage (模拟API)
二、项目初始化 #
2.1 创建项目 #
bash
ember new blog-app
cd blog-app
ember install ember-cli-mirage
2.2 配置路由 #
javascript
// app/router.js
Router.map(function () {
this.route('home', { path: '/' });
this.route('posts', function () {
this.route('new');
this.route('show', { path: '/:post_id' });
this.route('edit', { path: '/:post_id/edit' });
});
this.route('login');
this.route('register');
});
三、数据模型 #
3.1 Post模型 #
javascript
// app/models/post.js
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
export default class PostModel extends Model {
@attr('string') title;
@attr('string') body;
@attr('string') excerpt;
@attr('date') createdAt;
@attr('date') updatedAt;
@attr('boolean') isPublished;
@belongsTo('user') author;
@hasMany('comment') comments;
get formattedDate() {
return this.createdAt?.toLocaleDateString('zh-CN');
}
}
3.2 User模型 #
javascript
// app/models/user.js
import Model, { attr } from '@ember-data/model';
export default class UserModel extends Model {
@attr('string') name;
@attr('string') email;
@attr('string') avatar;
}
3.3 Comment模型 #
javascript
// app/models/comment.js
import Model, { attr, belongsTo } from '@ember-data/model';
export default class CommentModel extends Model {
@attr('string') body;
@attr('date') createdAt;
@belongsTo('user') author;
@belongsTo('post') post;
}
四、路由实现 #
4.1 文章列表 #
javascript
// app/routes/posts.js
import Route from '@ember/routing/route';
export default class PostsRoute extends Route {
model() {
return this.store.query('post', {
filter: { isPublished: true },
include: 'author',
sort: '-createdAt',
});
}
}
4.2 文章详情 #
javascript
// app/routes/posts/show.js
import Route from '@ember/routing/route';
export default class PostsShowRoute extends Route {
model(params) {
return this.store.findRecord('post', params.post_id, {
include: 'author,comments.author',
});
}
}
五、组件实现 #
5.1 文章卡片组件 #
javascript
// app/components/post-card.js
import Component from '@glimmer/component';
export default class PostCardComponent extends Component {
get excerpt() {
const body = this.args.post.body || '';
return body.length > 150 ? body.substring(0, 150) + '...' : body;
}
}
handlebars
{{! app/components/post-card.hbs}}
<article class="post-card">
<LinkTo @route="posts.show" @model={{@post.id}}>
<h2 class="post-title">{{@post.title}}</h2>
</LinkTo>
<p class="post-excerpt">{{this.excerpt}}</p>
<footer class="post-meta">
<span class="author">{{@post.author.name}}</span>
<span class="date">{{@post.formattedDate}}</span>
</footer>
</article>
5.2 文章表单组件 #
javascript
// app/components/post-form.js
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class PostFormComponent extends Component {
@tracked title = this.args.post?.title || '';
@tracked body = this.args.post?.body || '';
@tracked isPublished = this.args.post?.isPublished || false;
@action
async submit(event) {
event.preventDefault();
const postData = {
title: this.title,
body: this.body,
isPublished: this.isPublished,
};
if (this.args.onSubmit) {
await this.args.onSubmit(postData);
}
}
}
六、总结 #
博客应用要点:
| 模块 | 技术 |
|---|---|
| 路由 | Ember Router |
| 数据 | Ember Data |
| 组件 | Glimmer组件 |
| 样式 | CSS |
通过完整项目实践掌握Ember开发。
最后更新:2026-03-28