Skip to content

Commit da22e66

Browse files
committed
Updated code to use and be compatible with v2.2.4 of vue.js
1 parent 399bd7b commit da22e66

File tree

5 files changed

+84
-147
lines changed

5 files changed

+84
-147
lines changed

build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ workbenchSettings
66

77
name := "Scala.js+Vue.js example"
88

9-
version := "0.2"
9+
version := "2.2.4"
1010

1111
scalaVersion := "2.11.8"
1212

1313
libraryDependencies ++= Seq(
1414
"org.scala-js" %%% "scalajs-dom" % "0.9.1"
1515
)
1616

17-
bootSnippet := "example.T1().main(document.getElementById('mydiv'));"
17+
bootSnippet := ""
1818

1919
updateBrowsers <<= updateBrowsers.triggeredBy(fastOptJS in Compile)
2020

project/plugins.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")
22

3-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.12")
3+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.14")
44

55
addSbtPlugin("com.lihaoyi" % "workbench" % "0.2.3")

src/main/resources/index-dev.html

Lines changed: 33 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -26,56 +26,14 @@
2626
height: 20px;
2727
background: black;
2828
}
29-
.bounce-enter {
30-
-webkit-animation: bounce-in .5s;
31-
animation: bounce-in .5s;
32-
}
33-
.bounce-leave {
34-
-webkit-animation: bounce-out .5s;
35-
animation: bounce-out .5s;
36-
}
3729

