Some dev notes about the VueJS integration
After some discussion at TikiFestMacau2019 we decided to add VueJS to Tiki for 21.x, and this enabled the first version of Tracker Field Rules.
Future Development
Some notes about where we may head in Tiki 24+ here: VueJS In Tiki Part 2
Next step after Hello World
Here, for the record, is my test wiki page that seems to work on that branch. It is based on this example.
Notes and Limitations
While building a Vue app in wiki plugins is an interesting experiment, and partially to aid my learning of how it all works, at some point we need to be able to support properly built VueJS projects (with npm)
The wiki plugin currently needs these changes from "normal" .vue
file based projects:
- One vue plugin needs to have
app="y"
as a parameter
- The JS module files are outputted to the temp/public dir prepended with
vue_
-
@:
shorthand doesn't work, we need to use v-on:
for now
- All
components
objects being exported need to have the component name as the object item key in lower case (i have no idea why), e.g.
Copy to clipboard
components: {
componentname: ComponentName
}
Some Ideas for the Future?
Related links
{img src=https://camo.githubusercontent.com/728ce9f78c3139e76fa69925ad7cc502e32795d2/68747470733a2f2f7675656a732e6f72672f696d616765732f6c6f676f2e706e67 width=64 alt="VueJS logo"}
''Some dev notes about the VueJS integration''
After some discussion at ((tw:TikiFestMacau2019)) we decided to add [https://vuejs.org|VueJS] to Tiki for 21.x, and this enabled the first version of ((doc:Tracker Field Rules)).
!! Future Development
Some notes about where we may head in Tiki 24+ here: ((VueJS In Tiki Part 2))
!! Next step after Hello World
Here, for the record, is my test wiki page that seems to work on that branch. It is based on [https://codesandbox.io/s/simple-todo-app-with-vue-w5zod|this example].
^{VUE(name="BaseInputText")}
<template>
<input
type="text"
class="input form-control"
:value="value"
v-on="listeners"
>
</template>
<script>
export default {
name: 'BaseInputText',
props: {
value: {
type: String,
default: '',
}
},
computed: {
listeners () {
return {
// Pass all component listeners directly to input
...this.$listeners,
// Override input listener to work with v-model
input: event => this.$emit('input', event.target.value)
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../variables.scss';
.input {
width: 100%;
padding: 8px 10px;
border: 1px solid $vue-blue;
}
</style>
{VUE}
{VUE(name="TodoListItem")}
<template>
<li>
{{ todo.text }}
<!-- tiki note, we cannot use @ shorthand for v-on (yet) -->
<button v-on:click="$emit('remove', todo.id)" class="btn btn-danger">
X
</button>
</li>
</template>
<script>
export default {
name: 'TodoListItem',
props: {
todo: {
type: Object,
required: true
}
}
}
</script>
{VUE}
{VUE(name="TodoList")}
<template>
<div>
<BaseInputText
v-model="newTodoText"
placeholder="New todo"
v-on:keydown.enter="addTodo"
/>
<ul v-if="todos.length">
<TodoListItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
v-on:remove="removeTodo"
/>
</ul>
<p v-else>
Nothing left in the list. Add a new todo in the input above.
</p>
</div>
</template>
<script>
import BaseInputText from './vue_BaseInputText.js';
import TodoListItem from './vue_TodoListItem.js';
window.BaseInputText = BaseInputText;
window.TodoListItem = TodoListItem;
let nextTodoId = 1
// tiki note: for some reason we need to use a lower case version of the component name
// as the key in the components object.
// BUT not in imports which refer to actual file names and need the same capitalisation as the files.
export default {
name: 'TodoList',
props: ['tag'],
components: {
baseinputtext: BaseInputText,
todolistitem: TodoListItem
},
data () {
return {
newTodoText: '',
todos: [
{
id: nextTodoId++,
text: 'Learn Vue'
},
{
id: nextTodoId++,
text: 'Learn about single-file components'
},
{
id: nextTodoId++,
text: 'GOTO 1'
}
]
}
},
methods: {
addTodo () {
const trimmedText = this.newTodoText.trim()
if (trimmedText) {
this.todos.push({
id: nextTodoId++,
text: trimmedText
})
this.newTodoText = ''
}
},
removeTodo (idToRemove) {
this.todos = this.todos.filter(todo => {
return todo.id !== idToRemove
})
}
}
}
</script>
{VUE}
{VUE(app="y" name="App")}<template>
<div>
<h4>My Tiki Todo App!</h4>
<TodoList>
</div>
</template>
<script>
import TodoList from './vue_TodoList.js';
window.TodoList = TodoList;
export default {
name: 'App',
components: {
todolist: TodoList
}
};
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
{VUE}^
!! Notes and Limitations
While building a Vue app in wiki plugins is an interesting experiment, and partially to aid my learning of how it all works, at some point we need to be able to support properly built VueJS projects (with npm)
The wiki plugin currently needs these changes from "normal" -+.vue+- file based projects:
* One vue plugin needs to have -+app="y"+- as a parameter
* The JS module files are outputted to the temp/public dir prepended with -+vue_+-
* -+@:+- shorthand doesn't work, we need to use -+v-on:+- for now
* All -+components+- objects being exported need to have the component name as the object item key in lower case (i have no idea why), e.g. %%% {CODE(colors="javascript")}components: {
componentname: ComponentName
}
{CODE}
!! Some Ideas for the Future?
* https://bootstrap-vue.org/docs#browser
* https://rhwilr.github.io/vue-nestable/ (replacement for jquery-ui ones on menus, modules, toolbar admin, object perms pages etc)
** or https://github.com/phphe/vue-draggable-nested-tree (not so pretty and has a "pro" version)
*check https://github.com/FranckFreiburger/vue-calendar-picker (again to replace jquery-ui date picker (and datetimepicker)
** https://krystalcampioni.github.io/vue-hotel-datepicker (good for ranges, but not sure it does single dates)
** https://chronotruck.github.io/vue-ctk-date-time-picker/ favourite so far (there are lots!)
!! Related links
* https://github.com/vuejs/awesome-vue
* (alias(VueJS))
* (alias(vue.js)) ''(this one doesn't work)''