基础知识的学习建议翻阅VUE官方文档
表单输入绑定 — Vue.jsVue.js - The Progressive JavaScript Frameworkhttps://cn.vuejs.org/v2/guide/forms.html其中,事件和表单方面比较常用
下面只介绍进阶一点的功能
基础
生命周期
1.静态路由
第一步引入"vue-router":"^3.0.1"配置
router-view相当于一个<div>标签,路由结果将显示在这个标签中
不加这个配置的话,路径能正常跳转,但页面并没有正常跳转
2.动态路由
:id与aa,bb相匹配,然后将获取的路径aa或bb通过$route.params.id传递
博客项目实战
视图层
index.vue为除了头部组件,尾部组件和部分组件的首页,通过导入最热文章,最新文章和标签等组件,构建出index.vue页面
还有data.data才是后端返回的数据,而不是data
<template>
<div v-title data-title="码神之路">
<el-container>
<el-main class="me-articles">
<article-scroll-page></article-scroll-page>
</el-main>
<el-aside>
<card-me class="me-area"></card-me>
<card-tag :tags="hotTags"></card-tag>
<card-article cardHeader="最热文章" :articles="hotArticles"></card-article>
<card-archive cardHeader="文章归档" :archives="archives"></card-archive>
<card-article cardHeader="最新文章" :articles="newArticles"></card-article>
</el-aside>
</el-container>
</div>
</template>
<script>
import CardMe from '@/components/card/CardMe'
import CardArticle from '@/components/card/CardArticle'
import CardArchive from '@/components/card/CardArchive'
import CardTag from '@/components/card/CardTag'
import ArticleScrollPage from '@/views/common/ArticleScrollPage'
import {getArticles, getHotArtices, getNewArtices} from '@/api/article'
import {getHotTags} from '@/api/tag'
import {listArchives} from '@/api/article'
export default {
name: 'Index',
created() {
this.getHotArtices()
this.getNewArtices()
this.getHotTags()
this.listArchives()
},
data() {
return {
hotTags: [],
hotArticles: [],
newArticles: [],
archives: []
}
},
methods: {
getHotArtices() {
let that = this
getHotArtices().then(data => {
that.hotArticles = data.data
}).catch(error => {
if (error !== 'error') {
that.$message({type: 'error', message: '最热文章加载失败!', showClose: true})
}
})
},
getNewArtices() {
let that = this
getNewArtices().then(data => {
that.newArticles = data.data
}).catch(error => {
if (error !== 'error') {
that.$message({type: 'error', message: '最新文章加载失败!', showClose: true})
}
})
},
getHotTags() {
let that = this
getHotTags().then(data => {
that.hotTags = data.data
}).catch(error => {
if (error !== 'error') {
that.$message({type: 'error', message: '最热标签加载失败!', showClose: true})
}
})
},
listArchives() {
listArchives().then((data => {
this.archives = data.data
})).catch(error => {
if (error !== 'error') {
that.$message({type: 'error', message: '文章归档加载失败!', showClose: true})
}
})
}
},
components: {
'card-me': CardMe,
'card-article': CardArticle,
'card-tag': CardTag,
ArticleScrollPage,
CardArchive
}
}
</script>
<style scoped>
.el-container {
width: 960px;
}
.el-aside {
margin-left: 20px;
width: 260px;
}
.el-main {
padding: 0px;
line-height: 16px;
}
.el-card {
border-radius: 0;
}
.el-card:not(:first-child) {
margin-top: 20px;
}
</style>
Home.vue展示的才是主页面
<template>
<div id="home">
<el-container>
<base-header :activeIndex="activeIndex"></base-header>
<router-view class="me-container"/>
<base-footer v-show="footerShow"></base-footer>
</el-container>
</div>
</template>
<script>
import BaseFooter from '@/components/BaseFooter'
import BaseHeader from '@/views/BaseHeader'
export default {
name: 'Home',
data (){
return {
activeIndex: '/',
footerShow:true
}
},
components:{
'base-header':BaseHeader,
'base-footer':BaseFooter
},
beforeRouteEnter (to, from, next){
next(vm => {
vm.activeIndex = to.path
})
},
beforeRouteUpdate (to, from, next) {
if(to.path == '/'){
this.footerShow = true
}else{
this.footerShow = false
}
this.activeIndex = to.path
next()
}
}
</script>
<style>
.me-container{
margin: 100px auto 140px;
}
</style>
主页面的路由存放在router下的index.js下。
展示时先展示Home页面的路由出口,把其他标签,组件作为children,等先加载完home时才加载别的路由。
另外,不同页面的路由应该用不同的path来说明。
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/Home'
/*import Index from '@/views/Index'
import Login from '@/views/Login'
import Register from '@/views/Register'
import Log from '@/views/Log'
import MessageBoard from '@/views/MessageBoard'
import BlogWrite from '@/views/blog/BlogWrite'
import BlogView from '@/views/blog/BlogView'
import BlogAllCategoryTag from '@/views/blog/BlogAllCategoryTag'
import BlogCategoryTag from '@/views/blog/BlogCategoryTag'*/
import {Message} from 'element-ui';
import store from '@/store'
import {getToken} from '@/request/token'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/write/:id?',
component: r => require.ensure([], () => r(require('@/views/blog/BlogWrite')), 'blogwrite'),
meta: {
requireLogin: true
},
},
//展示时先展示Home页面的路由出口,把其他标签,组件作为children,等先加载完home时才加载别的路由
{
path: '',
name: 'Home',
component: Home,
children: [
{
path: '/',
component: r => require.ensure([], () => r(require('@/views/Index')), 'index')
},
{
path: '/log',
component: r => require.ensure([], () => r(require('@/views/Log')), 'log')
},
{
path: '/archives/:year?/:month?',
component: r => require.ensure([], () => r(require('@/views/blog/BlogArchive')), 'archives')
},
{
path: '/messageBoard',
component: r => require.ensure([], () => r(require('@/views/MessageBoard')), 'messageboard')
},
{
path: '/view/:id',
component: r => require.ensure([], () => r(require('@/views/blog/BlogView')), 'blogview')
},
{
path: '/:type/all',
component: r => require.ensure([], () => r(require('@/views/blog/BlogAllCategoryTag')), 'blogallcategorytag')
},
{
path: '/:type/:id',
component: r => require.ensure([], () => r(require('@/views/blog/BlogCategoryTag')), 'blogcategorytag')
}
]
},
{
path: '/login',
component: r => require.ensure([], () => r(require('@/views/Login')), 'login')
},
{
path: '/register',
component: r => require.ensure([], () => r(require('@/views/Register')), 'register')
}
],
scrollBehavior(to, from, savedPosition) {
return {x: 0, y: 0}
}
})
router.beforeEach((to, from, next) => {
if (getToken()) {
if (to.path === '/login') {
next({path: '/'})
} else {
if (store.state.account.length === 0) {
store.dispatch('getUserInfo').then(data => { //获取用户信息
next()
}).catch(() => {
Message({
type: 'warning',
showClose: true,
message: '登录已过期'
})
next({path: '/'})
})
} else {
next()
}
}
} else {
if (to.matched.some(r => r.meta.requireLogin)) {
Message({
type: 'warning',
showClose: true,
message: '请先登录哦'
})
}
else {
next();
}
}
})
export default router
另外,不同的组件通过清晰的import功能引入,可以清晰地到components目录下找到相应的功能,以最热标签组件为例。
特殊的,像如果调用的方法中带有参数,例如下面的tag(t.id),
写明方法时,应这样写,才能将id传过去,实现页面跳转。
tag(id) {
this.$router.push({path: `/tag/${id}`})
}
<template>
<el-card :body-style="{ padding: '8px 18px' }">
<div slot="header" class="me-tag-header">
<span>最热标签</span>
<a @click="moreTags" class="me-pull-right me-tag-more">查看全部</a>
</div>
<ul class="me-tag-list">
<li class="me-tag-item" v-for="t in tags" :key="t.id">
<!--type="primary"-->
<el-button @click="tag(t.id)" size="mini" type="primary" round plain>{{t.tagName}}</el-button>
</li>
</ul>
</el-card>
</template>
<script>
export default {
name: 'CardTag',
props: {
tags: Array
},
data() {
return {}
},
methods: {
moreTags() {
this.$router.push('/tag/all')
},
tag(id) {
this.$router.push({path: `/tag/${id}`})
}
}
}
</script>
<style scoped>
.me-tag-header {
font-weight: 600;
}
.me-tag-more {
font-size: 14px;
color: #78b6f7;
}
.me-tag-list {
list-style-type: none;
}
.me-tag-item {
display: inline-block;
padding: 4px;
font-size: 14px;
color: #5FB878;
}
.me-tag-item a:hover {
text-decoration: underline;
}
</style>