Vue从TodoList中学父子组件通信


Posted in Javascript onFebruary 05, 2019

简单的 TodoList

实现一个简单的 todolist,当我输入内容后,点击提交自动添加在下面,如下图所示:

Vue从TodoList中学父子组件通信

用代码实现这个效果:

<div id="app">
  <input type="text" v-model="inputVal">
  <button v-on:click="clickBtn">提交</button>
  <ul>
    <li v-for="item in list">{{item}}</li>
  </ul>
</div>
<script>
  let vm = new Vue({
    el:'#app',
    data:{
      list:[],
      inputVal:''
    },
    methods:{
      clickBtn(){
        this.list.push(this.inputVal)
        inputVal = ''
      }
    }
  })
</script>

当我在input框中输入内容后,点击提交,Vue 会自动将内容渲染在页面中,具体是怎么实现的呢?

我们都知道 Vue 是一个 MVVM 框架,让开发者专注于数据变更,无需关注 Dom,所以它的核心是VM层,也就是说渲染这部分不需要开发者考虑了。

循环v-for

v-for指令是 Vue 提供的api,可以实现循环添加

v-for="item in list"

将list中数据循环添加到页面中,值为item

所以当我点击提交时,只需要获取到输入框中的值,然后push到list中,我们看到的效果就是一个个添加。

绑定v-model

如何获取输入框中的值变成了一个问题,没用 Vue 之前,获取输入框中的值,非常简单,用$(input).val()就能轻松获取。

用了 Vue 之后,不应该操作 Dom 来获取值,Vue 肯定也考虑到这点了,提供了一个api

v-model="inputVal"

第一次用这个指令时,踩了一个坑,我在inputVal两边加上了双括号,从而导致页面中没任何反应,这边是不需要加双括号的。渲染模版时才需要用 Vue 提供的模版字符串

一个简单的 TodoList 就已经实现了。

组件化

每个li其实都是一个组件,我们可以用组件的形式来开发

全局组件:

<div id="app">
  <input type="text" v-model="inputVal">
  <button v-on:click="clickBtn">提交</button>
  <ul>
    <todo-list v-for="item in list"
          v-bind:content="index"
    ></todo-list>
  </ul>
</div>
<script>
  Vue.component('TodoLsit',{
    props:['content'],
    template:`<li>{{content}}</li>`,
  })
  let vm = new Vue({
    el: '#app',
    data: {
      list: [],
      inputVal: ''
    },
    methods: {
      clickBtn() {
        this.list.push(this.inputVal)
        this.inputVal = ''
      }
    }
  })
</script>

用 Vue 提供的component创建组件可创建一个全局组件,组件的名字TodoList在模版中需要用todo-list来实现,大小变小写,中间用-连接。

局部组件:

<button v-on:click="clickBtn">提交</button>
  <ul>
    <todo-list v-for="item in list"
         v-bind:content="item"
    ></todo-list>
  </ul>
</div>
<script>
  let TodoList = {
    props:['content'],
    template: `<li>{{content}}</li>`,
  }
  let vm = new Vue({
    el: '#app',
    data: {
      list: [],
      inputVal: ''
    },
    component:{   //注册组件
     TodoList 
    },
    methods: {
      clickBtn() {
        this.list.push(this.inputVal)
        this.inputVal = ''
      }
    }
  })
</script>

使用局部组件,声明一个对象,内容和全局组件一样,不过需要再 Vue 中注册一下,使用component属性注册

component:{
  TodoList
}

用了组件后之后,就会涉及到数据通信,一般有两种:

  • 组件中如何才能拿到外面的数据
  • 组件中数据变化,外面如何知道

父 -> 子组件通信

现在已经用组件实现上面的功能了,但是组件中还没有数据,如果将我输入框中的数据传递给子组件。

子组件中获取数据,还是用v-for循环,用v-bind绑定需要的数据,组件中用props获取绑定的数据

<todo-list v-for="(item,index) in list"
      v-bind:content="item"
      v-bind:index="index"
      v-on:delete="handleItemDelete"
></todo-list>

let TodoList = {
  props:['content'],
  template: `<li>{{content}}</li>`,      // content 就是相关数据
}

父 -> 子组件通信实现了往组件里面添加数据,如果子组件中要删除一项,应该怎么操作呢?

子 -> 父组件通信

子 -> 父组件通信,Vue 提供了一个$emit()方法,组件中使用v-on指令可绑定事件

<div id="app">
  <input type="text" v-model="inputVal">
  <button v-on:click="clickBtn">提交</button>
  <ul>
    <todo-list v-for="(item,index) in list"
         v-bind:item="item"
         v-bind:index="index"
         v-on:delete="handleItemDelete"
    ></todo-list>
  </ul>
