Web實(shí)戰(zhàn)之文章閱覽與編輯


完成的功能

  • 閱覽文章
  • 有作者信息欄
  • 根據(jù)當(dāng)前用戶判斷是否可修改文章
  • 修改并保存文章

依賴的第三方工具

  • vue.js
  • SuMarkdown
  • jquery
  • bootstrap-taginput

前言

我們先來分析一下這個(gè)功能的實(shí)現(xiàn)其做,其實(shí)這個(gè)過程中是需要很多數(shù)據(jù)的——作者的數(shù)據(jù)构挤,文章的數(shù)據(jù)菠红,當(dāng)前用戶的數(shù)據(jù)。如果分兩個(gè)頁面來做沥曹,顯然許多異步數(shù)據(jù)會(huì)被重復(fù)加載,所以我決定把這一部分做成一個(gè)極小的單頁面應(yīng)用。

同時(shí)福压,在這一次的博客里仿村,用到了許多Vue的重要特性锐朴,比如component,directive蔼囊,life-cycle焚志,是Vue一個(gè)不錯(cuò)的示例。

頁面代碼

主頁面代碼

 <!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">

    <title>
        <%= title %>
    </title>
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="lib/suMarkdown/lib/highlight/styles/default.css">
    <link rel="stylesheet" href="lib/bootstrap/bootstrap-tag/bootstrap-tagsinput.css">
    <script src="lib/jquery/dist/jquery.min.js"></script>
    <script src="lib/bootstrap/dist/js/bootstrap.min.js"></script>
    <script src="lib/suMarkdown/lib/highlight/highlight.pack.js"></script>
    <script src="lib/suMarkdown/lib/marked/marked.js"></script>
    <script src="lib/bootstrap/bootstrap-tag/bootstrap-tagsinput.min.js"></script>
    <script src="lib/suMarkdown/js/suMarkdown.js"></script>
</head>
<body>
    <%include layout/left-bar.ejs%>
    <div v-component="{{currentView}}" v-ref='center'></div>
    <%include layout/alert.ejs%>
    <script src="js/blog.js"></script>
</body>

閱覽模板

<style>

    .log-bar{
        position:fixed;
        top:10px;
        right:0;
        width:100%;
        z-index:999;
        padding-right:10px;
    }
    .log-bar *{
        float:right;
        margin-right:10px;
    }
    .header-bar{
        position:fixed;
        top:10px;
        right:0;
        width:100%;
        z-index:999;
        padding-right:10px;
    }
    .header-bar .btn-group{
        top:15px;
        float:right;
        margin-right:6px;
        vertical-align:middle;
    }
    .header-bar .dropdown-toggle{
        float:right;
        top:10px;
        margin-right:10px;
        position:relative;
        width:42px;
        height:42px;
        display:inline-block;
    }
    .header-bar .dropdown-toggle img{
        display:block;
        width:100%;
        height:100%;            
        border: 2px solid white;
    }
    .header-bar .dropdown-toggle .caret{
        position:absolute;
        right:-8px;
        top:20px;
    }
    .header-bar .dropdown-menu{
        left:auto;
        right:0;
        top:50px;
        position:absolute;
        z-index:1000;
        min-width:160px;
        padding:5px 5px;
        margin:2px 0 0;
        border: 1px solid #ccc;
    }
    .header-bar li{
        line-height:20px;
        margin-bottom:5px;
    }
    .header-bar li a{
        padding:3px 20px;
        clear:both;
        font-weight:normal;
    }
    .header-bar li a:hover{
        background-color:#333333;
        color:white;
    }
    .header-bar li a span{
        margin-right:8px;
    }


    .people {
        position: absolute;
        right: 70%;
        top: 80px;
        width: 160px;
        padding: 0 20px 20px 0;
        text-align: right;
    } 

    .people .author {
    margin: 0;
    font-size: 16px;
    font-weight: bold;
    line-height: 24px;
    }
    .people img{
        width: 60px;
        height: 60px;
        margin: 0 0 10px 0;
        display: inline-block;
        border: 2px solid white;
    }
    .people .about{
        color: #999999;
        font-size: 12px;
        margin:0 0 10
    }
    .people  .sns{
        margin-bottom:10px;
    }
    .sns a{
        width:20px;
        margin-left:7px;
        display:inline-block;
        color:#555555;
    }
    .sns a img{
        opacity:0.8;
        border-radius:3px;
        height:auto;
        max-width:100%;
        vertical-align:middle;
        border:0;
    }

    .container .article{
        position:relative;
        line-height:30px;
        left:25%;
        width:60%;
        padding:0 40px 30px;
    }
    .article #blogHead h1{
        font-size:50px;
        font-weight:700;
        line-height:70px;
    }
    .article #blogHead p{
        font-size:14px;
        color:#999999;
    }
    .article #blogHead span{
        margin:0 2%;
    }
    .article #blogBody{
        font-size:17px;
    }


