Vue简易博客总结
项目结构:

首先,编写博客的导航栏组件BlogHeader.vue:
<template>
<nav>
<ul>
<li>
<router-link to="/" exact>博客</router-link>
<router-link to="/add" exact>写博客</router-link>
</li>
</ul>
</nav> </template> <script>
export default{
name:"blog-header"
} </script> <style scoped>
ul{
list-style-type: none;
text-align: center;
margin: 0px;
} li{
display: inline-block;
margin: 0 10px;
} a{
color: #fff;
text-decoration: none;
padding: 12px;
border-radius: 5px;
} nav{
background: crimson;
padding: 30px 0;
margin:10px;
} .router-link-active{
background: rgba(255,255,255,0.8);
color: #444;
} </style>
如图所示:

然后,编写展示博客的组件showBlog.vue:
用到的知识点有axios访问api:更多axios知识点请访问:https://www.npmjs.com/package/axios
new Vue({
el: '#app',
data () {
return {
info: null
}
},
created () {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response))
}
})
<div id="app">
{{ info }}
</div>
错误处理:
<!--
很多时候我们可能并没有从 API 获取想要的数据。这可能是由于很多种因素引起的,比如 axios 调用可能由于多种原因而失败,包括但不限于:
API 不工作了;
请求发错了;
API 没有按我们预期的格式返回信息。
-->
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = response.data.bpi))
.catch(error => console.log(error))
自定义指令,详见:https://cn.vuejs.org/v2/guide/custom-directive.html
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
}) //如果想注册局部指令,组件中也接受一个 directives 的选项:
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
} //然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:
<input v-focus>
过滤器:https://cn.vuejs.org/v2/guide/filters.html
showBlog.vue代码:
<template>
<div id="show-blog" v-theme:column="'narrow'">
<h1 style="text-align: center;padding: 15px 0px 0px 0px">博客总览</h1>
<input type="text" v-model="serach" placeholder="搜索" />
<div v-for="blog in blogs" class="single-blog">
<!-- | pipe管道过滤器的标识 -->
<router-link v-bind:to="'/blog/' + blog.id"><h2 v-rainbow>{{blog.name}} </h2></router-link>
<article>
<!-- {{blog.price | snippet}} -->
{{blog.detail | snippet}}
</article>
</div>
</div>
</template> <script>
export default {
name: 'show-blog',
data(){
return{
blogs:[ ],
serach:''
}
},
created(){
/*this.$http.get('http://jsonplaceholder.typicode.com/posts').then(function(data){
this.blogs = data.body.slice(0,30);
})*/
this.$axios.get('/api/items').then((data)=>{
// console.log(data.body);
this.blogs = data.data; })
},
/* computed:{
filteredBlogs:function(){
return this.blogs.filter((blog)=>{
return blog.title.match(this.serach);
})
}*/
// },
//过滤器局部实现方法
filters:{
"to-uppercase":function(data){
return data.toUpperCase();
}
},
//自定义指令的局部实现方式
directive:{ }
}
</script> <style> #show-blog{
max-width: 800px;
margin:0 auto;
} .single-blog{
padding: 20px;
margin: 20px auto;
box-sizing: border-box;
background: #ccc;
border:1px dotted #aaa;
} #show-blog a{
color: #444;
text-decoration: none;
} input[type="text"]{
padding: 8px;
width:100%;
box-shadow: border-box;
}
</style>
界面如图所示:

博客详情页代码:
<template>
<div id="single-blog">
<h1>{{blog.title}}</h1>
<article>{{blog.body}}</article>
</div>
</template> <script>
export default{
name:"singleblog",
data(){
return{
id:this.$route.params.id,
blog:{}
}
},
created(){
this.$http.get('http://jsonplaceholder.typicode.com/posts/'+this.id).then(function(data){
this.blog = data.body;
})
}
} </script> <style>
#single-blog{
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #eee;
border:1px dotted #aaa;
}
</style>

