vue组件化编程应用

写几个小案例来理解vue的组件化编程思想,下面是一个demo.

效果图示:
在这里插入图片描述
功能: Add组件用于添加用户评论,提交后右边评论回复会立马显示数据.Item组件点击删除可以删除当前用户评论.当List组件中用户评论为空时,会提示"暂无评论,点击左侧添加评论".

项目目录:
在这里插入图片描述
代码:

1.index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vue_demo</title>
    <link rel="stylesheet" href="./static/css/bootstrap.css">
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

2.main.js

import Vue from 'vue'
import App from './App'

new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

3.App.vue

<template>
  <div>
    <header class="site-header jumbotron">
      <div class="container">
        <div class="row">
          <div class="col-xs-12">
            <h1>请发表对Vue的评论</h1>
          </div>
        </div>
      </div>
    </header>
    <div class="container">
      <Add :addComment="addComment" />
      <!-- 组件通信:属性名最好与model中一致(绑定表达式) -->
      <List :comments="comments" :deleteComment="deleteComment"/>

    </div>
  </div>
</template>

<script>
  import Add from './components/Add'
  import List from './components/List'

  export default {
    name: 'App',
    data(){
      return {
        comments: [   // 数据在哪个组件,更新数据的行为(方法)就应该定义在哪个组件
          {
            name: 'Jack',
            content: 'vue so easy'
          },
          {
            name: 'Tom',
            content: 'vue so nice'
          },
          {
            name: 'Cat',
            content: 'vue so cool'
          },
        ],
      }
    },
    methods: {
      // 添加评论
      addComment (comment) {
        this.comments.unshift(comment)
      },
      // 删除指定下标的评论
      deleteComment (index) {
        this.comments.splice(index,1)
      }
    },
    components: {Add ,List},

  }
</script>

<style>

</style>

4.Add.vue

<template>
  <div class="col-md-4">
    <form class="form-horizontal">
      <div class="form-group">
        <label>用户名</label>
        <input type="text" class="form-control" placeholder="用户名" v-model="name">
      </div>
      <div class="form-group">
        <label>评论内容</label>
        <textarea class="form-control" rows="6" placeholder="评论内容" v-model="content"></textarea>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
          <button type="button" class="btn btn-default pull-right" @click="add">提交</button>
        </div>
      </div>
    </form>
  </div>
</template>

<script>
  export default {
    name: "Add",
    props: {  // 声明接受属性
      addComment: {   //指定属性名/属性值类型/必要性
        type: Function,
        required: true
      }
    },
    data () {
      return {
        name: '',
        content: ''
      }
    },
    methods: {
      add () {
        // 1.检查输入的合法性
        const name = this.name.trim()
        const content = this.content.trim()
        if (!name || !content) {
          alert('name和content不能为空')
          return
        }
        // 2.根据输入的数据,封装成一个comment对象
        const comment = {
          name,
          content
        }
        // 3.添加到comments中
        this.addComment(comment)
        // 4.清楚输入
        this.name = ''
        this.content = ''
      }
    }
  }
</script>

<style scoped>

</style>

5.List.vue

<template>
  <div class="col-md-8">
    <h3 class="reply">评论回复:</h3>
    <h2 v-show="comments.length===0">暂无评论,点击左侧添加评论!!!</h2>
    <ul class="list-group">
      <!-- 使用Item标签: 遍历数组,数组通信 -->
      <Item v-for="(comment,index) in comments" :key="index" :comment="comment"
        :deleteComment="deleteComment" :index="index"/>

    </ul>
  </div>
</template>

<script>
  // 引入Item组件
  import Item from './Item'

  export default {
    name: "List",
    // 声明接受属性: 会成为组件对象的属性(类似与vm: data(){return {comments: []}})
    props: ['comments','deleteComment'],  //只指定属性名
    components: { // 组件映射标签
      Item
    }

  }
</script>

<style scoped>
  .reply {
    margin-top: 0px;
  }

</style>

6.Item.vue

<template>
  <li class="list-group-item">
    <div class="handle">
      <a href="javascript:;" @click="deleteItem">删除</a>
    </div>
    <p class="user"><span >{{comment.name}}</span><span>说:</span></p>
    <p class="centence">{{comment.content}}</p>
  </li>
</template>

<script>
    export default {
      name: "Item",
      // 声明接受属性
      props: {  // 指定属性名和属性值的类型
        comment: Object,
        deleteComment: Function,
        index: Number
      },
      methods: {
        deleteItem () {
          const {comment,deleteComment,index} = this
          if (window.confirm(`是否确定删除${comment.name}的评论?`)) {
            deleteComment(index)
          }
        }
      }
    }
</script>

<style scoped>
  li {
    transition: .5s;
    overflow: hidden;
  }

  .handle {
    width: 40px;
    border: 1px solid #ccc;
    background: #fff;
    position: absolute;
    right: 10px;
    top: 1px;
    text-align: center;
  }

  .handle a {
    display: block;
    text-decoration: none;
  }

  .list-group-item .centence {
    padding: 0px 50px;
  }

  .user {
    font-size: 22px;
  }
</style>

posted @ 2019-11-17 23:24  zlgSmile  阅读(364)  评论(0编辑  收藏  举报