</style>






<div class="header-bar" v-show="login" >
    <a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">
        <img class="img-circle" v-attr="src: user.avatar">
        <span class="caret"></span>
    </a>
    <ul class="dropdown-menu" role="menu">
        <li>
            <a href="#">
                <span class="glyphicon glyphicon-user"></span>
                我的主頁
            </a>
            <a href="#">
                <span class="glyphicon glyphicon-hand-right"></span>
                我的小組
            </a>
            <a href="#">
                <span class="glyphicon glyphicon-cog"></span>
                我的設(shè)置
            </a>
            <a href="#">
                <span class="glyphicon glyphicon-inbox"></span>
                消息
            </a>
            <a href="#">
                <span class="glyphicon glyphicon-info-sign"></span>
                幫助
            </a>
            <a href="#">
                <span class="glyphicon glyphicon-log-out"></span>
                登出
            </a>
        </li>
    </ul>
    <div class="btn-group">
        <a href="javascript:void(0)" class="btn" v-on="click: edit()" v-show="editable">
            <span class="glyphicon glyphicon-edit"></span>
        </a> 
    </div>
</div>

<div class="log-bar" v-show="!login">
    <a href='#'>登陸</a>
    <a href='#'>注冊(cè)</a>
</div>

<div class="container">
    <div class="people">
        <a class="author" href="#">
            <img class="img-circle" v-attr="src: author.avatar">
            <br>
            {{blog.author}}
        </a>
        <div class="about">
            <p>{{author.description}}</p>
        </div>
        <div class="sns">
            <a href="#">
                <img src="img/home.png">
            </a>
            <a href="#">
                <img src="img/home.png">
            </a>
            <a v-href="author.page">
                <img src="img/home.png">
            </a>
        </div>
    </div>
    <div class="article">
        <div id="blogHead">
            <h1>{{blog.title}}</h1>
            <p>
            <span>發(fā)表時(shí)間     {{blog.date | toDate }}</span>
            <span>字?jǐn)?shù):{{blog.body.length}}</span>
                <span>閱讀量:30</span>
            </p>
        </div>
        <div id="blogBody">
        </div>
    </div>
</div>

編輯模板


<style>


    body{
        background-color: #f5f5f5;
    }
    .right-bar{
        float:left;
        height: 100%;
        width:100px;
        padding: 2% 5%;

    }
    .center-page{
        float: left;
        padding: 0 7% 0 7%;
        width:86%;
        vertical-align: middle;
        border-right: solid 1px;
        border-color: #cccccc;
    }
    .form-group h4{
        position: relative;
        top:-12px;
    }
    form:first-child input{
        font-size: 16px;
    }



    .alert {
        margin: 3% 5% 0;
        text-align: center;
        position: fixed;
        top: 80%;
        width:60%;
    }