最后编写添加博客页代码:
<template>
<div id="add-blog" >
<h2>添加博客</h2>
<form action="" v-if="!submmited">
<label>博客标题</label>
<input type="text" v-model="blog.title" required="" />
<label for="">博客内容</label>
<textarea name="" id="" cols="30" rows="10" v-model="blog.content"></textarea>
<div id="checkboxes">
<label for="">Vue.js</label>
<input type="checkbox" value="Vue.js" v-model="blog.categories" />
<label for="">Node.js</label>
<input type="checkbox" value="Node.js" v-model="blog.categories"/>
<label for="">React.js</label>
<input type="checkbox" value="React.js" v-model="blog.categories"/>
<label for="">Angular</label>
<input type="checkbox" value="Angular" v-model="blog.categories"/>
<label for="">作者:</label>
<select v-model="blog.author">
<option v-for="author in authors">
{{author}}
</option>
</select>
<button v-on:click.prevent="post">添加博客</button>
</div>
</form> <div>
<h3 v-if="submmited">您的博客发布成功!</h3>
</div>
<hr>
<div id="preview">
<h3>博客总览</h3>
<p>博客标题:{{blog.title}}</p>
<p>博客内容:{{blog.content}}</p>
<p>博客分类:</p>
<ul>
<li v-for="category in blog.categories">
{{category}}
</li>
</ul>
<p>作者:{{blog.author}}</p>
</div>
</div>
</template> <script>
import axios from 'axios'
export default {
name: 'addBlog',
data () {
return {
blog:{
title:"",
content:"",
categories:[],
author:""
},
authors:["lianmin","wnagdalu","zhoujielun"],
submmited:false
}
},
methods:{
post:function(){
/*this.$http.post("http://jsonplaceholder.typicode.com/posts",{
title:this.blog.title,
body:this.blog.content,
userId:1
}).then(function(data){
console.log(data.body);
this.submmited=true;
});*/
var _this = this;
axios.post("http://jsonplaceholder.typicode.com/posts",{
title:this.blog.title,
body:this.blog.content,
userId:1
}).then((data)=>{
console.log(data.body);
_this.submmited=true;
});
}
}
}
</script> <!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#add-blog *{
box-sizing:border-box ;
}
#add-blog{
margin: 20px auto;
max-width: 600px;
padding: 20px;
} label{
display: block;
margin:20px 0 10px;
} input[type="text"],textarea,select{
display: block;
width: 100%;
padding: 8px;
} textarea{
height: 200px;
} #checkboxes label{
display: inline-block;
margin-top: 0;
} #checkboxes input{
display: inline-block;
margin-right: 10px;
} button{
display: block;
margin:20px 0;
background: crimson;
color: #fff;
border: 0;
padding: 14px;
border-radius: 4px;
font-size: 18px;
cursor: pointer;
} #preview{
padding: 10px 20px;
border:1px dotted #ccc;
margin:30px 0;
} h3{
margin-top: 10px;
}
</style>

