最近学习了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. 导入https证书

    摘 要 JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问.但是,如果该站点的证书未经权威机构的验证,JSSE将拒绝信任该证书从而不能访问HTTPS站 ...

  2. When to use next() and return next() in Node.js

    Some people always write return next() is to ensure that the execution stops after triggering the ca ...

  3. Dubbo源码-Dubbo是如何随心所欲自定义XML标签的

    叨叨 今天考虑了很久要不要写这篇文章. 距离<Dubbo源码>系列的开篇到现在已经快两个月时间了.当时是想着工作上的RPC框架使用存在一些让人头疼的问题,就来看看Dubbo给出了一套什么样 ...

  4. .Net Core vs .Net Framework 如何为一个应用程序选择一个运行时

    .Net Core是下一件大事吗?我已经使用了一段时间了,我倾向认为它是.事实上,我们推测,在2018年,对这项技术熟练的开发人员将会有巨大的需求.但是它和.Net Framework的区别是什么?你 ...

  5. Python Assert 为何不尽如人意

    Python中的断言用起来非常简单,你可以在assert后面跟上任意判断条件,如果断言失败则会抛出异常. >>> assert 1 + 1 == 2 >>> ass ...

  6. [爬虫]Fiddler证书错误

    在使用fiddler抓包的时候出现 creation of the root certificate was not successful 这个错误出现这个错误会导致https包抓不到 解决方法:1. ...

  7. python3:操作excel文件

    前提:自动化接口测试中,可以将用例放在excel中管理.结合实际情况讲解如何操作excel文件 1.安装xlrd:pip install xlrd 2.导入模块:import xlrd 3.打开Exc ...

  8. Mac下将文件复制到移动硬盘

    在Mac下将移动硬盘格式化成exfat,这样Mac和Windows都可以对移动硬盘进行识别

  9. balancer.go

    package) , {         close(b.upc)     }     return nil } func getHost(ep string) string {     url, u ...

  10. InfluxDB介绍

    InfluxDB介绍 InfluxDB用Go语言编写的一个开源分布式时序.事件和指标数据库,和传统是数据库相比有不少不同的地方. 类似的数据库有Elasticsearch.Graphite等. 特点 ...