</style>
<div class="container">
    <div class="center-page" >
       <form class="form-horizontal" id="writePage">
           <div class="form-group">
               <div class="col-sm-1"></div>
               <h4 class="col-sm-2 control-label">標(biāo)題</h4>
               <div class="col-sm-6">
                   <input class="form-control" v-model="myBlog.title">
               </div>
           </div>
           <br>
           <div class="form-group">
               <div class="col-sm-1"></div>
               <h4 class="col-sm-2 control-label">標(biāo)簽</h4>
               <div class="col-sm-6">
                   <select multiple class="form-control" data-role="tagsinput" v-tags="myBlog.tags"></select>
               </div>
           </div>
           <br>
           <div class="form-group">
               <div class="col-sm-12 suMarkdown">
                <style>
                    .su-toolbar{
                        width:100%;
                        height:45px;
                        display: block;
                        background: #ffffff;
                        padding: 5px;
                        border: solid 1px;
                        border-color: #cccccc;
                    }
                    .su-toolbar .tool-block{
                        cursor: pointer;
                        display: block;
                        width:35px;
                        margin:0 1%;
                        height:35px;
                        float:left;
                        padding: 5px;
                    }
                    .su-toolbar .tool-block *{
                        left:20%;
                        top:20%;
                    }
                    .su-toolbar .tool-block:hover{
                        background: #00ffff;
                    }
                    .su-toolbar button{
                        margin-top:5px;
                    }
                    .suEditor{
                        width:50%;
                        float:left;
                        display: block;
                    }
                    .suEditor textarea{
                        width:100%;
                        height: 400px;
                        background: #ffffff;
                        tab-size: 4;
                        border:solid 1px;
                        border-top: none;
                        border-color: #cccccc;
                        padding: 20px;
                        resize: none;
                    }
                    .suEditor textarea:focus{
                        background: #fff;
                        border-color:#cccccc ;
                        outline: none;
                    }
                    .suPreview{
                        width:50%;
                        left:50%;
                        float:left;
                        background: #ffffff;
                        height: 400px;
                        display: block;
                        overflow: auto;
                        padding: 0 20px;
                        border-right: solid 1px;
                        border-bottom: solid 1px;
                        border-color: #cccccc;
                    }
                    .suProgress{
                        width: 100%;
                    }
                </style>
                <div class="suProgress progress">
                    <div class="progress-bar su-progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100">
                        0%
                    </div>
                </div>
                <div class="su-toolbar">
                    <div class="tool-block su-tool-bold" title="加粗(Ctrl+B)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-bold"></span>
                    </div>
                    <div class="tool-block su-tool-italic" title="斜體(Ctrl+I)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-italic"></span>
                    </div>
                    <div class="tool-block su-tool-head" title="標(biāo)題(Ctrl+H)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-header"></span>
                    </div>
                    <div class="tool-block su-tool-link" title="鏈接(Ctrl+L)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-link"></span>
                    </div>
                    <div class="tool-block su-tool-img" title="圖片(Ctrl+G)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-picture"></span>
                    </div>
                    <div class="tool-block su-tool-list" title="無序列表(Ctrl+U)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-list"></span>
                    </div>
                    <div class="tool-block su-tool-orderlist" title="有序列表(Ctrl+O)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-th-list"></span>
                    </div>
                    <div class="tool-block su-tool-code" title="單行代碼(Ctrl+K)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-asterisk"></span>
                    </div>
                    <div class="tool-block su-tool-quote" title="引用(Ctrl+Q)" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-comment"></span>
                    </div>
                    <div class="tool-block su-tool-plus" title="文件上傳" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-upload"></span>
                    </div>
                    <input type="file" style="display: none" class="su-tool-upload" multiple>
                    <a class="tool-block su-tool-help"  title="幫助" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-info-sign"></span>
                    </a>
                    <div class="tool-block pull-right su-tool-fullscreen" title="全屏" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-fullscreen"></span>
                    </div>

                    <div class="tool-block pull-right su-tool-preview" title="預(yù)覽" data-placement="top" data-toggle="tooltip">
                        <span class="glyphicon glyphicon-eye-open"></span>
                    </div>
                </div>
                <div class="suEditor">
                    <textarea v-model="myBlog.body"></textarea>
                </div>
                <div class="suPreview">
                </div>
               </div>
           </div>
        </form>
        <button class="btn btn-primary btn-lg pull-left" id="submit" v-on="click: submit()">
            發(fā)表
        </button>
        <button class="btn btn-primary btn-lg pull-right" id="submit" v-on="click: cancel()">
            取消
        </button>
    </div>
    <div class="right-bar" >
        <img class="img-circle" style="width: 90px;height: 90px;" v-attr="src: author.avatar">
    </div>
</div>

前端代碼

Directive

/**
 * Created by suemi on 14-12-13.
 */
module.exports={
  tag:function(Vue){
       Vue.directive('tags',{
          twoWay:true,
          bind: function () {
              var self=this;
              console.log(self);
              $(self.el).on('itemAdded',function(){
                  scope.blog.tags=$(this).val();
              });
              $(self.el).on('itemRemoved',function(){
                  scope.blog.tags=$(this).val();
              });
          },
          update:function(){},
          unbind:function(){
              $(this.el).off();
          }
      });
      return module.exports;
  },
  all:function(Vue){
      for(var i in module.exports){
          if(i==='all') return module.exports;
          else module.exports[i](Vue);
      }
      return module.exports;
  }
};

讓所有函數(shù)返回module.exports可以支持漂亮的鏈調(diào)的寫法压真,同時(shí)還寫了all函數(shù)以實(shí)現(xiàn)像angular一樣(如下)

angular.module('demo',['app.directives']);

一次加載全部directive