38-
@-webkit-keyframes bounce-in {
39-
0% {
40-
-webkit-transform: scale(0);
30+
.fade-enter-active, .fade-leave-active {
31+
transition: opacity .5s
4132
}
42-
50% {
43-
-webkit-transform: scale(1.2);
33+
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
34+
opacity: 0
4435
}
45-
100% {
46-
-webkit-transform: scale(1);
47-
}
48-
}
49-
50-
@keyframes bounce-in {
51-
0% {
52-
transform: scale(0);
53-
}
54-
50% {
55-
transform: scale(1.2);
56-
}
57-
100% {
58-
transform: scale(1);
59-
}
60-
}
61-
62-
@-webkit-keyframes bounce-out {
63-
0% {
64-
-webkit-transform: scale(1);
65-
}
66-
100% {
67-
-webkit-transform: scale(0);
68-
}
69-
}
7036

71-
@keyframes bounce-out {
72-
0% {
73-
transform: scale(1);
74-
}
75-
100% {
76-
transform: scale(0);
77-
}
78-
}
7937
</style>
8038
</head>
8139
<body>
@@ -84,46 +42,47 @@
8442
<div id="demo">
8543
<div style="float:left;height:400px;overflow: auto;">
8644
Title=<input v-model="title"/>
87-
<ol>
88-
<li v-transition="bounce" v-repeat="todos">
89-
<span v-on="click: done = !done" class="{{done ? 'done' : ''}}">
90-
{{content}}
91-
</span>
92-
<button v-on="click:remove($index)">Remove</button>
93-
</li>
94-
</ol>
45+
46+
<transition-group name="fade" tag="ol">
47+
<li v-for="(todo,index) in todos" :key="todo">
48+
<span @click="todo.done = !todo.done" :class="{done: todo.done}">
49+
{{todo.content}}
50+
<button @click="remove(index)">Remove</button>
51+
</span>
52+
</li>
53+
</transition-group>
54+
9555
Tasks# {{todos.length}}<BR/>
9656
N={{n}}<BR/>
9757
</div>
9858
<div style="padding-left:30px;height:400px;overflow: auto;width:30%"><pre>data JSON: {{$data | json 2}}</pre></div>
9959

10060
<div style="clear:left">
10161
Using a v-text directive title=<span v-text="title"></span>
102-
<div>Smooth CSS animation:
103-
<input type="button" value="+" v-on="click: barValue += 50"/>
104-
<input type="button" value="-" v-on="click: barValue -= 50">
62+
<div>Smooth CSS animation:
63+
<input type="button" value="+" @click="barValue += 50"/>
64+
<input type="button" value="-" @click="barValue -= 50">
10565
</div>
106-
<div class="bar" v-style="{ width: barValue + 'px' }"></div>
66+
<div class="bar" :style="{ width: barValue + 'px' }"></div>
10767
<div v-text="'Using a v-text directive with inline expression, title='+title"></div>
10868
<div>Title reversed={{title | reverse}}</div>
109-
<div>Title wrapper={{title | wrap '<<' '>>'}}</div>
110-
<div v-my-directive="myarg:title">xx</div>
111-
<my-component my-msg="hello">Special content</my-component>
112-
113-
<button v-on="click:clickHandler">Call clickHandler in Scala</button>
114-
<button v-on="click:n++">Increment N</button>
115-
116-
<button v-on="click:addTask">Add Task</button>
117-
<button v-on="click:change1st">Change 1st</button>
118-
<button v-on="click:remove(0,$event)">Remove 1st</button>
119-
<button v-on="click:flipAll">Flip All</button><BR/><BR/>
120-
Via custom filter <select v-model="selected" options="todos | extract 'content'"></select>
121-
Via computed property<select v-model="selected" options="todosFiltered"></select>
69+
<div>Title wrapper={{title | wrap('<<','>>')}}</div>
70+
<div v-mydirective="title">xx</div>
71+
<my-component my-msg="hello">Special content</my-component>
72+
<!---->
73+
<button @click="clickHandler">Call clickHandler in Scala</button>
74+
<button @click="n++">Increment N</button>
75+
<!---->
76+
<button @click="addTask">Add Task</button>
77+
<button @click="change1st">Change 1st</button>
78+
<button @click="remove(0)">Remove 1st</button>
79+
<button @click="flipAll">Flip All</button><BR/><BR/>
80+
Todos computed: {{ todosComputed }}
12281
</div>
12382
</div>
12483

12584

126-
<script src='http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.14/vue.min.js'></script>
85+
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js'></script>
12786
<div id="mydiv"></div>
12887

12988
<script type="text/javascript" src="../scala-js-vue-js-example-fastopt.js"></script>
@@ -133,17 +92,11 @@
13392
// custom filter to pull out field
13493
// Now done in Scala.
13594

136-
//Vue.filter('extract', function (value, keyToExtract) {
137-
// return value.map(function (item) {
138-
// return item[keyToExtract]
139-
// })
140-
// })
14195
// we get DemoVue back from Scala, then use it
14296
var demo=example.Todo().main();
143-
demo.title="Todo Todo Todo"
97+
14498
demo.todos.push({done:false,content:"Extra task"})
145-
//demo.todos[0]=({done:false,content:"!!!!"})
146-
//demo.todos.$set(0, {done:false,content:"!!!!"})
99+
147100
</script>
148101

149102
</body>

src/main/scala/com/felstar/scalajs/vue/Vue.scala

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ import js.annotation.JSName
2626
def $watch(expOrFn:js.Any,callback:Callback):Unwatch=js.native
2727
def $watch(expOrFn:js.Any,callback:Callback,options:js.Any):Unwatch=js.native
2828
def $get(exp:String):js.Any=js.native
29-
def $set(keypath:String,value:js.Any):Unit=js.native
29+
def $set(target:js.Any,key:js.Any, value:js.Any):Unit=js.native
30+
def $delete(target:js.Any,key:js.Any):Unit=js.native
3031
def $add(key:String,value:js.Any):Unit=js.native
31-
def $delete(key:String):Unit=js.native
3232
def $eval(exp:String):js.Any=js.native
3333
def $interpolate(templateString:String):js.Any=js.native
34-
def $log(keypath:String):Unit=js.native
35-
def $log():Unit=js.native
34+
3635
// Events
3736
def $dispatch(event:String):Unit=js.native
3837
def $dispatch(event:String,args:js.Any):Unit=js.native
@@ -87,26 +86,22 @@ import js.annotation.JSName
8786
def transition(id:String):js.Any=js.native
8887
def transition(id:String,definition:js.Any):js.Any=js.native
8988
def partial(id:String):js.Any=js.native
90-
def partial(id:String,template:String):js.Any=js.native
89+
def partial(id:String,template:String):js.Any=js.native
9190
def use(plugin:js.Any):js.Any=js.native
9291
def use(plugin:js.Any,args:js.Any*):js.Any=js.native
92+
def set(target:js.Any,key:js.Any, value:js.Any):Unit=js.native
93+
def delete(target:js.Any,key:js.Any):Unit=js.native
9394
}
9495

