http://chloerei.com/2018/02/24/stimulus/
说是简介,其实不介绍语法,而是介绍它解决的问题,以及是否对各个场景适用。
喜欢前端的这个思路:
现在大部分前端的复杂,来自工具产生的附属性复杂,而非需求的本质性复杂
和我们这里的实践有些异曲同工。
实际中,Turbolinks 很有用吗?有些觉得:Turbolinks 进行页面加速,是否以增加开发烦恼为代价? 3 Reasons Why Turbolinks Is Not Worth The Effort
以前分享过 Turbolinks 的话题,最直观效果就是看这个视频 http://chloerei.com/rubyconfchina2016/#/4/4 ,一旦用过就很难回到没有 Turbolinks 的环境,有多少地方能优化出 200ms 呢?
理解了 Turbolinks 提供的 SPA 环境之后,增加的开发成本很小,远小于前端渲染的 SPA 方案。
利用 turbolinks 和 stimulus, 再改改 slim, 就和 vue + pug 差不多了...
简化的 slim 模板:
/ hello.slim
div @controller="hello"
input type="text" @target="hello.name"
button @click="hello#greet" Greet
span @target="hello.output"
目标是让它生成 stimulus 对应的 HTML:
<div data-controller="hello">
<input data-target="hello.name" type="text" />
<button data-action="click->hello#greet">Greet</button>
<span data-target="hello.output"></span>
</div>
魔改的 slim 和测试:
require 'slim'
module Slim
class Parser
def parse_attributes(attributes)
# Check to see if there is a delimiter right after the tag name
delimiter = nil
if @line =~ @attr_list_delims_re
delimiter = @attr_list_delims[$1]
@line = $'
end
if delimiter
boolean_attr_re = /#{@attr_name}(?=(\s|#{Regexp.escape delimiter}|\Z))/
end_re = /\A\s*#{Regexp.escape delimiter}/
end
while true
case @line
when @splat_attrs_regexp
# Splat attribute
@line = $'
attributes << [:slim, :splat, parse_ruby_code(delimiter)]
when /\A\s*@(\w+)\s*=\s*(["'])([\w\.\-\>\#]+)\2/
attr_value = $3
if attr_value['#']
@line = $'
attr_value = "#$1->#{attr_value}"
attributes << [:html, :attr, 'data-action', [:slim, :interpolate, attr_value]]
else
case $1
when 'controller'
@line = $'
attributes << [:html, :attr, 'data-controller', [:slim, :interpolate, attr_value]]
when 'target'
@line = $'
attributes << [:html, :attr, 'data-target', [:slim, :interpolate, attr_value]]
else
syntax_error!('Must use "@controller=" or "@target=" or assign "controller#action"')
end
end
when /\A\s*@/
syntax_error!('Expect @controller or @target or event names')
when @quoted_attr_re
# Value is quoted (static)
@line = $'
attributes << [:html, :attr, $1,
[:escape, $2.empty?, [:slim, :interpolate, parse_quoted_attribute($3)]]]
when @code_attr_re
# Value is ruby code
@line = $'
name = $1
escape = $2.empty?
value = parse_ruby_code(delimiter)
syntax_error!('Invalid empty attribute') if value.empty?
attributes << [:html, :attr, name, [:slim, :attrvalue, escape, value]]
else
break unless delimiter
case @line
when boolean_attr_re
# Boolean attribute
@line = $'
attributes << [:html, :attr, $1, [:multi]]
when end_re
# Find ending delimiter
@line = $'
break
else
# Found something where an attribute should be
@line.lstrip!
syntax_error!('Expected attribute') unless @line.empty?
# Attributes span multiple lines
@stacks.last << [:newline]
syntax_error!("Expected closing delimiter #{delimiter}") if @lines.empty?
next_line
end
end
end
end
end
end
result = Slim::Template.new('hello.slim').render binding
puts result
思路老實說很不錯 初看最少免去特別處理前端的 routing 跟 form 的
但還是半觀望態度 始終現在前端太依賴第三方套件了
而且也擔心業務複雜起來是否需要重寫。。。