Components

/**
 * Created by suemi on 14-12-13.
 */
module.exports={
    readBlog:function(Vue){
        var scope=Vue.component('readBlog',{
            inherit:true,
            template:require('../templates/readBlog.html'),
            ready:function(){
                $('#blogBody').html(marked(this.blog.body));
                $('pre code').each(function(i,block){
                       hljs.highlightBlock(block);
                });
            },
            methods:{
                edit:function(){
                    console.log(this);
                    this.currentView='editBlog';
                }
            },
            filters:{
                toDate:function(date){
                    var tmp=new Date(date);
                    return tmp.getFullYear()+'-'+tmp.getMonth()+'-'+tmp.getDate()+' '+tmp.toTimeString().split(' ')[0];
                }
            }
        });
        return module.exports;
    },
    editBlog:function(Vue){
      var scope=Vue.component('editBlog',{
          inherit:true,
          template:require('../templates/editBlog.html'),
          ready:function(){
            console.log(this.$el);
            $.extend(this.myBlog,this.blog);
            //復(fù)制原文標(biāo)簽
            $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]",$(this.$el)).tagsinput();
            var tmp=[];
            $.extend(tmp,this.blog.tags);
            for(var i=0;i<tmp.length;i++) $('select').tagsinput('add',tmp[i]);

            SuMarkdown({
                preview:true,
                upload:'/upload'
            });
            $('.suPreview').html(marked(this.myBlog.body));
            $('pre code').each(function(){hljs.highlightBlock(this);});
          },
          data:function(){
              return {
                  myBlog:{
                    title:'',
                    body:'',
                    tags:[],
                    author:''
                  }
              };
          },
          methods:{
            save:function(){
                var tmp=window.location.href.split('/');
                $.post(window.location.href,scope.myBlog).done(function(data){
                    if(data.success) {
                        $.extend(scope.blog,scope.myBlog);
                        scope.content=marked(scope.blog.body);
                    }
                    else{
                        if(!data.err.message) return;
                        scope.msg=data.err.messgae;
                        scope.display=true;
                    }
                }).fail(function(){
                    scope.msg='未知錯(cuò)誤娩嚼,請(qǐng)重試';
                    scope.display=true;
                });
            },
            cancel:function(){
                this.currentView='readBlog';
            }
          }
      });
    },
    all:function(Vue){
        for(var i in module.exports){
            if(i==='all') return module.exports;
            else module.exports[i](Vue);
        }
        return module.exports;
    }
};

main.js

/**
 * Created by suemi on 14-12-13.
 */
hljs.initHighlightingOnLoad();
var Vue=require('vue');
//Vue.config.debug=true;
require('./directives.js').tag(Vue);
require('./components.js').readBlog(Vue).editBlog(Vue);



scope=new Vue({
    el:'body',
    data:{
        user:{
            name:'',
            avatar:''
        },
        author:{
            avatar:''
            description:'',
            page:''
        },
        blog:{
            title:'',
            tags:[],
            body:'',
            author:'',
            date:undefined,
            content:''//html of the blog
        },
        msg:'',
        display:false,
        currentView:'readBlog',
        editable:true,
        login:false
    },
    methods:{
        getAuthor:function(){
            var tmp=window.location.href.split('/');
            $.get('/getBlog/'+tmp.pop()).done(function(data){
                if(data.success){
                    $.extend(scope.user,data.user);
                    $.extend(scope.author,data.author);
                    $.extend(scope.blog,data.blog);
                    $('#blogBody').html(marked(scope.blog.body));
                    $('pre code').each(function(){hljs.highlightBlock(this);});
                    //scope.blog.content=marked(scope.blog.body);
                    if(scope.user.name!=='') scope.login=true;
                    if(scope.user.name!==scope.blog.author) scope.editable=false;
                }
                else window.location.href='/404';
            }).fail(function(){
                window.location.href='/404';
            });
        },
    }
});


scope.getAuthor();

后端代碼

/**
 *
 * Created by suemi on 14-12-4.
 */
var Err=usf.module.tool.Err,
    EndHanler=usf.module.tool.EndHandler,
    msg=usf.module.msg,
    Then=usf.lib.then,
    User=usf.db.def.User,
    Blog=usf.db.def.Blog;

function writeBlog(req,res){
    req.session.uname='suemi';
    if(req.body.author!==req.session.uname)
        return res.json({
            success:false,
            err:new Err('用戶名不一致')
        });
    (new Blog(req.body)).save(function(err){
       if(!err) res.json({
           success:true,
           err:null
       });
        else res.json({
           success:false,
           err: new Err('后臺(tái)錯(cuò)誤,稍后再試')
       });
    });
}

