adding latest tutorial
This commit is contained in:
31
links.md
Normal file
31
links.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Vue resources/references
|
||||||
|
|
||||||
|
Awesome Vue
|
||||||
|
https://github.com/ais-one/vue-crud-x
|
||||||
|
|
||||||
|
Real time data-table editing in Vue:
|
||||||
|
https://www.freecodecamp.org/news/how-to-build-a-real-time-editable-data-table-in-vue-js-46b7f0b11684/
|
||||||
|
|
||||||
|
Integrating a datetime into a datatable CRUD:
|
||||||
|
https://www.reddit.com/r/vuejs/comments/apdm4u/how_to_integrate_a_datepicker_like_this_in/
|
||||||
|
|
||||||
|
Vuetify CRUD datatables:
|
||||||
|
https://github.com/ais-one/vue-crud-x
|
||||||
|
|
||||||
|
Loading bar component for top of page:
|
||||||
|
https://medium.com/js-dojo/how-to-visualize-application-loading-state-in-vuetify-44f0f0242094
|
||||||
|
https://gist.github.com/AlexeyIsavnin/c24d7ae75bfdb599907bd36d6bfc0344
|
||||||
|
|
||||||
|
Using AJAX and rate limiting with lodash:
|
||||||
|
https://vuejs.org/v2/guide/computed.html#Watchers
|
||||||
|
|
||||||
|
Composition API in Vue3:
|
||||||
|
https://css-tricks.com/an-early-look-at-the-vue-3-composition-api-in-the-wild/?ref=madewithvuejs.com
|
||||||
|
|
||||||
|
Libraries that work with Vue:
|
||||||
|
|
||||||
|
JS library to simplify working with arrays, numbers, objects, strings, etc.
|
||||||
|
|
||||||
|
- Iterating arrays, objects, & strings
|
||||||
|
- Manipulating & testing values
|
||||||
|
- Creating composite functions
|
||||||
173
notes.md
Normal file
173
notes.md
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
To Do:
|
||||||
|
|
||||||
|
Organise Trilium with the Vue development
|
||||||
|
|
||||||
|
- Have a note for tutorials
|
||||||
|
- Have a note for references (grouped by category)
|
||||||
|
|
||||||
|
Once done with this, go through this and the auth0 tutorial and pick out any vue/javascript snippets into their own trilium note.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
|
||||||
|
Vuetify
|
||||||
|
|
||||||
|
Forms
|
||||||
|
https://vuetifyjs.com/en/components/forms
|
||||||
|
|
||||||
|
To make a form you define a `v-model` of valid in the `<v-form>`. `lazy-validation` will set this to true unless there are visible validation errors.
|
||||||
|
|
||||||
|
`<v-form v-model="valid" ref="form" lazy-validation="">`
|
||||||
|
|
||||||
|
The `v-form` component has three functions that can be access by setting a `ref` on the component.
|
||||||
|
|
||||||
|
- this.\$refs.form.validate()
|
||||||
|
- this.\$refs.form.reset()
|
||||||
|
- this.\$refs.form.resetValidation()
|
||||||
|
|
||||||
|
Validation is easy: https://vuetifyjs.com/en/components/forms/#usage
|
||||||
|
|
||||||
|
Custom rules can be done: https://vuetifyjs.com/en/components/forms/#creating-rules
|
||||||
|
|
||||||
|
When the `submit()` event is made, `this.$refs.form.validate()` will check the form.
|
||||||
|
|
||||||
|
`v-model` is used to bind data 2 ways to the form and the data instance in vue.
|
||||||
|
|
||||||
|
https://vuejs.org/v2/guide/forms.html
|
||||||
|
|
||||||
|
`v-text-fields` are used to render inputs in a form.
|
||||||
|
|
||||||
|
https://vuetifyjs.com/en/components/text-fields/
|
||||||
|
|
||||||
|
Using `:` before a prop means that the prop is dynamic and the value of it contains javascript.
|
||||||
|
|
||||||
|
`:append-icon="passwordVisible ? 'visibility' : 'visibility_off'"`
|
||||||
|
|
||||||
|
Here this is saying that `append-icon` takes a dynamic value. We are using the `? :` syntax - conditional ternary operator. This is short for a if then else.
|
||||||
|
|
||||||
|
Available icons are (with `mdi-` prefix) https://materialdesignicons.com/ or https://material.io/resources/icons/?style=baseline
|
||||||
|
|
||||||
|
Double bang notation
|
||||||
|
|
||||||
|
The notation `!!variable` is double bang notation
|
||||||
|
https://medium.com/better-programming/javascript-bang-bang-i-shot-you-down-use-of-double-bangs-in-javascript-7c9d94446054
|
||||||
|
|
||||||
|
It returns the `variable` _truthy_ value. I.e if it's a string with a value it will be true. This is similar to doing `variable.__bool__` in python.
|
||||||
|
|
||||||
|
When writing inputs you can create custom rules.
|
||||||
|
|
||||||
|
For example: (in the `computed`)
|
||||||
|
|
||||||
|
```
|
||||||
|
passwordRules() {
|
||||||
|
return {
|
||||||
|
required: value => !!value || 'Required.',
|
||||||
|
min: v => v.length >= 8 || 'Min 8 characters',
|
||||||
|
emailMatch: () => ('The email and password you entered don\'t match'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
For a `<v-text-field`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<v-text-field
|
||||||
|
v-model="password"
|
||||||
|
:append-icon="passwordVisible ? 'visibility' : 'visibility_off'"
|
||||||
|
:rules="[passwordRules.required, passwordRules.min]"
|
||||||
|
>
|
||||||
|
</v-text-field>
|
||||||
|
```
|
||||||
|
|
||||||
|
The value of the field will be passed to the method `passwordRules()` and passed into the function inside it. This way, we can verify that the value exists (using double bang notation) and that it has a minimum length.
|
||||||
|
|
||||||
|
Events on the input can be defined using the following syntax:
|
||||||
|
`@click:append="passwordVisible = !passwordVisible"`
|
||||||
|
This event (each event is documented in the Vuetify docs) will trigger when you click on the append icon you defined.
|
||||||
|
|
||||||
|
You can write regex in javascript by placing it between two slash's.
|
||||||
|
They are useful with arrow notation to check if something matches a regex.
|
||||||
|
`v => /.+@.+/.test(v) || 'E-mail must be valid.'`
|
||||||
|
|
||||||
|
Backtick strings is javascript's version of f-strings in python. You can then access variables with `${}` notation:
|
||||||
|
|
||||||
|
```
|
||||||
|
console.log(
|
||||||
|
`SIGN UP username: ${this.username}, password: ${this.password}, email: ${this.username}`
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can write an if block like you would a function:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (this.$refs.form.validate()) {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also follow this with an else (aligned with the end of the if block)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (condition) {
|
||||||
|
// block of code to be executed if the condition is true
|
||||||
|
} else {
|
||||||
|
// block of code to be executed if the condition is false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use the conditional ternary notation of
|
||||||
|
`condition ? true_action : false_action`
|
||||||
|
|
||||||
|
Computed (properties and watchers)
|
||||||
|
https://stackoverflow.com/a/44350932
|
||||||
|
|
||||||
|
With computed you are creating getters/setters. You do this by writing the function in the `computed` directive.
|
||||||
|
Here we have written a computed property for `emailRules()` - we are using this function to check input on a form is correct.
|
||||||
|
|
||||||
|
The main difference between `computed` and a `method` is that `computed` will cache automatically. It will only update, if the value updates. Everytime you call it it will use its cache. Expensive operations can be done this way.
|
||||||
|
|
||||||
|
Remember: anything in `data` you can access in the `<script>` with `$this.var`. In the html you can access the var name directly `{{var}}`
|
||||||
|
|
||||||
|
Watchers
|
||||||
|
https://vuejs.org/v2/guide/computed.html#Watchers
|
||||||
|
|
||||||
|
The watch directive can be used to watc variables in the component. You create a function that is the same name as the variable you want to watch. This function should take two arguments: new and old. (You can use this to compare inputs for exmaple).
|
||||||
|
|
||||||
|
There is a good example of using this functionality to do an ajax call (with rate limiting) in the documentation for watches above.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Sending form data to an api
|
||||||
|
|
||||||
|
You can check the form is in a valid state by doing `this.$refs.form.validate()`
|
||||||
|
|
||||||
|
You can then access each component of the form to the variable you defined in the `v-model` attribute.
|
||||||
|
|
||||||
|
`<v-text-field v-model="username" />` can be accessed with `this.username`.
|
||||||
|
|
||||||
|
Remember that the variable defined in the `v-model` has to be defined in the `data`.
|
||||||
|
|
||||||
|
|
||||||
|
Usage of `$this`
|
||||||
|
|
||||||
|
The following (under the "No separate this" header) explains well.
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
|
||||||
|
|
||||||
|
When you write a function and define a variable, you might want to write another function inside. If you use `$this` inside the second function, you will find it is bound to the global scope, not the parent function!
|
||||||
|
|
||||||
|
To fix this behaviour, you should _close over_ the variable `$this`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function Person() {
|
||||||
|
var that = this;
|
||||||
|
that.age = 0;
|
||||||
|
|
||||||
|
setInterval(function growUp() {
|
||||||
|
// The callback refers to the `that` variable of which
|
||||||
|
// the value is the expected object.
|
||||||
|
that.age++;
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is similar to "closure" in python.
|
||||||
|
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
<div></div>
|
||||||
<v-btn
|
<v-btn
|
||||||
href="https://github.com/vuetifyjs/vuetify/releases/latest"
|
href="https://github.com/vuetifyjs/vuetify/releases/latest"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
0
src/tmp/test.html
Normal file
0
src/tmp/test.html
Normal file
@@ -1,16 +1,59 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sign-up"></div>
|
<div class="sign-up">
|
||||||
|
<h1>Sign Up</h1>
|
||||||
|
<v-form v-model="valid" ref="form" lazy-validation="">
|
||||||
|
<v-text-field
|
||||||
|
v-model="username"
|
||||||
|
:rules="emailRules"
|
||||||
|
label="Email Address"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
</v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="password"
|
||||||
|
:append-icon="passwordVisible ? 'visibility' : 'visibility_off'"
|
||||||
|
:rules="[passwordRules.required, passwordRules.min]"
|
||||||
|
:type="passwordVisible ? 'text' : 'password'"
|
||||||
|
name="password"
|
||||||
|
label="Password"
|
||||||
|
hint="At least 8 characters"
|
||||||
|
counter
|
||||||
|
@click:append="passwordVisible = !passwordVisible"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
</v-text-field>
|
||||||
|
<v-btn :disabled="!valid" @click="submit"></v-btn>
|
||||||
|
</v-form>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
name: "SignUp",
|
||||||
name: 'SignUp',
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
valid: false,
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
passwordVisible: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
emailRules() {
|
||||||
|
return [
|
||||||
|
v => !!v || "Email is required",
|
||||||
|
v => /.+@.+/.test(v) || "E-mail must be valid."
|
||||||
|
];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
if (this.$refs.form.validate()) {
|
||||||
|
console.log(
|
||||||
|
`SIGN UP username: ${this.username}, password: ${this.password}, email: ${this.username}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
60
src/views/SignUpConfirm.vue
Normal file
60
src/views/SignUpConfirm.vue
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<div class="confirm">
|
||||||
|
<h1>Confirm</h1>
|
||||||
|
<v-form v-model="valid" ref="form" lazy-validation>
|
||||||
|
<v-text-field
|
||||||
|
v-model="username"
|
||||||
|
:rules="emailRules"
|
||||||
|
label="Email Address"
|
||||||
|
required
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="code"
|
||||||
|
:rules="codeRules"
|
||||||
|
label="Code"
|
||||||
|
required
|
||||||
|
></v-text-field>
|
||||||
|
<v-btn :disabled="!valid" @click="submit">Submit </v-btn>
|
||||||
|
</v-form>
|
||||||
|
<v-btn @click="resend">Resend Code</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SignUpConfirm",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
valid: false,
|
||||||
|
username: "",
|
||||||
|
code: ""
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
emailRules() {
|
||||||
|
return [
|
||||||
|
v => !!v || "Email is required",
|
||||||
|
v => /.+@.+/.test(v) || "Email must be valid"
|
||||||
|
];
|
||||||
|
},
|
||||||
|
codeRules() {
|
||||||
|
return [
|
||||||
|
v => !!v || "Code is required",
|
||||||
|
v => (v && v.length === 6) || "Code must be 6 digits"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
if (this.$refs.form.validate()) {
|
||||||
|
console.log(`CONFIRM username: ${this.username}, code: ${this.code}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resend() {
|
||||||
|
console.log(`RESEND username: ${this.username}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
Reference in New Issue
Block a user