95-
@js.native
96-
trait VueArray[T] extends js.Array[T]{
97-
def $set(idx:Int,obj:T):Unit=js.native
98-
def $remove(idx:Int):Unit=js.native
99-
}
100-
10196
@js.native
10297
class Directive extends js.Object {
103-
val el:dom.raw.Element =js.native
104-
val vm:Vue =js.native
105-
val expression:js.Any =js.native
106-
val arg:String =js.native
107-
val raw:String =js.native
108-
val name:String =js.native
98+
val name:String =js.native
99+
val rawName:String =js.native
100+
val value:String =js.native
101+
val expression:String =js.native
102+
val modifiers:js.Any =js.native
103+
val `def`:js.Any =js.native
109104
}
110-
111-
105+
106+
112107

src/main/scala/example/Todo.scala

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
package example
22
import org.scalajs.dom
3+
34
import scalajs.js.annotation.JSExport
45
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
56
import dom.ext.Ajax
7+
68
import scalajs.js
79
import js.Dynamic.literal
810
import com.felstar.scalajs.vue._
11+
import org.scalajs.dom.raw.HTMLElement
12+
913
import js.annotation.JSName
1014

1115
@JSExport
1216
object Todo extends {
1317

14-
// Strongly typed wrapper around below dynamic Vue
15-
// You don't have to do this, can access as js.Dynamic
16-
// But obviously type safety is a good thing, a Scala thing.
1718
@js.native
1819
trait DemoVue extends Vue{
1920
var title:String=js.native
2021
var n:Double=js.native
21-
var todos:VueArray[DemoVueTodo]=js.native
22-
}
23-
22+
var todos:js.Array[DemoVueTodo]=js.native
23+
}
24+
2425
type DemoVueMethod=js.ThisFunction0[DemoVue,_]
25-
26+
2627
@js.native
27-
trait DemoVueTodo extends js.Object{
28+
trait DemoVueTodo extends js.Object{
2829
var done:Boolean=js.native
2930
var content:String=js.native
3031
}
31-
32+
3233
object DemoVueTodo{
3334
def apply(done:Boolean,content:String)=literal(done=done,content=content).asInstanceOf[DemoVueTodo]
3435
}
@@ -38,59 +39,47 @@ object Todo extends {
3839
// could have returned raw Vue of course
3940
def main():DemoVue = {
4041

41-
val tasks=js.Array("Learn JavaScript","Learn Vue.js","Learn Scala.js")
42-
42+
val tasks=js.Array("Learn JavaScript","Learn Vue.js","Learn Scala.js")
43+
//
4344
def ts=new java.util.Date().toString
4445

4546
Vue.component("my-component", literal(
4647
props=js.Array("myMsg"),
47-
template="<p>A custom component with msg {{myMsg}} <content>default content</content></p>"))
48+
template="<p>A custom component with msg {{myMsg}} <slot>default content</slot></p>"))
4849

49-
// Note, don't need to define as js.ThisFunction, as signature expects this
50-
// Vue.directive("my-directive", (directive:Directive,value:js.Any)=> {
51-
// println(s"myDirective! expression=${directive.expression} arg=${directive.arg} raw=${directive.raw} name=${directive.name} value=$value ")
52-
// directive.el.innerHTML="This comes from my-directive "+directive.raw+" "+value
53-
// })
54-
55-
50+
Vue.directive("mydirective", literal(
51+
update=(el:HTMLElement, directive:Directive)=>{el.innerHTML="This comes from my-directive with contents "+directive.value+" and expression "+directive.expression}
52+
)
53+
)
54+
5655
val demo = new Vue(
5756
literal(el="#demo",
5857
data=literal(
58+
message="Hello Vue.js!!!!!",
5959
title="Todo App",
60-
todos=tasks.map(content=>literal(done=content==tasks.head,content=content)),
60+
todos=tasks.map(content=>literal(done=content==tasks.head,content=content)),
6161
barValue= 100,
62-
n=0
63-
),
62+
n=0
63+
),//,
6464
// js.ThisFunction would be fine, just trying to be more type specific
6565
methods=literal(clickHandler=((demoVue:DemoVue)=>demoVue.n-=1):DemoVueMethod,
6666
addTask=((demoVue:DemoVue)=>demoVue.todos.append(DemoVueTodo(false,s"new $ts"))):DemoVueMethod,
67-
change1st=((demoVue:DemoVue)=>demoVue.todos.$set(0,DemoVueTodo(false,ts))):DemoVueMethod,
68-
remove=((demoVue:DemoVue,idx:Int)=>demoVue.todos.$remove(idx)):js.ThisFunction1[DemoVue,Int,_],
69-
flipAll=((demoVue:DemoVue)=>demoVue.todos.foreach(td=>td.done= !td.done)):DemoVueMethod
67+
change1st=((demoVue:DemoVue)=>Vue.set(demoVue.todos, 0,DemoVueTodo(false,ts))):DemoVueMethod,
68+
remove=((demoVue:DemoVue,idx:Int)=>Vue.delete(demoVue.todos,idx)):js.ThisFunction1[DemoVue,Int,_],
69+
flipAll=((demoVue:DemoVue)=>demoVue.todos.foreach(td=>td.done= !td.done)):DemoVueMethod
7070
),
71-
computed=literal(todosFiltered=(demoVue:DemoVue)=> demoVue.todos.map(_.content)),
72-
73-
filters=literal(reverse=((value:js.Any)=>value.toString.reverse),
71+
computed=literal(todosComputed=(demoVue:DemoVue)=> demoVue.todos.map(_.content)),
72+
//
73+
filters=literal(reverse=((value:js.Any)=>value.toString.reverse),
7474
wrap=(value:js.Any,begin:String, end:String)=>begin+value.toString+end,
7575
extract=(array:js.Array[js.Dynamic],field:String)=>
76-
if (js.isUndefined(array)) array else array.map(_.selectDynamic(field))
77-
),
78-
events=literal(greeting= ((demoVue:DemoVue,msg:js.Any)=> println(s"Greeting $msg")):js.ThisFunction,
79-
greeting2= (msg:js.Any)=> println(s"Greeting2 $msg")
80-
),
81-
directives=literal( // directives get passed a Directive object.
82-
myDirective= ((directive:Directive,value:String)=> {
83-
println(s"myDirective expression=${directive.expression} arg=${directive.arg} raw=${directive.raw} name=${directive.name} value=$value ");
84-
directive.el.innerHTML="This comes from my-directive "+directive.raw+" "+value
85-
}):js.ThisFunction
86-
)
87-
)
76+
if (js.isUndefined(array)) array else array.map(_.selectDynamic(field))
77+
)
78+
)
8879
)
8980

90-
demo.$watch("title+' <<title'",(newValue:String, oldValue:String) => println("changed "+newValue))
91-
demo.$emit("greeting","hello")
92-
demo.$emit("greeting2","goodbye")
93-
81+
demo.$watch("title",(newValue:String, oldValue:String) => println("changed "+newValue))
82+
9483
val demoVue=demo.asInstanceOf[DemoVue]
9584

9685
// filters declared above inline, can be also done as below
@@ -99,7 +88,7 @@ object Todo extends {
9988

10089
// println(js.JSON.stringify(demo.$data))
10190

102-
demo.$log
91+
//demo.$log
10392

10493
demoVue
10594
}

0 commit comments

Comments
 (0)