function editBlog(req,res){
    Then(function(cont){
        if(!req.session.uname) return new Err('未登錄');
        Blog.findById(req.params.blogID,cont);
    }).then(function(cont,doc){
        if(!doc) return new Err(msg.BLOG.blogNone);
        if(doc.author!==req.session.uname) return new Err('權(quán)限不足');
        delete req.body._id;
        doc=tool.union(doc,req.body);
        doc.save(cont);
    }).then(function(cont){
        res.json({
            success:true,
            err:null
        });
    }).fail(EndHandler);
}

function getBlog(req,res){
    var tmp={};
    tmp.user={};
    tmp.author={};
    Then(function(cont){
        Blog.findById(req.params.blogID,cont);
    }).then(function(cont,doc){
        if(!doc) return new Err(msg.BLOG.blogNone);
        tmp.blog=doc;
        User.findOne({username:doc.author},cont);
    }).then(function(cont,doc){
        if(!doc) return new Err('數(shù)據(jù)錯(cuò)誤');
        tmp.author.name=doc.username;
        tmp.author=tool.union(tmp.author,doc.profile);
        if(req.session.uname) User.findOne({username:req.session.uname},cont);
        else cont();
    }).then(function(cont,doc){
        if(doc){
            tmp.user.name=doc.username;
            tmp.user=tool.union(tmp.user,doc.profile);
        }
        res.json({
            success:true,
            user:tmp.user,
            author:tmp.author,
            blog:tmp.blog,
            err:null
        });
    }).fail(EndHandler);
}
module.exports= {
    writeBlog: writeBlog,
    editBlog:  editBlog,
    getBlog:   getBlog
};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滴肿,一起剝皮案震驚了整個(gè)濱河市岳悟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖贵少,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呵俏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡滔灶,警方通過查閱死者的電腦和手機(jī)普碎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來录平,“玉大人麻车,你說我怎么就攤上這事《氛猓” “怎么了动猬?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長表箭。 經(jīng)常有香客問我赁咙,道長,這世上最難降的妖魔是什么免钻? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任彼水,我火速辦了婚禮,結(jié)果婚禮上极舔,老公的妹妹穿的比我還像新娘凤覆。我一直安慰自己,他們只是感情好姆怪,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布叛赚。 她就那樣靜靜地躺著,像睡著了一般稽揭。 火紅的嫁衣襯著肌膚如雪俺附。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天溪掀,我揣著相機(jī)與錄音事镣,去河邊找鬼。 笑死揪胃,一個(gè)胖子當(dāng)著我的面吹牛璃哟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喊递,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼随闪,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了骚勘?” 一聲冷哼從身側(cè)響起铐伴,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤撮奏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后当宴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畜吊,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年户矢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玲献。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梯浪,死狀恐怖捌年,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驱证,我是刑警寧澤延窜,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站抹锄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荠藤。R本人自食惡果不足惜伙单,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哈肖。 院中可真熱鬧吻育,春花似錦、人聲如沸淤井。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽币狠。三九已至游两,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漩绵,已是汗流浹背贱案。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留止吐,地道東北人宝踪。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像碍扔,于是被迫代替她去往敵國和親瘩燥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 奧斯維辛是一個(gè)很安靜的地方不同。世界上鮮少有這樣的景點(diǎn)——有著絡(luò)繹不絕的游客厉膀,卻沒有通常觀光者的嬉笑怒罵,取而代之的是...
    薄暮初陽閱讀 1,650評(píng)論 6 16
  • Git Flow 是構(gòu)建在Git之上的一個(gè)軟件開發(fā)活動(dòng)源碼管理的模型,是在Git之上構(gòu)建的一項(xiàng)源碼管理最佳實(shí)踐站蝠。 ...
    元亨利貞o閱讀 557評(píng)論 0 1
  • 就是你做最原始的動(dòng)作汰具,像朝圣者一樣,你也會(huì)得到別人的憐憫菱魔。
    思考者王峰閱讀 138評(píng)論 0 0
  • 愿景:通過90天的踐行留荔,先完成一個(gè)小目標(biāo),接下來再完成下一個(gè)目標(biāo)澜倦,人生的精彩從此展開…… 無規(guī)則不成方圓聚蝶,根據(jù)以下...
    alicewang588閱讀 329評(píng)論 0 0