如果你使用过React或者Vue这类流行的前端框架,你会对可复用模板/组件的概念感到熟悉。实际上,在Phoenix中,我们也可以使用View和eex构建可复用模板,当然咯,状态流和数据流监听什么的还做不到,但是对于Dumb Components来说,很大一部分可以搞定。
我们来看一下一个基本的模板。
<Tabs>
<Tab name="All Products" />
<Tab name="Featured" />
</Tabs>
这样的好处是,当你需要修改Tabs或Tabs时,你只需要修改一处地方,然后整个应用的模板都会修改了。
在Phoenix中,我们可以实现这个功能。
1. 创建 ComponentView 和 templates/component 目录
defmodule MyApp.Web.ComponentView do
use MyApp.Web, :view
end
2. 定义 Component 的模板
<!-- templates/component/tabs.html -->
<ul class="tabs">
<%= assigns[:do] %>
</ul>
<!-- templates/component/tab.html -->
<li class="tab"><%= assigns[:name] %></li>
3. 当你需要tabs时使用这些模板
<%= render ComponentView, "tabs.html" do %>
<%= render ComponentView, "tab.html", name: "All Products" %>
<%= render ComponentView, "tab.html", name: "Featured" %>
<% end %>
目前,它能工作,但是比较冗余,我们来增加 ComponentHelpers 模块
# views/component_helpers.ex
defmodule MyApp.Web.ComponentHelpers do
def component(template, assigns) do
MyApp.Web.ComponentView.render(template, assigns)
end
def component(template, assigns, do: block) do
MyApp.Web.ComponentView.render(template, Keyword.merge(assigns, [do: block]))
end
end
然后,在 MyApp.Web 的 view 模块中导入
def view do
quote do
# ...
import MyApp.Web.ComponentHelpers
end
end
现在的 markup 变为了
<%= component "tabs.html" do %>
<%= component "tab.html", name: "All Products" %>
<%= component "tab.html", name: "Featured" %>
<% end %>
你还可以将它继续精简
<%= c "tabs.html" do %>
<%= c "tab.html", name: "All Products" %>
<%= c "tab.html", name: "Featured" %>
<% end %>
它虽然没有像React那样精简,但是也差不多了
<Tabs>
<Tab name="All Products" />
<Tab name="Featured" />
</Tabs>
这只是一个非常简单的示例,并不需要花很大力气,当你需要使用复杂的 markup 时,你可以考虑这种方式。
Ref
http://blog.danielberkompas.com/2017/01/17/reusable-templates-in-phoenix.html