Skip to content

Commit

Permalink
Updated code to use and be compatible with v2.2.4 of vue.js
Browse files Browse the repository at this point in the history
  • Loading branch information
fancellu committed Mar 14, 2017
1 parent 399bd7b commit da22e66
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 147 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ workbenchSettings

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

version := "0.2"
version := "2.2.4"

scalaVersion := "2.11.8"

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

bootSnippet := "example.T1().main(document.getElementById('mydiv'));"
bootSnippet := ""

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

2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")

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

addSbtPlugin("com.lihaoyi" % "workbench" % "0.2.3")
113 changes: 33 additions & 80 deletions src/main/resources/index-dev.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,56 +26,14 @@
height: 20px;
background: black;
}
.bounce-enter {
-webkit-animation: bounce-in .5s;
animation: bounce-in .5s;
}
.bounce-leave {
-webkit-animation: bounce-out .5s;
animation: bounce-out .5s;
}

@-webkit-keyframes bounce-in {
0% {
-webkit-transform: scale(0);
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
50% {
-webkit-transform: scale(1.2);
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
opacity: 0
}
100% {
-webkit-transform: scale(1);
}
}

@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}

@-webkit-keyframes bounce-out {
0% {
-webkit-transform: scale(1);
}
100% {
-webkit-transform: scale(0);
}
}

@keyframes bounce-out {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
</style>
</head>
<body>
Expand All @@ -84,46 +42,47 @@
<div id="demo">
<div style="float:left;height:400px;overflow: auto;">
Title=<input v-model="title"/>
<ol>
<li v-transition="bounce" v-repeat="todos">
<span v-on="click: done = !done" class="{{done ? 'done' : ''}}">
{{content}}
</span>
<button v-on="click:remove($index)">Remove</button>
</li>
</ol>

<transition-group name="fade" tag="ol">
<li v-for="(todo,index) in todos" :key="todo">
<span @click="todo.done = !todo.done" :class="{done: todo.done}">
{{todo.content}}
<button @click="remove(index)">Remove</button>
</span>
</li>
</transition-group>

Tasks# {{todos.length}}<BR/>
N={{n}}<BR/>
</div>
<div style="padding-left:30px;height:400px;overflow: auto;width:30%"><pre>data JSON: {{$data | json 2}}</pre></div>

<div style="clear:left">
Using a v-text directive title=<span v-text="title"></span>
<div>Smooth CSS animation:
<input type="button" value="+" v-on="click: barValue += 50"/>
<input type="button" value="-" v-on="click: barValue -= 50">
<div>Smooth CSS animation:
<input type="button" value="+" @click="barValue += 50"/>
<input type="button" value="-" @click="barValue -= 50">
</div>
<div class="bar" v-style="{ width: barValue + 'px' }"></div>
<div class="bar" :style="{ width: barValue + 'px' }"></div>
<div v-text="'Using a v-text directive with inline expression, title='+title"></div>
<div>Title reversed={{title | reverse}}</div>
<div>Title wrapper={{title | wrap '<<' '>>'}}</div>
<div v-my-directive="myarg:title">xx</div>
<my-component my-msg="hello">Special content</my-component>

<button v-on="click:clickHandler">Call clickHandler in Scala</button>
<button v-on="click:n++">Increment N</button>

<button v-on="click:addTask">Add Task</button>
<button v-on="click:change1st">Change 1st</button>
<button v-on="click:remove(0,$event)">Remove 1st</button>
<button v-on="click:flipAll">Flip All</button><BR/><BR/>
Via custom filter <select v-model="selected" options="todos | extract 'content'"></select>
Via computed property<select v-model="selected" options="todosFiltered"></select>
<div>Title wrapper={{title | wrap('<<','>>')}}</div>
<div v-mydirective="title">xx</div>
<my-component my-msg="hello">Special content</my-component>
<!---->
<button @click="clickHandler">Call clickHandler in Scala</button>
<button @click="n++">Increment N</button>
<!---->
<button @click="addTask">Add Task</button>
<button @click="change1st">Change 1st</button>
<button @click="remove(0)">Remove 1st</button>
<button @click="flipAll">Flip All</button><BR/><BR/>
Todos computed: {{ todosComputed }}
</div>
</div>


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

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

//Vue.filter('extract', function (value, keyToExtract) {
// return value.map(function (item) {
// return item[keyToExtract]
// })
// })
// we get DemoVue back from Scala, then use it
var demo=example.Todo().main();
demo.title="Todo Todo Todo"

demo.todos.push({done:false,content:"Extra task"})
//demo.todos[0]=({done:false,content:"!!!!"})
//demo.todos.$set(0, {done:false,content:"!!!!"})

</script>

</body>
Expand Down
33 changes: 14 additions & 19 deletions src/main/scala/com/felstar/scalajs/vue/Vue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ import js.annotation.JSName
def $watch(expOrFn:js.Any,callback:Callback):Unwatch=js.native
def $watch(expOrFn:js.Any,callback:Callback,options:js.Any):Unwatch=js.native
def $get(exp:String):js.Any=js.native
def $set(keypath:String,value:js.Any):Unit=js.native
def $set(target:js.Any,key:js.Any, value:js.Any):Unit=js.native
def $delete(target:js.Any,key:js.Any):Unit=js.native
def $add(key:String,value:js.Any):Unit=js.native
def $delete(key:String):Unit=js.native
def $eval(exp:String):js.Any=js.native
def $interpolate(templateString:String):js.Any=js.native
def $log(keypath:String):Unit=js.native
def $log():Unit=js.native

// Events
def $dispatch(event:String):Unit=js.native
def $dispatch(event:String,args:js.Any):Unit=js.native
Expand Down Expand Up @@ -87,26 +86,22 @@ import js.annotation.JSName
def transition(id:String):js.Any=js.native
def transition(id:String,definition:js.Any):js.Any=js.native
def partial(id:String):js.Any=js.native
def partial(id:String,template:String):js.Any=js.native
def partial(id:String,template:String):js.Any=js.native
def use(plugin:js.Any):js.Any=js.native
def use(plugin:js.Any,args:js.Any*):js.Any=js.native
def set(target:js.Any,key:js.Any, value:js.Any):Unit=js.native
def delete(target:js.Any,key:js.Any):Unit=js.native
}

