【Vue】Vue模块化实战-demo1-动态评价页面

1. 目标功能界面

在这里插入图片描述
项目代码:https://github.com/yk2012/vue_demo/tree/main/demo2_Comments

2. 界面模块拆分

在这里插入图片描述
在这里插入图片描述

3. 主页 index.html

在head标签里引入bootstrap.css文件

<!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>

4. 静态页面搭建

4.1 main.js

  • 打包入口js文件,后期全部打包形成一个app.js在主页index.html中
import Vue from 'vue'
import App from './App.vue'

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

4.2 App.vue

  1. 引入标签 import
  2. 映射组件标签 components
  3. 使用组件标签
<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">
      <!-- *3* 使用组件标签 -->
      <Add />
      <List />
    </div>
  </div>
</template>

<script>
<script>
  // *1* 引入组件
  import Add from './components/Add'
  import List from './components/List'

  export default {
     
     
    // *2* 映射组件标签
    components: {
     
     
      Add,
      List
    }
  }
</script>
</script>

<style>

</style>

4.3 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="用户名">
      </div>
      <div class="form-group">
        <label>评论内容</label>
        <textarea class="form-control" rows="6" placeholder="评论内容"></textarea>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
        <button type="button" class="btn btn-default pull-right">提交</button>
        </div>
      </div>
    </form>
  </div>
</template>

<script>
  export default {
     
     

  }
</script>

<style>

</style>

4.4 List.vue

<template>
  <div class="col-md-8">
    <h3 class="reply">评论回复:</h3>
    <h2 style='display: none'>暂无评论,点击左侧添加评论!!!</h2>
    <ul class="list-group">
      <li class="list-group-item">
        <div class="handle">
          <a href="javascript:;">删除</a>
        </div>
        <p class="user"><span >xxx</span><span>说:</span></p>
        <p class="centence">React不错!</p>
      </li>
      <li class="list-group-item">
        <div class="handle">
          <a href="javascript:;">删除</a>
        </div>
        <p class="user"><span >yyy</span><span>说:</span></p>
        <p class="centence">React有点难!</p>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
     
     

  }
</script>

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

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>

4.5 展示

在这里插入图片描述

5. 动态组件

5.1 动态显示初始化数据

  • 数据data:用户名+评论内容
  • 用数组存储 []
  • 数据放在App组件中

5.1.1 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">
      <!-- *3* 使用组件标签 -->
      <add />
      <list :comments="comments" />
    </div>
  </div>
</template>

<script>
    // *1* 引入组件
import Add from './components/Add'
import List from './components/List'

  export default {
     
     
    data(){
     
     
      return {
     
     
        comments: [
          {
     
     
            name:'Bob',
            content: 'Vue so easy.'
          },
          {
     
     
            name: 'Cat',
            content: 'Vue so so.'
          }
        ]
      }
    },
    // *2* 映射组件标签
    components: {
     
     
      Add,
      List
    }
  }
</script>

<style>

</style>



5.1.2 List.vue

<template>
  <div class="col-md-8">
    <h3 class="reply">评论回复:</h3>
    <h2 style='display: none'>暂无评论,点击左侧添加评论!!!</h2>
    <ul class="list-group">
      <item v-for="(comment, index) in comments" :key="index" :comment="comment" />
    </ul>
  </div>
</template>

<script>
import Item from './Item.vue'
export default {
     
     
  //声明接收属性, 这个属性就会成为组件对象的属性
  props: ['comments'],
  
  components: {
     
      Item },
}
</script>

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


</style>

5.1.3 Item.vue

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

<script>
export default {
     
     
  props:{
     
      // 指定属性名和属性值的类型
    comment: Object,
  }
}
</script>

<style>
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>

5.1.4 展示

在这里插入图片描述

5.2 动态交互——添加操作

App.vue

  • 数据在哪个组件,更新数据的行为(方法)就定义在哪个组件
  • 定义添加评论函数(方法)
  • 传递给Add.vue
<template>
    <add :addComment="addComment "/>
</template>

<script>
  export default {
     
     
    methods:{
     
     
      // 添加评论
      addComment(comment){
     
     
        this.comments.unshift(comment);
      }
    },
  }
</script>

Add.vue

  • 给按钮添加事件 @click
  1. 检查输入的合法性
  2. 根据输入的数据,封装成一个comment对象
  3. 添加到comments中
  4. 清除输入
  • 从输入框拿数据 v-model
  • 定义data
  • 添加方法add
<template>
  <input type="text" class="form-control" placeholder="用户名" v-model="name">
  <textarea class="form-control" rows="6" placeholder="评论内容" v-model="content"></textarea>
  <button type="button" class="btn btn-default pull-right" @click="add">提交</button>
</template>

<script>
  export default {
     
     
    props:{
     
     
      addComment: {
     
      //完整的写法(指定属性名/属性值类型/属性必要性)
        type:Function,
        required: true
      }
    },
    data(){
     
      // 要从页面拿数据,用v-model 
      return {
     
     
        name: '',
        content: ''
      }
    },
    methods: {
     
     
      add(){
     
     
        // 1. 检查输入的合法性
        const name = this.name.trim();
        const content = this.content.trim();
        if(!name || !content){
     
     
          alert("姓名和内容不能为空");
          return;
        }
        // 2. 根据输入的数据,封装成一个comment对象
        const comment = {
     
     
          name,
          content
        };
        // 3. 添加到comments中
        this.addComment(comment);
        // 4. 清除输入
        this.name='';
        this.content='';
      }
    }
  }
</script>

5.3 动态交互——删除操作

App.vue

<template>
  <list :comments="comments" :deleteComment="deleteComment" />
</template>

<script>
  export default {
     
     
    methods:{
     
     
      deleteComment(index){
     
     
        this.comments.splice(index, 1);
      }
    },
</script>

List.vue

<template>
  <div class="col-md-8">
    <h3 class="reply">评论回复:</h3>
    <h2 v-show="comments.length===0">暂无评论,点击左侧添加评论!!!</h2>
    <ul class="list-group">
      <item v-for="(comment, index) in comments" :key="index" :comment="comment" :deleteComment="deleteComment" :index="index" />
    </ul>
  </div>
</template>

<script>
import Item from './Item.vue'
export default {
     
     
  //声明接收属性, 这个属性就会成为组件对象的属性
  props: ['comments',"deleteComment"],

  components: {
     
      Item },
}
</script>

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 {
     
     
  props:{
     
      // 指定属性名和属性值的类型
    comment: Object,
    deleteComment: Function,
    index: Number
  },
  methods: {
     
     
    deleteItem(){
     
     
      const {
     
     comment, index, deleteComment} = this;
      if(window.confirm(`确定删除${
       
       comment.name}吗?`)){
     
     
        deleteComment(index);
      }
    }
  }
}
</script>

项目代码:https://github.com/yk2012/vue_demo/tree/main/demo2_Comments

猜你喜欢

转载自blog.csdn.net/weixin_44972008/article/details/113484310
今日推荐