zoukankan      html  css  js  c++  java
  • Vue评论组件案例

    最近学习了Vue前端框架,在这里记录一下组件的用法,我自己试着写了一个评论的组件,大神看到勿喷,欢迎提出宝贵意见。

    首先看一下效果图

    用到的文件有:

    <link rel="stylesheet" href="../js/bootstrap/dist/css/bootstrap.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="../js/Ionicons/css/ionicons.min.css">
    <!-- jQuery 3 -->
    <script src="../js/jquery/dist/jquery.min.js"></script>
    <!-- Bootstrap 3.3.7 -->
    <script src="../js/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- vue -->
    <script src="../js/vue.js"></script>

    demo下载地址:https://download.csdn.net/download/qingchundaima/10842714

    话不多说直接上代码,基本注释我都写全了,这里我没有将js和html文件分开直接在html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <link rel="stylesheet" href="../js/bootstrap/dist/css/bootstrap.min.css">
      <!-- Ionicons -->
      <link rel="stylesheet" href="../js/Ionicons/css/ionicons.min.css">
      <!-- jQuery 3 -->
      <script src="../js/jquery/dist/jquery.min.js"></script>
      <!-- Bootstrap 3.3.7 -->
      <script src="../js/bootstrap/dist/js/bootstrap.min.js"></script>
      <!-- vue -->
      <script src="../js/vue.js"></script>
      <style>
        [v-cloak] {
          display: none
        } 
         .tb_comment{
          width: 100%;
          /* border: 1px solid; */
        }
        .tb_comment img{
           width:64px;
           height:64px;
        }
        .tb_user{
          width: 80px;
        }
     
     
             /* 用户评论内容展示 */
          .div_comment_content{
            padding: 6px 12px;  
            border: 1px solid #d2d6de;
            background-color: #f0f8ff;
          }
       
      </style>
    
    
    </head>
    
    <body>
      <div class="row" id="app" v-cloak>
        <div class='row'>
          <div class="col-md-3"></div>
          <div class="col-md-6">
            <!-- comment_item:传递给子组件数据  comment_data:父组件里定义的数据 -->
            <!-- id子父组件里我都定义成id----当前评论资源id -->
            <!-- prentsendcomment:在子组件里调用父组件发表方法的名称 sendcomment:父组件里发表方法 -->
            <!-- prentsendsupport:子组件里调用父组件点赞方法名称  sendsupport:父组件里点赞方法 -->
            <!-- prentsendopposition:子组件里调用父组件反对方法名称  sendopposition:父组件里反对方法 -->
            <temp_comment v-bind:comment_item="comment_data" v-bind:id="id" @prentsendcomment="sendcomment"
              @prentsendsupport="sendsupport" @prentsendopposition="sendopposition">
            </temp_comment>
    
          </div>
          <div class="col-md-3"></div>
    
        </div>
      </div>
    
      <!-- 评论组件html代码结构 -->
      <template id='tp_comment'>
        <div class="panel panel-primary">
          <div class="panel-heading">
            <h3 class="panel-title">欢迎您发表评论</h3>
          </div>
          <div class="panel-body form-check-inline">
            <label style="color:gray">请勿发表与本片无关的主题,评论需要审核</label>
            <textarea class="form-control" style="resize:none;" rows="5" placeholder="说点什么吧..." maxlength="20" v-model="input_comment"> </textarea>
            <span class="pull-right">还能输入<b style="color:red">{{surplus}}</b>/{{total}}</span><br>
            <input type="button" class="pull-right btn btn-primary" value="发表" @click="btnsend">
            <div v-for="item in comment_item" :key="item.Id">
              <table class="tb_comment table table-condensed">
                <tbody>
                  <tr>
                    <td class="tb_user">
                      <img class="img-circle" v-bind:src="item.PortraitUrl">
                    </td>
                    <td>
                      <p>{{item.NickName}} &nbsp;&nbsp;<i class="glyphicon glyphicon-time"></i>&nbsp;{{item.CreateTime|date}}
                        <span class="pull-right">
                          <a href="#" @click.prevent="btnsupport(item.Id)"> <i class="    glyphicon glyphicon-thumbs-up"></i>&nbsp;({{item.SupportNum}})</a>
                          &nbsp;&nbsp;
                          <a href="#" @click.prevent="btnopposition(item.Id)"><i class="    glyphicon glyphicon-thumbs-down"></i>&nbsp;({{item.OppositionNum}})</a>
                        </span>
                      </p>
                      <div class='div_comment_content'>
                        {{item.CommentContent}}
                      </div>
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
            <table class="tb_comment table table-condensed" v-if="comment_item.length==0">
              <tbody>
                <tr>
                  <td class="text-muted" style="100%">
                    <h4>暂无评论...</h4>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </template>
    
      <script>
        window.onload = function (ev) {
          // 定义评论组件
          var temp_comment = {
            template: '#tp_comment',
            // 组件里的数据必须是方法返回。
            data: function () {
              return {
                input_comment: '',// 输入的评论 
                total: 200,// 评论可输入总字数 
              }
            },
            // 父组件传递的消息列表
            props: ['comment_item', 'id'],
            // 计算属性
            computed: { // 计算剩余可输入字数
              surplus: function () {
                return this.total - this.input_comment.length;
              },
            },
            // 自定义过滤器
            filters: {
              // 时间过滤器
              "date": function (d) {
                var newdate = new Date(d);
                y = newdate.getFullYear();
                m = (newdate.getMonth() + 1).toString().padStart(2, '0');
                d = newdate.getDay().toString().padStart(2, '0');
                hh = newdate.getHours().toString().padStart(2, '0');
                mm = newdate.getMinutes().toString().padStart(2, '0');
                ss = newdate.getSeconds().toString().padStart(2, '0');
                return y + '-' + m + '-' + d + ' ' + hh + ':' + mm + ':' + ss
              }
            },
            // 方法
            methods: {
              // 父组件传入的发表评论方法,由子组件调用父组件发表评论方法
              btnsend: function () {
                // 调用父组件方法。
                this.$emit('prentsendcomment', this.id, this.input_comment)
              },
              // 评论点赞
              btnsupport: function (id) {
                // 调用父组件方法。
                this.$emit('prentsendsupport', id)
              },
              // 评论反对
              btnopposition: function (id) {
                // 调用父组件方法。
                this.$emit('prentsendopposition', id)
              }
            }
          }
    
          var vm = new Vue({
            el: '#app',
            data: {
              id: 12,
              // 测试数据
              comment_data: [
                {
                  Id: 1,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '那年初夏',
                  CommentContent: '劝君更敬一杯酒',
                  SupportNum: 14,
                  OppositionNum: 323,
                  CreateTime: new Date()
                },
                {
                  Id: 2,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '列夫托尔斯泰',
                  CommentContent: '这个部电影指的我们去好好看看。',
                  SupportNum: 2312,
                  OppositionNum: 33,
                  CreateTime: new Date()
                },
                {
                  Id: 3,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '小怪兽',
                  CommentContent: '千万不要下载,千万不要下载,千万不要下载,我活了34年,这种烂片,第一次见难道比纯洁心灵还要烂》?',
                  SupportNum: 23,
                  OppositionNum: 43,
                  CreateTime: new Date()
                },
                {
                  Id: 4,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '帅大叔',
                  CommentContent: '到菜市场买菜,看到一个孩子在看摊,我问:“一只鸡多少钱?” 那孩子回答:“23。” 我又问:“两只鸡多少钱?” 孩子愣了一下,一时间没算过来,急中生智大吼一声:“一次只能买一只!”',
                  SupportNum: 56,
                  OppositionNum: 55,
                  CreateTime: new Date()
                },
                {
                  Id: 5,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '夏末',
                  CommentContent: '版权归作者所有,任何形式转载请联系作者。作者:电影幕后故事(来自豆瓣)来源:https://movie.douban.com/review/9666136/郭敬明当作家远不如当商人成功。当作家写出来的那些不知所云、虚到不行的句子只能骗一骗心智不成熟的小孩子;但做商人时所展现出来的精明与虚伪倒是能骗过不少人。我指的就这部披着“反校园霸凌”外衣,实则还是矫情、无病呻吟的电影。',
                  SupportNum: 78,
                  OppositionNum: 23,
                  CreateTime: new Date()
                },
                {
                  Id: 6,
                  PortraitUrl: "../images/user2-160x160.jpg",
                  NickName: '罗罔极',
                  CommentContent: '前阵子,我犯了个错。 我在文章里说,当下的大陆喜剧,有两大派系分庭抗礼。 一派是徐峥宁浩,其作品核心偏于人间悲剧; 一派是开心麻花,其作品核心偏于纯粹喜剧。 没想到,现在又杀出个程咬金。 八年酝酿,慢工打磨。 导演、编剧:黄渤。 这一出手,就震惊四座—— 《一出好... ',
                  SupportNum: 332,
                  OppositionNum: 33,
                  CreateTime: new Date()
                },
              ]
            },
            // 注册组件
            components: {
              'temp_comment': temp_comment,
            },
            // 方法
            methods: {
              getdata: function () {
                var list = JSON.parse(localStorage.getItem('cmts') || '[]')
                this.list = list;
              },
              // 由子组件调用后传入评论资源的id和内容
              sendcomment: function (id, content) {
                alert(id + '------' + content)
              },
              // 子组件触发点赞
              sendsupport: function (id) {
                alert(id)
              },
              // 子组件触发反对
              sendopposition: function (id) {
                alert(id)
              }
            },
    
            beforeCreate() {
              // 这时候data 和methods 都还没有被初始化,所以访问不到getdata
            },
            created() {
              this.getdata();
            }
          })
    
        };
      </script>
    </body>
    
    </html>
  • 相关阅读:
    C++高级程序员(廊坊+高薪)欢迎各种漂回家!(该职位已截止)
    utf8_unicode_ci和utf8_general_ci区别
    Percentencoding
    libiconv GNU Project Free Software Foundation (FSF)
    2013年1月6日北京交流会:当当网如何打造个性化推荐&精准营销生态系统
    COM Vs .NET (Qt ActiveQt)
    新一篇: Unicode字符编码规范 实例详细介绍各种字符集编码转换问题
    甩开外包,雄踞榜首:揭开“宫爆老奶奶”成功的秘密
    awk使用命令
    API SOCKET基础(三)网络字节序与主机字节序的转换
  • 原文地址:https://www.cnblogs.com/wendj/p/10101614.html
Copyright © 2011-2022 走看看