</div>
<script>
  Vue.component('TodoList',{
   props:['item', 'index'],
   template: `<li v-on:click="handleItemClick">{{item}}</li>`,
   methods: {
     handleItemClick() {
       this.$emit('delete', this.index)
     }
   }
  })
  let vm = new Vue({
    el: '#app',
    data: {
      list: [],
      inputVal: ''
    },
    methods: {
      clickBtn() {
        this.list.push(this.inputVal)
        this.inputVal = ''
      },
      handleItemDelete(index) {
        this.list.splice(index, 1)
      }
    }
  })
</script>

组件中绑定事件,第一个参数是事件名,第二个参数是要传递给父元素的参数

template: '<li v-on:click="handleItemClick">{{item}}</li>'' //绑定事件为 click,需要执行的函数是 handleItemClick

methods: {                 //写在组件里面
  handleItemClick() {
    this.$emit('delete', this.index) 
  }
}

父元素监听事件

<todo-list v-for="(item,index) in list"
      v-bind:item="item"
      v-bind:index="index"
      v-on:delete="handleItemDelete"  //监听 delete 事件, 执行函数是 handleItemDelete
></todo-list>

handleItemDelete(index) {          //写在 Vue 实例中
  this.list.splice(index, 1)
}

通过父子组件之间的通信,就可以实现 父->子 子->父 之间数据传输问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JTrackBar水平拖动效果
Jul 15 Javascript
HTML Dom与Css控制方法
Oct 25 Javascript
表单序列化与jq中的serialize使用示例
Feb 21 Javascript
浅谈jquery回调函数callback的使用
Jan 30 Javascript
jQuery对JSON数据进行排序输出的方法
Jun 24 Javascript
jQuery实现背景滑动菜单
Dec 02 Javascript
bootstrap提示标签、提示框实现代码
Dec 28 Javascript
js, jQuery实现全选、反选功能
Mar 08 Javascript
bootstrapvalidator之API学习教程
Jun 29 Javascript
Vue v-model组件封装(类似弹窗组件)
Jan 08 Javascript
vue项目或网页上实现文字转换成语音播放功能
Jun 09 Javascript
vue+axios全局添加请求头和参数操作
Jul 24 Javascript
详解webpack编译速度提升之DllPlugin
Feb 05 #Javascript
基于Webpack4和React hooks搭建项目的方法
Feb 05 #Javascript
利用Dectorator分模块存储Vuex状态的实现
Feb 05 #Javascript
小程序页面动态配置实现方法
Feb 05 #Javascript
PHP实现基于Redis的MessageQueue队列封装操作示例
Feb 02 #Javascript
AngularJS实现的自定义过滤器简单示例
Feb 02 #Javascript
vue实现的树形结构加多选框示例
Feb 02 #Javascript
You might like
PHP文件去掉PHP注释空格的函数分析(PHP代码压缩)
2013/07/02 PHP
使用配置类定义Codeigniter全局变量
2014/06/12 PHP
js获取单选按钮的数据
2006/11/27 Javascript
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
DWR Ext 加载数据
2009/03/22 Javascript
jQuery获取对象简单实现方法小结
2014/10/30 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
javascript制作的滑动图片菜单
2015/05/15 Javascript
使用Chart.js图表库制作漂亮的响应式表单
2015/10/28 Javascript
JavaScript setTimeout使用闭包功能实现定时打印数值
2015/12/18 Javascript
JavaScript的this关键字的理解
2016/06/18 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
JS实现简单的浮动碰撞效果示例
2017/12/28 Javascript
用jquery获取select标签中选中的option值及文本的示例
2018/01/25 jQuery
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
webpack file-loader和url-loader的区别
2019/01/15 Javascript
详解微信小程序用定时器实现倒计时效果
2019/04/30 Javascript
详解微信小程序回到顶部的两种方式
2019/05/09 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
[00:23]DOTA2群星共贺开放测试 25日无码时代来袭
2013/09/23 DOTA
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python base64编码解码实例
2015/06/21 Python
在Python的Django框架中为代码添加注释的方法
2015/07/16 Python
python+opencv实现阈值分割
2018/12/26 Python
python opencv圆、椭圆与任意多边形的绘制实例详解
2020/02/06 Python
什么是python的自省
2020/06/21 Python
Python 操作 MySQL数据库
2020/09/18 Python
python实现代码审查自动回复消息
2021/02/01 Python
html5应用缓存_动力节点Java学院整理
2017/07/13 HTML / CSS
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
linux面试题参考答案(1)
2016/01/22 面试题
在校学生职业规划范文
2014/01/08 职场文书
市场策划求职信
2014/08/07 职场文书
干部个人对照检查材料
2014/08/25 职场文书
倡议书的写法
2014/08/30 职场文书
乡镇防汛工作汇报
2014/10/28 职场文书