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 相关文章推荐
Javascript----文件操作
Jan 18 Javascript
javascript 控制弹出窗口
Apr 10 Javascript
如何使用jQuery Draggable和Droppable实现拖拽功能
Jul 05 Javascript
javascript中动态加载js文件多种解决办法总结
Nov 15 Javascript
jQuery animate easing使用方法图文详解
Jun 17 Javascript
Bootstrap Table使用方法详解
Aug 01 Javascript
JavaScript中省略元素对数组长度的影响
Oct 26 Javascript
浅谈JavaScript的自动垃圾收集机制
Dec 15 Javascript
浅析javaScript中的浅拷贝和深拷贝
Feb 15 Javascript
微信小程序实现运动步数排行功能(可删除)
Jul 05 Javascript
对angularJs中$sce服务安全显示html文本的实例
Sep 30 Javascript
vue 实现特定条件下绑定事件
Nov 09 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
把77A收信机改造成收音机
2021/03/02 无线电
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
服务器端解压缩zip的脚本
2006/12/22 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
2014/11/17 PHP
Linux系统递归生成目录中文件的md5的方法
2015/06/29 PHP
PHP封装curl的调用接口及常用函数详解
2018/05/31 PHP
JavaScript DOM学习第八章 表单错误提示
2010/02/19 Javascript
再次分享18个非常棒的jQuery表格插件
2011/04/10 Javascript
js在指定位置增加节点函数insertBefore()用法实例
2015/01/12 Javascript
JavaScript中的setUTCDate()方法使用详解
2015/06/11 Javascript
JS实现选择TextArea内文本的方法
2015/08/03 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
JS日程管理插件FullCalendar简单实例
2017/02/07 Javascript
angularjs实现过滤并替换关键字小功能
2017/09/19 Javascript
详解如何优雅地在React项目中使用Redux
2017/12/28 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
对angular 实时更新模板视图的方法$apply详解
2018/10/09 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
Element Collapse 折叠面板的使用方法
2020/07/26 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
2020/07/31 Javascript
Python 文件和输入输出小结
2013/10/09 Python
Python 列表(List)操作方法详解
2014/03/11 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
对dataframe数据之间求补集的实例详解
2019/01/30 Python
Python基础之字符串常见操作经典实例详解
2020/02/26 Python
django model通过字典更新数据实例
2020/04/01 Python
Mamas & Papas沙特阿拉伯:英国最受欢迎的婴儿品牌
2017/11/20 全球购物
Fenty Beauty官网:蕾哈娜创立的美妆品牌
2021/01/07 全球购物
幼儿园开学家长寄语
2014/01/19 职场文书
建议书怎么写
2014/03/12 职场文书
倡议书作文
2015/01/19 职场文书
客房服务员岗位职责
2015/02/09 职场文书
招商银行收入证明
2015/06/17 职场文书
实习员工转正的评语汇总,以备不时之需
2019/12/17 职场文书
Python实现仓库管理系统
2022/05/30 Python
numpy array找出符合条件的数并赋值的示例代码
2022/06/01 Python