Skip to content

Feat(): Layout #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ module.exports = {
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"@typescript-eslint/ban-types": "off",
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid this:
image

},
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service serve",
"dev": "cross-env PORT=8000 vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
Expand All @@ -28,6 +28,7 @@
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-typescript": "^9.1.0",
"babel-plugin-component": "^1.1.1",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
Expand Down
46 changes: 35 additions & 11 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<Container id="app" direction="vertical">
<Header :height="'auto'">
<!-- <nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav> -->
<NavMenu />
</Header>
<!-- <Main> -->
<router-view />
</div>
<!-- </Main> -->
</Container>
</template>

<style lang="scss">
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import { Container, Header, Main } from "element-ui";
const NavMenu = () =>
import(
/* webpackChunkName: 'NavMenu' */ /* webpackPrefetch: true */ "./components/NavMenu.vue"
);

@Component({
components: {
Container,
Header,
Main,
NavMenu,
},
})
export default class App extends Vue {}
</script>

<style lang="scss" scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
// -webkit-font-smoothing: antialiased;
// -moz-osx-font-smoothing: grayscale;
// text-align: center;
// color: #2c3e50;
}

nav {
Expand Down
61 changes: 61 additions & 0 deletions src/components/NavMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<div>
<Menu
style="display: inline-flex; float: left"
data-qa-id="nav-menu"
:mode="'horizontal'"
:router="true"
:default-active="currentRoute"
>
<MenuItem
v-for="route in $router.options.routes"
:key="route.path"
:route="route"
:index="route.path"
>
{{ route.path }}
</MenuItem>
</Menu>
<Button
style="text-color: white; float: right"
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create classes for this

plain
type="primary"
icon="el-icon-switch-button"
@click="openLoginDialog = true"
>Login</Button
>
<div v-if="openLoginDialog">
<Login
:open="openLoginDialog"
@close="(val) => (openLoginDialog = val)"
/>
</div>
</div>
</template>

<script lang="ts">
import { Vue, Component, Watch } from "vue-property-decorator";
import { Menu, MenuItem, Button } from "element-ui";
import Login from "@/views/Login.vue";

@Component({
components: {
Menu,
MenuItem,
Button,
Login,
},
})
export default class NavMenu extends Vue {
currentRoute = "/";
openLoginDialog = false;

@Watch("$route.path")
onRoutePathChange(newValue: string) {
// triggered only once at startup since router is not reactive.
this.currentRoute = newValue;
}
}
</script>

<style lang="scss" scoped></style>
18 changes: 1 addition & 17 deletions src/views/Home.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,19 @@
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App" />
<Button @click="openDialog" type="primary" icon="el-icon-switch-button"
>Login</Button
>
<Login
v-if="openLoginDialog"
:open="openLoginDialog"
@close="(val) => (openLoginDialog = val)"
/>
</div>
<div class="home">Homepage</div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { Button } from "element-ui";

// Components
const HelloWorld = () =>
import(
/* webpackChunkName: "HelloWorld" */ /* webpackPrefetch: true */ "../components/HelloWorld.vue"
);
const Login = () =>
import(
/* webpackChunkName: "Login" */ /* webpackPrefetch: true */ "./Login.vue"
);

@Component({
components: {
HelloWorld,
Login,
Button,
},
Expand Down
110 changes: 72 additions & 38 deletions src/views/Login.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
<template>
<Dialog :visible="open" :title="'Login'" @close="close">
<Dialog
:width="'400px'"
:visible="open"
:title="'Login'"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="close"
>
<Form
ref="loginForm"
:statusIcon="true"
inline
:label-width="'auto'"
:model="loginModel"
:rules="formValidator"
size="small"
@validate="onValidate"
>
<FormItem :label="'Username'" required prop="username">
<Input v-model="loginModel.username" />
<Input class="form_input" v-model="loginModel.username" />
</FormItem>
<FormItem :label="'Password'" required prop="password">
<Input :show-password="true" v-model="loginModel.password" />
</FormItem>
<FormItem>
<Button type="primary" :disabled="!canSubmit" @click="submitLogin"
>Login</Button
>
<Input
class="form_input"
:show-password="true"
v-model="loginModel.password"
/>
</FormItem>
</Form>
<template #footer>
<Button type="primary" :disabled="!canSubmit" @click="submitLogin">
Login
</Button>
<Button type="secondary" :disabled="!canSubmit" @click="submitLogin">
Sign Up
</Button>
</template>
</Dialog>
</template>

Expand All @@ -38,17 +54,19 @@ import { Dialog, Input, Form, FormItem, Button } from "element-ui";
export default class Login extends Vue {
@Prop() open!: boolean;

loginModel = {
username: "",
password: "",
};

// https://github.com/yiminghe/async-validator
// validatePass = (rule, value, callback: Function) => {
// if (value === '') {
// callback(new Error('Please input the password'));
// } else {
// if (this.ruleForm.checkPass !== '') {
// this.$refs.ruleForm.validateField('checkPass');
// }
// callback();
// }
// };
validatePass = (rule: object, password: string, callback: Function) => {
console.log(rule);
if (/\s/.test(password)) {
callback(new Error("No spaces please!"));
}
callback();
};

formValidator = {
username: [
Expand All @@ -66,32 +84,34 @@ export default class Login extends Vue {
{
type: "string",
whitespace: true,
message: "Hmm, ever had a username with spaces?!",
message: "Hmm, ever had a username with just spaces?!",
},
],
password: [
{
required: true,
type: "string",
message: "We wont tell anyone, just need to authenticate it's you!",
},
{
type: "string",
message: "No spaces please!",
validator: this.validatePass,
},
],
password: {
required: true,
type: "string",
message: "We wont tell anyone, just need to authenticate it's you!",
},
};

loginModel = {
username: "",
password: "",
formValidity: { [key: string]: boolean } = {
username: false,
password: false,
};

username = "";
password = "";

openDialog = false;

mounted() {
this.openDialog = this.open;
}

get canSubmit(): boolean {
return !!this.loginModel.username && !!this.loginModel.password;
return (
!!this.loginModel.username &&
!!this.loginModel.password &&
this.isFormValid
);
}

submitLogin() {
Expand All @@ -100,9 +120,23 @@ export default class Login extends Vue {
this.loginModel.password = "";
}

get isFormValid(): boolean {
return this.formValidity.username && this.formValidity.password;
}

onValidate(result: string, isValid: boolean) {
this.formValidity[result] = isValid;
}

@Emit()
close() {
return false;
}
}
</script>

<style lang="scss" scoped>
.form_input {
width: 100%;
}
</style>
3 changes: 3 additions & 0 deletions vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
configureWebpack: {
devtool: "source-map",
},
});
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2539,6 +2539,13 @@ cosmiconfig@^7.0.0:
path-type "^4.0.0"
yaml "^1.10.0"

cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
dependencies:
cross-spawn "^7.0.1"

cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
Expand All @@ -2559,7 +2566,7 @@ cross-spawn@^6.0.0:
shebang-command "^1.2.0"
which "^1.2.9"

cross-spawn@^7.0.2, cross-spawn@^7.0.3:
cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
Expand Down