@js.native
trait VueArray[T] extends js.Array[T]{
def $set(idx:Int,obj:T):Unit=js.native
def $remove(idx:Int):Unit=js.native
}

@js.native
class Directive extends js.Object {
val el:dom.raw.Element =js.native
val vm:Vue =js.native
val expression:js.Any =js.native
val arg:String =js.native
val raw:String =js.native
val name:String =js.native
val name:String =js.native
val rawName:String =js.native
val value:String =js.native
val expression:String =js.native
val modifiers:js.Any =js.native
val `def`:js.Any =js.native
}



79 changes: 34 additions & 45 deletions src/main/scala/example/Todo.scala
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
package example
import org.scalajs.dom

import scalajs.js.annotation.JSExport
import scala.scalajs.concurrent.JSExecutionContext.Implicits.runNow
import dom.ext.Ajax

import scalajs.js
import js.Dynamic.literal
import com.felstar.scalajs.vue._
import org.scalajs.dom.raw.HTMLElement

import js.annotation.JSName

@JSExport
object Todo extends {

// Strongly typed wrapper around below dynamic Vue
// You don't have to do this, can access as js.Dynamic
// But obviously type safety is a good thing, a Scala thing.
@js.native
trait DemoVue extends Vue{
var title:String=js.native
var n:Double=js.native
var todos:VueArray[DemoVueTodo]=js.native
}
var todos:js.Array[DemoVueTodo]=js.native
}

type DemoVueMethod=js.ThisFunction0[DemoVue,_]

