返回

从头搭建Vue.js、TypeScript、Express.js全栈SSR博客系统

前端

摘要:

在这篇文章中,我们将从头开始构建一个功能齐全的Vue.js、TypeScript、Express.js全栈SSR博客系统。我们将探讨SSR的工作原理,并逐步指导您完成构建前端和后端的整个过程。通过本教程,您将获得宝贵的经验,了解如何从零开始构建复杂的现代网络应用程序。

前端起步

1. 初始化项目

首先,我们需要使用Vue CLI创建一个新的Vue.js项目:

vue create vue-ssr-blog

2. 安装依赖项

接下来,我们需要安装必要的依赖项:

cd vue-ssr-blog
npm install express body-parser cookie-parser

3. 配置Vue.js路由

src/router/index.js文件中,配置路由:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home.vue'
import Post from '@/views/Post.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/post/:id',
      name: 'post',
      component: Post
    }
  ]
})

4. 创建Vuex存储

src/store/index.js文件中,创建Vuex存储:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    posts: []
  },
  getters: {
    allPosts: state => state.posts
  },
  mutations: {
    addPost(state, post) {
      state.posts.push(post)
    }
  },
  actions: {
    async fetchPosts({ commit }) {
      const posts = await fetch('/api/posts').then(res => res.json())
      commit('addPost', posts)
    }
  }
})

5. 创建根组件

src/App.vue文件中,创建根组件:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

6. 创建主页组件

src/views/Home.vue文件中,创建主页组件:

<template>
  <div class="home-page">
    <h1>Home Page</h1>
    <ul>
      <li v-for="post in posts" :key="post.id">
        <router-link :to="'/post/' + post.id">{{ post.title }}</router-link>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Home',
  computed: {
    ...mapState('posts', ['allPosts'])
  },
  created() {
    this.$store.dispatch('fetchPosts')
  }
}
</script>

7. 创建帖子组件

src/views/Post.vue文件中,创建帖子组件:

<template>
  <div class="post-page">
    <h1>{{ post.title }}</h1>
    <p>{{ post.content }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Post',
  computed: {
    ...mapState('posts', ['allPosts'])
  },
  created() {
    const id = this.$route.params.id
    this.$store.dispatch('fetchPost', id)
  }
}
</script>