最后进行路由表的相关配置:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import showblog from '@/components/showblog'
import addblog from '@/components/AddBlog'
import singleBlog from '@/components/SingleBlog' Vue.use(Router) export default new Router({
routes: [
{
path: '/',
name: 'showblog',
component: showblog
},
{
path: '/add',
name: 'addblog',
component: addblog
},
{
path: '/blog/:id', /*路由参数*/
component: singleBlog
},
],
mode:"history" //不用显示#号
})
还要在App.vue中进行一些编写,主要是使用写好的路由:
<template>
<div id="app">
<blog-header></blog-header>
<!-- <add-blog></add-blog> -->
<!-- <show-blog></show-blog> -->
<router-view/>
</div>
</template> <script>
import AddBlog from './components/AddBlog'
import showblog from './components/showblog'
import blogHeader from './components/BlogHeader'
export default {
name: 'App',
components: {
'add-blog': AddBlog,
'show-blog':showblog,
"blog-header":blogHeader
}
}
</script> <style> </style>
另外,还可以在main.js中进行一些全局属性的配置:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueResource from 'vue-resource'
import axios from 'axios' Vue.prototype.$axios = axios
//全局配置axios
//axios.defaults.baseURL='http://localhost:8080'
//请求头配置
/*
axios.defaults.headers.common['Authorization'] = 'Token'
axios.defaults.headers.post['Content-type'] = ''
axios.defaults.headers.get['Accepts']='application/json'
*/
Vue.config.productionTip = false
Vue.use(VueResource) //自定义指令
Vue.directive('rainbow',{
bind(el,binding,vnode){
el.style.color = "#" + Math.random().toString(16).slice(2,8)
}
}) Vue.directive('theme',{
bind(el,binding,vnode){
if(binding.value=='wide'){
el.style.maxWidth = "1260px"
}else if(binding.value='narrow'){
el.style.maxWidth="600px"
} if(binding.arg=='column'){
el.style.background = "#F4A460";
el.style.margin = "10px auto"
}
}
}) //自定义过滤器 全局的实现方式
/*Vue.filter("to-uppercase",function(value){
return value.toUpperCase();
})*/ Vue.filter("snippet",function(value){
return value.slice(0,10) + "...";
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
Vue简易博客总结的更多相关文章
- Django搭建简易博客
Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...
- 简易博客[ html + css ] 练习
1. 前言 通过使用 html + css 编写一个简易的博客作为入门练习 2. 代码及实现 2.1 目录结构 2.2 代码部分 <!DOCTYPE html> <html lang ...
- Nodejs+MongoDB+Bootstrap+esj搭建的个人简易博客
github:https://github.com/yehuimmd/myNodeBloy Nodejs+MongoDB+jQuery+Bootstrap-esj搭建的个人简易博客 主要功能 前台 : ...
- django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
上一篇博客介绍了comments库使用及ajax支持,现在blog已经具备了基本的功能,但是只能发表文字,不支持富文本编辑.今天我们利用markdown添加富文本支持. markdown语法说明: h ...
- django 简易博客开发 4 comments库使用及ajax支持
首先还是贴一下源代码地址 https://github.com/goodspeedcheng/sblog 上一篇文章我们介绍了静态文件使用以及如何使用from实现对blog的增删改,这篇将介绍如何给 ...
- django 简易博客开发 3 静态文件、from 应用与自定义
首先还是贴一下源代码地址 https://github.com/goodspeedcheng/sblog 上一篇博客我们介绍了 django 如何在views中使用templates以及一些常用的数 ...
- django 简易博客开发 2 模板和数据查询
首先还是贴一下项目地址 https://github.com/goodspeedcheng/sblog 因为代码全在上面 上一篇博客我们介绍了 django的安装配置,新建project,新建a ...
- django 简易博客开发 1 安装、创建、配置、admin使用
首先贴一下项目地址吧 https://github.com/goodspeedcheng/sblog 到现在位置项目实现的功能有: 1.后台管理使用Admin ,前端显示使用bootstrap 2. ...
- Vue个人博客关于标题自动打字机效果Typewriter
最近在写个人Blog 中间看过很多个人博客的开发 一大部分用的是Hexo框架或者vuePress框架 导入各种主题样式插件等等 但是看多了就会发现 很多博主的个人博客基本都很相似 并没有什么新东西呈现 ...
随机推荐
- ZOJ 3870 Team Formation 贪心二进制
B - Team Formation Description For an upcoming progr ...
- 【OI】关于快速幂的简单理解
都知道算某个数的幂需要线性的复杂度,为了优化复杂度,就出现了所谓的快速幂. 快速幂的代码很短,但是要原理需要一点心思. 首先,我们知道, a^b = a^c * a^d (c+d=b) 那么,不就可以 ...
- <form> 标签的entype属性
entype属性规定在发送到服务器之前应该如何对表单数据进行编码. 属性值 描述 application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/ ...
- Notification操作大全
目录 一:普通的Notification Notification 的基本操作 给 Notification 设置 Action 更新 Notification 取消 Notification 设置 ...
- RDA DEBUG
DEBUG寄存器:word 0xa0000010 word 0xa0000010 1 //debug开 word 0xa0000010 0 //debug关 当然也可以按模块打开/关闭debug信息, ...
- nginx 静态目录配置规则,路径匹配与本地资源
经常配了nginx静态目录,死活访问不了,每次访问404.查看文档后,发现nginx配置静态目录使 用以下规则 假如nginx是在本机,静态目录也是在本机, 1.子目录匹配 如下配置 location ...
- 错误: 实例 "ruiy" 执行所请求操作失败,实例处于错误状态。: 请稍后再试 [错误: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)].
错误: 实例 "ruiy" 执行所请求操作失败,实例处于错误状态.: 请稍后再试 [错误: 'ascii' codec can't decode byte 0xe6 in posi ...
- java笔记线程方式1获取对象名称
* 如何获取线程对象的名称呢? * public final String getName():获取线程的名称. * 如何设置线程对象的名称呢? * public final void setName ...
- bzoj 1633: [Usaco2007 Feb]The Cow Lexicon 牛的词典【dp】
预处理出g[i][j]表示原串第i个匹配第j个单词需要去掉几个字母(匹配不上为-1) 设f[i]为i及之后满足条件要去掉的最少字母 倒着dp! f[i]初始为f[i+1]+1,转移方程为f[i]=mi ...
- 1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
1642: [Usaco2007 Nov]Milking Time 挤奶时间 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 935 Solved: 55 ...