vue项目开发

master
DueClassic 5 years ago
commit 62d543ae56

@ -0,0 +1,2 @@
> 1%
last 2 versions

@ -0,0 +1,5 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

@ -0,0 +1,17 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/essential',
'@vue/standard'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}

21
.gitignore vendored

@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,24 @@
# single_page_app
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

12319
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,36 @@
{
"name": "single_page_app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.4",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-eslint": "^4.2.0",
"@vue/cli-plugin-router": "^4.2.0",
"@vue/cli-plugin-vuex": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"@vue/eslint-config-standard": "^5.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.1.2",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11",
"stylus": "^0.54.7",
"stylus-loader": "^3.0.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

@ -0,0 +1,12 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<style lang="scss">
* {
padding: 0;
margin: 0;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -0,0 +1,12 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router/router'
import store from './store/store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

@ -0,0 +1,45 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../views/Login.vue'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Login',
component: Login
},
{
path: '/home',
name: 'home',
component: Home,
children: [
{
path: 'list',
name: 'list',
component: () => import(/* webpackChunkName: "list" */ '../views/List.vue')
},
{
path: 'user',
name: 'user',
component: () => import(/* webpackChunkName: "user" */ '../views/User.vue')
}
]
},
{
path: '/add',
name: 'add',
component: () => import(/* webpackChunkName: "add" */ '../views/Add.vue')
}
]
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
linkActiveClass: 'active',
routes
})
export default router

@ -0,0 +1,37 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
lists: [],
users: []
},
mutations: {
addItem (state, value) {
state.lists.push(value)
},
addUser (state, value) {
state.users.push(value)
},
delItem (state, index) {
state.lists.splice(index, 1)
},
getLocal (state) {
if (localStorage.getItem('pageLists')) {
state.lists = JSON.parse(localStorage.getItem('pageLists'))
}
},
getLocalUsers (state) {
if (localStorage.getItem('users')) {
state.users = JSON.parse(localStorage.getItem('users'))
}
}
},
getters: {
myLists: state => {
return state.lists.filter(item => item.user === sessionStorage.getItem('currentUser'))
}
}
})

@ -0,0 +1,88 @@
<template>
<div>
<div class="main">
<p>标题</p>
<input class="title" type="text" v-model="title"/>
<p>内容</p>
<textarea class="content" v-model="content"/>
</div>
<div class="button">
<button @click="add()"></button>
<button @click="cancel()"></button>
</div>
</div>
</template>
<script>
import store from '../store/store'
export default {
name: 'Add',
store,
data () {
return {
title: '',
content: ''
}
},
methods: {
add () {
var newTime = new Date()
var year = newTime.getFullYear()
var month = ('0' + (newTime.getMonth() + 1)).slice(-2)
var day = ('0' + newTime.getDate()).slice(-2)
var hours = ('0' + newTime.getHours()).slice(-2)
var minutes = ('0' + newTime.getMinutes()).slice(-2)
var addTime = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes
store.commit('addItem', {
title: this.title,
content: this.content,
time: addTime,
user: sessionStorage.getItem('currentUser')
})
localStorage.pageLists = JSON.stringify(store.state.lists)
this.title = ''
this.content = ''
this.$router.push('/home/list')
},
cancel () {
this.$router.push('/home/user')
}
}
}
</script>
<style lang="stylus" scoped>
.main
margin 10px
p
margin-bottom 5px
input, textarea
border 1px solid #d5d5d5
border-radius 7px
width 100%
box-sizing border-box
font-size 15px
.title
padding 0 10px
height 30px
line-height 30px
.content
height 400px
line-height 25px
padding 10px 10px
.button
display flex
margin 45px 20px
button
flex 1
margin 5px
height 35px
line-height 35px
border-radius 7px
border 1px solid #42b983
cursor pointer
button:nth-child(1)
background #42b983
color #fff
button:nth-child(2)
color #42b983
</style>

@ -0,0 +1,47 @@
<template>
<div>
<ul class="footer">
<li class="icons"><router-link :to="{name:'list'}">新闻列表</router-link></li>
<li class="icons"><router-link :to="{name:'user'}">个人中心</router-link></li>
</ul>
<router-view />
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
<style scoped lang="scss">
li{
list-style: none;
}
.footer{
position: fixed;
width: 100%;
height: 60px;
line-height: 60px;
left: 0;
bottom: 0;
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
}
.icons{
font-size: 16px;
flex: 1;
text-align: center;
border-top: 1px solid #42b983;
a{
text-decoration: none;
color: #42b983;
display: block;
&.active{
color: #fff;
background: #42b983;
}
}
}
</style>