@js.native
trait DemoVueTodo extends js.Object{
trait DemoVueTodo extends js.Object{
var done:Boolean=js.native
var content:String=js.native
}

object DemoVueTodo{
def apply(done:Boolean,content:String)=literal(done=done,content=content).asInstanceOf[DemoVueTodo]
}
Expand All @@ -38,59 +39,47 @@ object Todo extends {
// could have returned raw Vue of course
def main():DemoVue = {

val tasks=js.Array("Learn JavaScript","Learn Vue.js","Learn Scala.js")
val tasks=js.Array("Learn JavaScript","Learn Vue.js","Learn Scala.js")
//
def ts=new java.util.Date().toString

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

// Note, don't need to define as js.ThisFunction, as signature expects this
// Vue.directive("my-directive", (directive:Directive,value:js.Any)=> {
// println(s"myDirective! expression=${directive.expression} arg=${directive.arg} raw=${directive.raw} name=${directive.name} value=$value ")
// directive.el.innerHTML="This comes from my-directive "+directive.raw+" "+value
// })


Vue.directive("mydirective", literal(
update=(el:HTMLElement, directive:Directive)=>{el.innerHTML="This comes from my-directive with contents "+directive.value+" and expression "+directive.expression}
)
)

val demo = new Vue(
literal(el="#demo",
data=literal(
message="Hello Vue.js!!!!!",
title="Todo App",
todos=tasks.map(content=>literal(done=content==tasks.head,content=content)),
todos=tasks.map(content=>literal(done=content==tasks.head,content=content)),
barValue= 100,
n=0
),
n=0
),//,
// js.ThisFunction would be fine, just trying to be more type specific
methods=literal(clickHandler=((demoVue:DemoVue)=>demoVue.n-=1):DemoVueMethod,
addTask=((demoVue:DemoVue)=>demoVue.todos.append(DemoVueTodo(false,s"new $ts"))):DemoVueMethod,
change1st=((demoVue:DemoVue)=>demoVue.todos.$set(0,DemoVueTodo(false,ts))):DemoVueMethod,
remove=((demoVue:DemoVue,idx:Int)=>demoVue.todos.$remove(idx)):js.ThisFunction1[DemoVue,Int,_],
flipAll=((demoVue:DemoVue)=>demoVue.todos.foreach(td=>td.done= !td.done)):DemoVueMethod
change1st=((demoVue:DemoVue)=>Vue.set(demoVue.todos, 0,DemoVueTodo(false,ts))):DemoVueMethod,
remove=((demoVue:DemoVue,idx:Int)=>Vue.delete(demoVue.todos,idx)):js.ThisFunction1[DemoVue,Int,_],
flipAll=((demoVue:DemoVue)=>demoVue.todos.foreach(td=>td.done= !td.done)):DemoVueMethod
),
computed=literal(todosFiltered=(demoVue:DemoVue)=> demoVue.todos.map(_.content)),
filters=literal(reverse=((value:js.Any)=>value.toString.reverse),
computed=literal(todosComputed=(demoVue:DemoVue)=> demoVue.todos.map(_.content)),
//
filters=literal(reverse=((value:js.Any)=>value.toString.reverse),
wrap=(value:js.Any,begin:String, end:String)=>begin+value.toString+end,
extract=(array:js.Array[js.Dynamic],field:String)=>
if (js.isUndefined(array)) array else array.map(_.selectDynamic(field))
),
events=literal(greeting= ((demoVue:DemoVue,msg:js.Any)=> println(s"Greeting $msg")):js.ThisFunction,
greeting2= (msg:js.Any)=> println(s"Greeting2 $msg")
),
directives=literal( // directives get passed a Directive object.
myDirective= ((directive:Directive,value:String)=> {
println(s"myDirective expression=${directive.expression} arg=${directive.arg} raw=${directive.raw} name=${directive.name} value=$value ");
directive.el.innerHTML="This comes from my-directive "+directive.raw+" "+value
}):js.ThisFunction
)
)
if (js.isUndefined(array)) array else array.map(_.selectDynamic(field))
)
)
)

demo.$watch("title+' <<title'",(newValue:String, oldValue:String) => println("changed "+newValue))
demo.$emit("greeting","hello")
demo.$emit("greeting2","goodbye")

demo.$watch("title",(newValue:String, oldValue:String) => println("changed "+newValue))

val demoVue=demo.asInstanceOf[DemoVue]

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

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

demo.$log
//demo.$log

demoVue
}
Expand Down

0 comments on commit da22e66

Please sign in to comment.