最近学习了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="width: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>

Vue评论组件案例的更多相关文章

  1. vue 评论 computed watch 分隔符 局部组件 全局组件 子传父消息|父传子消息

    评论案例 splice: (start 几位,替换(新增)内容) splice(0,0,内容)在头部插入内容 splice(0,1) 把索引为0的往后删除1位  splice(0,1,内容)把索引为0 ...

  2. 前端笔记之Vue(二)组件&案例&props&计算属性

    一.Vue组件(.vue文件) 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器 ...

  3. Vue 根组件,局部,全局组件 | 组件间通信,案例组件化

    一 组件 <div id="app"> <h1>{{ msg }}</h1> </div> <script src=" ...

  4. vue路由异步组件案例

    最近研究了vue性能优化,涉及到vue异步组件.一番研究得出如下的解决方案. 原理:利用webpack对代码进行分割是异步调用组件前提.异步组件在优先级上让位同步组件.下面介绍的是怎么实现异步组件. ...

  5. 【Vue.js实战案例】- Vue.js递归组件实现组织架构树和选人功能

    大家好!先上图看看本次案例的整体效果. 浪奔,浪流,万里涛涛江水永不休.如果在jq时代来实这个功能简直有些噩梦了,但是自从前端思想发展到现在的以MVVM为主流的大背景下,来实现一个这样繁杂的功能简直不 ...

  6. 从零开始学 Web 之 Vue.js(六)Vue的组件

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  7. react-react中的css+评论组件

    一个小案例,巩固有状态组件和无状态组件的使用 通过for循环生成多个组件 数据: CommentList = [ { user: '张三', content: '哈哈,沙发' }, { user: ' ...

  8. 如何理解vue.js组件的作用域是独立的

    vue.js组件的作用域是独立,可以从以下三个方面理解: 1.父组件模板在父组件作用域内编译,父组件模板的数据用父组件内data数据:2.子组件模板在子组件作用域内编译,子组件模板的数据用子组件内da ...

  9. 16款优秀的Vue UI组件库推荐

    16款优秀的Vue UI组件库推荐 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基 ...

随机推荐

  1. OAthe2 Login use OkHttpClient and OAuth2RestTemplate

    http://samchu.logdown.com/posts/1437422-oathe2-login-use-okhttpclient-and-oauth2resttemplate?utm_sou ...

  2. php对接微信小程序支付

    前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就 ...

  3. ESXI的安装和部署

     1.  实验拓扑图: 2.  实验要求 (1)   新建一台exsi主机,安装exsi5.5系统. 步骤: 1)新建虚拟机,导入光盘. 2)安装esxi系统 (2)在exsi主机中,配置IP地址为1 ...

  4. 字符串匹配KMP算法的讲解C++

    转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...

  5. I/O------字节输出流

    package io.day03; import java.io.FileOutputStream; import java.io.OutputStream; public class day03ou ...

  6. BZOJ_4196_[Noi2015]软件包管理器_树链剖分

    BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...

  7. JS基础:常用API

    全局属性 typeof() 检测数据类型 parseInt() 从字符串解析一个整数 parseFloat() 从字符串解析一个小数 Number() 强制类型转换为数字 String() 强制类型转 ...

  8. Entity Framework Core 关联删除

    关联删除通常是一个数据库术语,用于描述在删除行时允许自动触发删除关联行的特征:即当主表的数据行被删除时,自动将关联表中依赖的数据行进行删除,或者将外键更新为NULL或默认值. 数据库关联删除行为 我们 ...

  9. koa+mysql+vue+socket.io全栈开发之web api篇

    目标是建立一个 web QQ的项目,使用的技术栈如下: 后端是基于koa2 的 web api 服务层,提供curd操作的http接口,登录验证使用的是 json web token,跨域方案使用的是 ...

  10. Arduino入门笔记(6):温度传感器及感温杯实验

    转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.本次实验所需器材 1.Arduino板 :https://item.taob ...