@ -0,0 +1,159 @@
<template>
<div>
<div class="header" v-if="isNone"></div>
<div class="item-container" v-if="!isDetail">
<div class="item"
v-for="(item,index) in pageLists"
:key="index"
@click="toggleItem(index)"
:class="{'active':index===activeIndex}">
<span class="delete" v-show="index==activeIndex" @click.stop="delItem(index)">&times;</span>
<p class="title">{{item.title}}</p>
<p class="content">{{item.content}}</p>
<div class="footer">
<div>{{item.time}}</div>
<a v-if="index===activeIndex" @click.stop="goDetail(index)">>></a>
</div>
</div>
</div>
<div class="detail" v-else>
<p class="title">{{detailTitle}}</p>
<p class="content">{{detailContent}}</p>
<button @click="backList()"></button>
</div>
</div>
</template>
<script>
import store from '../store/store'
export default {
name: 'List',
store,
data () {
return {
activeIndex: -1,
isDetail: false,
detailTitle: '',
detailContent: ''
}
},
mounted () {
store.commit('getLocal')
},
computed: {
pageLists () {
return store.getters.myLists
},
isNone () {
if (this.pageLists.length === 0) {
return true
} else {
return false
}
}
},
methods: {
toggleItem (index) {
if (this.activeIndex === index) {
this.activeIndex = -1
} else {
this.activeIndex = index
}
},
delItem (index) {
store.commit('delItem', index)
localStorage.pageLists = JSON.stringify(store.state.lists)
},
goDetail (index) {
this.isDetail = true
this.detailTitle = this.pageLists[index].title
this.detailContent = this.pageLists[index].content
},
backList () {
this.isDetail = false
}
}
}
</script>
<style lang="stylus" scoped>
.header
text-align center
margin 5px
font-size 14px
.item-container
position absolute
top 0
bottom 60px
overflow auto
width 100%
.item
position relative
border 1px solid #d5d5d5
border-radius 7px
margin 10px
font-size 14px
box-shadow 2px 3px 3px #d5d5d5
.title
height 25px
line-height 30px
padding 5px
font-weight bold
border-bottom 1px solid #d5d5d5
.content
height 25px
line-height 25px
padding 5px
overflow: hidden; //
text-overflow: ellipsis; //
white-space: nowrap; //
.footer
height 20px
display flex
justify-content space-between
font-size 12px
margin 5px
a
text-decoration none
cursor pointer
&.active
color #fff
background #42b983
.delete
position absolute
top 5px
left 94%
font-size 20px
cursor pointer
&:hover
color red
font-weight bold
font-size 22px
.detail
position absolute
top 0
bottom 60px
overflow auto
width 100%
.title
padding 10px
font-weight bold
border-bottom 1px solid #d5d5d5
.content
font-size 14px
padding 15px
letter-spacing 2px
word-wrap break-word
button
width 90%
margin-left 5%
margin-top 30px
margin-bottom 20px
height 35px
line-height 35px
border-radius 7px
border 1px solid #42b983
background-color #42b983
color #fff
cursor pointer
</style>

@ -0,0 +1,148 @@
<template>
<div>
<!-- 登录表单 -->
<form v-if="!isReg">
<div class="header">欢迎登录</div>
<div class="form">
<label>用户名</label>
<input type="text" v-model="name">
</div>
<div class="form">
<label>密码</label>
<input type="password" v-model="password">
</div>
<div class="button">
<button class="first" @click="login()"></button>
<button class="second" @click="reg()"></button>
</div>
</form>
<!-- 注册表单 -->
<form v-else>
<div class="header">请输入以下信息</div>
<div class="form">
<label>用户名</label>
<input type="text" v-model="name">
</div>
<div class="form">
<label>密码</label>
<input type="password" v-model="password">
</div>
<div class="form">
<label>确认密码</label>
<input type="password" v-model="repeat">
</div>
<div class="button">
<button class="first" @click="addUser()"></button>
<button class="second" @click="cancel()"></button>
</div>
</form>
</div>
</template>
<script>
import store from '../store/store'
export default {
name: 'Login',
data () {
return {
isReg: false,
name: '',
password: '',
repeat: ''
}
},
mounted () {
store.commit('getLocalUsers')
},
computed: {
users () {
return store.state.users
},
checkUser () {
return this.users.find(user => user.name === this.name && user.password === this.password)
}
},
methods: {
login () {
if (this.name === '' || this.password === '') {
alert('请输入用户名和密码')
} else if (this.checkUser) {
sessionStorage.setItem('currentUser', this.checkUser.name)
this.name = ''
this.password = ''
this.$router.push('/home/user')
} else {
alert('用户名密码错误')
}
},
reg () {
this.name = ''
this.password = ''
this.isReg = true
},
cancel () {
this.isReg = false
},
addUser () {
if (this.name === '' || this.password === '' || this.repeat === '') {
alert('请输入用户名和密码')
} else if (this.checkUser) {
alert('用户已存在')
} else if (this.password !== this.repeat) {
alert('两次输入密码不一致')
} else {
store.commit('addUser', {
name: this.name,
password: this.password
})
localStorage.setItem('users', JSON.stringify(store.state.users))
this.name = ''
this.password = ''
this.repeat = ''
this.isReg = false
alert('注册成功')
}
}
}
}
</script>
<style lang="stylus" scoped>
.header
margin 25px
margin-left 45px
font-weight bold
.form
display flex
justify-content flex-end
margin 10px
margin-right 15px
label
height 30px
line-height 30px
margin-right 10px
input
width 75%
height 30px
line-height 30px
border-radius 7px
border 1px solid #d5d5d5
padding 0 10px
box-sizing border-box
.button
display flex
margin 30px 20px
button
flex 1
margin 5px
height 35px
line-height 35px
border-radius 7px
border 1px solid #42b983
cursor pointer
&.first
background #42b983
color #fff
&.second
color 42b983
</style>

@ -0,0 +1,47 @@
<template>
<div>
<div class="img">
<img src="../assets/logo.png">
</div>
<div class="user">{{userName}}</div>
<div class="welcome">欢迎来到个人中心</div>
<div class="add">
<router-link :to="{ name: 'add'}">添加</router-link>
</div>
</div>
</template>
<script>
export default {
name: 'User',
data () {
return {
userName: sessionStorage.getItem('currentUser')
}
}
}
</script>
<style lang="stylus">
.img
text-align center
.user
font-weight bold
.user, .welcome
text-align center
margin 5px
.add
text-align center
margin 20px
margin-top 40px
height 35px
line-height 35px
background-color #42b983
border 1px solid #42b983
border-radius 7px
a
text-decoration none
color #fff
display block
</style>>
Loading…
Cancel
Save