《Vue.js实战》一书 p183 练习 1& 2 试做源代码

练习1 : 给每条留言都增加一个删除的功能。
练习2 :将该示例的render 写法改写为template 写法,加以对比,总结出两者的差异性,深刻理解其使用场景。

Demo在线效果浏览

IDE:VScode

项目构成:app.vue vinput.vue, vtextarea.vue, list.vue. style.css

app.vue

<template>
  <div id="app" v-cloak style="500px; margin:0 auto;">
    <div class="message">
      <v-input v-model="username"></v-input>
      <v-textarea v-model="message" ref="message"></v-textarea>
      <button @click="handleSend">发布</button>
    </div>
    <list :list="list" @reply="handleReply" @del="handleDel"></list>
  </div>
</template>
<script>
import vInput from './components/vinput';
import vTextarea from './components/vtextarea';
import list from './components/list';
export default {
  name:'app',
  components:{
    vInput,
    vTextarea,
    list
  },
  data(){
    return{
      username:'',
      message:'',
      list:[]
    }    
  },
  methods:{
    handleSend(){
      if(this.username===''){
        window.alert('请输入昵称');
        return;
      }
      if(this.message===''){
        window.alert('请输入留言内容');
        return;
      }
      this.list.push({
        name:this.username,
        message:this.message
      });
      this.message='';
    },
    handleReply(index){
      var name=this.list[index].name;
      this.message='回复@'+name+': ';
      this.$refs.message.focus();
    },
    handleDel(index){
      this.list.splice(index,1);
    }
  }
}
</script>

vinput.vue

<template>
    <div>
        <span>昵称</span>
        <input :value="value" @input="handleInput">
    </div>
</template>
<script>
export default {
    props:{
        value:{
            type:[String,Number],
            default:''
        }
    },
    methods:{
        handleInput(event){
            this.$emit('input',event.target.value);
        }
    }
}
</script>

vtextarea.vue

<template>
    <div>
        <span>留言内容</span>
        <textarea :value="value" @input="handleInput" ref="message"></textarea>
    </div>
</template>
<script>
export default {
    props:{
        value:{
            type:String,
            default:''
        }
    },
    methods:{
        handleInput(event){
            this.$emit('input',event.target.value);
        },
        focus(){
            this.$refs.message.focus();
        }
    }

}
</script>

list.vue

<template>
    <div v-if="list.length" class="list">
        <div v-for="(msg, index) in list" :key="index" class="list-item">
            <span>{{msg.name +': '}} </span>
            <div class="list-msg">
                <p>{{msg.message}}</p>
                <a class="list-reply" @click="handleReply(index)">回复</a>
                <a class="list-del" @click="handleDel(index)">删除</a>
            </div>
        </div>
    </div>
    <div v-else class="list-nothing">
        留言内容为空
    </div>
</template>
<script>
export default {
    props:{
        list:{
            type:Array,
            default:function(){
                return []
            }
        }
    },
    methods:{
        handleReply(index){
            this.$emit('reply',index);
        },
        handleDel(index){
            this.$emit('del',index);
        }
    }
}
</script>
原文地址:https://www.cnblogs.com/sx00xs/p/11380734.html