返回

一步步构建一个简单的 Instagram 应用

后端

你有没有想过如何创建一个像 Instagram 这样的社交媒体应用程序?你想知道需要什么技术和工具吗?

在这篇文章中,我们将引导您逐步构建一个简单的 Instagram 应用,使用 Phoenix LiveView、Elixir、TailwindCSS 和 AlpineJS。我们将从搭建基本结构开始,然后逐步添加用户注册、登录、发帖等功能,最终完成一个完整的 Instagram 应用。

先决条件

在开始之前,您需要确保您的系统满足以下先决条件:

  • Elixir 1.13 或更高版本
  • Phoenix Framework 1.7 或更高版本
  • Node.js 16 或更高版本
  • npm 8 或更高版本
  • TailwindCSS 3 或更高版本
  • AlpineJS 3 或更高版本

如果您还没有安装这些工具,请按照相应的安装指南进行安装。

搭建基本结构

首先,我们需要搭建一个基本的 Phoenix 项目。打开您的终端,并执行以下命令:

mix phx.new instagram

这将创建一个名为 instagram 的新 Phoenix 项目。进入该项目目录:

cd instagram

接下来,我们需要安装必要的依赖项。首先,我们需要安装 Phoenix LiveView:

mix deps.get phoenix_live_view

然后,我们需要安装 Elixir Live:

mix deps.get live

最后,我们需要安装 TailwindCSS 和 AlpineJS:

npm install -D tailwindcss alpinejs

配置 Phoenix 项目

接下来,我们需要配置 Phoenix 项目。首先,在 config/config.exs 文件中添加以下代码:

config :live, :csrf_protection, [csrf_token: :ajax]

这将启用 CSRF 保护。

接下来,我们需要在 assets/tailwind.css 文件中添加以下代码:

@tailwind base;
@tailwind components;
@tailwind utilities;

这将加载 TailwindCSS 的基本样式、组件和实用程序。

创建第一个 LiveView

现在,我们可以创建我们的第一个 LiveView。在 lib/instagram_web/live/post_live.ex 文件中添加以下代码:

defmodule InstagramWeb.PostLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
    <h1>Hello, world!</h1>
    """
  end
end

这将创建一个名为 PostLive 的 LiveView。

添加 LiveView 路由

接下来,我们需要在 lib/instagram_web/router.ex 文件中添加以下代码:

scope "/", InstagramWeb do
  pipe_through :browser

  live "/", PostLive
end

这将添加一个新的路由,将根路径 / 映射到 PostLive LiveView。

启动 Phoenix 服务器

现在,我们可以启动 Phoenix 服务器。在终端中执行以下命令:

mix phx.server

这将启动 Phoenix 服务器,您可以在浏览器中访问 http://localhost:4000 来查看您的 Instagram 应用。

逐步构建应用

现在,我们已经搭建了基本结构,就可以逐步构建我们的 Instagram 应用了。我们将添加用户注册、登录、发帖等功能。

用户注册

首先,我们需要添加用户注册功能。在 lib/instagram_web/controllers/user_controller.ex 文件中添加以下代码:

defmodule InstagramWeb.UserController do
  use InstagramWeb, :controller

  def new(conn, _params) do
    render conn, "new.html"
  end

  def create(conn, %{"user" => user_params}) do
    case Instagram.Accounts.create_user(user_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "User created successfully.")
        |> redirect(to: "/")

      {:error, changeset} ->
        render conn, "new.html", changeset: changeset
    end
  end
end

这将添加一个新的控制器 UserController,它包含了用户注册的逻辑。

接下来,我们需要在 lib/instagram_web/views/user_view.ex 文件中添加以下代码:

defmodule InstagramWeb.UserView do
  use InstagramWeb, :view

  def render("new.html", assigns) do
    ~H"""
    <h1>Sign up</h1>

    <%= form_for @changeset, "/users", fn f -> %>
      <div>
        <%= label f, :name, "Name" %>
        <%= text_input f, :name %>
      </div>

      <div>
        <%= label f, :email, "Email" %>
        <%= text_input f, :email %>
      </div>

      <div>
        <%= label f, :password, "Password" %>
        <%= password_input f, :password %>
      </div>

      <div>
        <%= submit "Sign up" %>
      </div>
    <% end %>
    """
  end
end

这将添加一个新的视图 UserView,它包含了用户注册表单的 HTML 代码。

用户登录

接下来,我们需要添加用户登录功能。在 lib/instagram_web/controllers/session_controller.ex 文件中添加以下代码:

defmodule InstagramWeb.SessionController do
  use InstagramWeb, :controller

  def new(conn, _params) do
    render conn, "new.html"
  end

  def create(conn, %{"session" => session_params}) do
    case Instagram.Accounts.login(session_params) do
      {:ok, user} ->
        conn
        |> put_flash(:info, "Logged in successfully.")
        |> redirect(to: "/")

      {:error, _} ->
        render conn, "new.html"
    end
  end

  def delete(conn, _params) do
    conn
    |> put_flash(:info, "Logged out successfully.")
    |> redirect(to: "/")
  end
end

这将添加一个新的控制器 SessionController,它包含了用户登录的逻辑。

接下来,我们需要在 lib/instagram_web/views/session_view.ex 文件中添加以下代码:

defmodule InstagramWeb.SessionView do
  use InstagramWeb, :view

  def render("new.html", assigns) do
    ~H"""
    <h1>Login</h1>

    <%= form_for @changeset, "/login", fn f -> %>
      <div>
        <%= label f, :email, "Email" %>
        <%= text_input f, :email %>
      </div>

      <div>
        <%= label f, :password, "Password" %>
        <%= password_input f, :password %>
      </div>

      <div>
        <%= submit "Login" %>
      </div>
    <% end %>
    """
  end
end

这将添加一个新的视图 SessionView,它包含了用户登录表单的 HTML 代码。

发帖

最后,我们需要添加发帖功能。在 lib/instagram_web/controllers/post_controller.ex 文件中添加以下代码:

defmodule InstagramWeb.PostController do
  use InstagramWeb, :controller

  def new(conn, _params) do
    render conn, "new.html"
  end

  def create(conn, %{"post" => post_params}) do
    case Instagram.Posts.create_post(post_params) do
      {:ok, post} ->
        conn
        |> put_flash(:info, "Post created successfully.")
        |> redirect(to: "/")

      {:error, changeset} ->
        render conn, "new.html", changeset: changeset
    end
  end
end

这将添加一个新的控制器 PostController,它包含了发帖的逻辑。

接下来,我们需要在 lib/instagram_web/views/post_view.ex 文件中添加以下代码:

defmodule InstagramWeb.PostView do
  use InstagramWeb, :view

  def render("new.html", assigns) do
    ~H"""
    <h1>New Post</h1>

    <%= form_for @changeset, "/posts", fn f -> %>
      <div>
        <%= label f, :title, "Title" %>
        <%= text_input f, :title %>
      </div>

      <div>
        <%= label f, :body, "Body" %>
        <%= textarea f, :body %>
      </div>

      <div>
        <%= submit "Post