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 相关文章推荐
经典的解除许多网站无法复制文字的绝招
Dec 31 Javascript
Jquery easyUI 更新行示例
Mar 06 Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
Mar 02 Javascript
javascript模拟C#格式化字符串
Aug 26 Javascript
jQuery实现的简单分页示例
Jun 01 Javascript
JavaScript Ajax编程 应用篇
Jul 02 Javascript
AngularJs页面筛选标签小功能
Aug 01 Javascript
JavaScript实战之菜单特效
Aug 16 Javascript
vue 实现通过手机发送短信验证码注册功能
Apr 19 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
Sep 07 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
Sep 03 Javascript
JavaScript前端开发时数值运算的小技巧
Jul 28 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获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
php获取字段名示例分享
2014/03/03 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
PHP扩展开发教程(总结)
2015/11/04 PHP
微信支付PHP SDK ―― 公众号支付代码详解
2016/09/13 PHP
php记录搜索引擎爬行记录的实现代码
2018/03/02 PHP
初学Javascript的一些总结
2008/11/03 Javascript
jQuery中需要注意的细节问题小结
2011/12/06 Javascript
showModalDialog在谷歌浏览器下会返回Null的解决方法
2013/11/27 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
基于javascript实现浏览器滚动条快到底部时自动加载数据
2015/11/30 Javascript
浏览器兼容的JS写法总结
2016/04/27 Javascript
15位和18位身份证JS校验的简单实例
2016/07/18 Javascript
webpack 1.x升级过程中的踩坑总结大全
2017/08/09 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
2017/08/31 Javascript
jquery鼠标悬停导航下划线滑出效果
2017/09/29 jQuery
Vue框架下引入ActiveX控件的问题解决
2019/03/25 Javascript
[01:00:14]DOTA2-DPC中国联赛 正赛 Ehome vs Elephant BO3 第二场 2月28日
2021/03/11 DOTA
python中字符串前面加r的作用
2015/06/04 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
Python入门之三角函数全解【收藏】
2017/11/08 Python
Python反射的用法实例分析
2018/02/11 Python
Python3实现的简单工资管理系统示例
2019/03/12 Python
python实现字符串加密 生成唯一固定长度字符串
2019/03/22 Python
代码总结Python2 和 Python3 字符串的区别
2020/01/28 Python
python opencv进行图像拼接
2020/03/27 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
金融专业个人的自我评价
2013/10/18 职场文书
三个儿子教学反思
2014/02/03 职场文书
班主任班级寄语大全
2014/04/04 职场文书
寄语学生的话
2014/04/10 职场文书
浅谈Python基础之列表那些事儿
2021/05/11 Python
利用python调用摄像头的实例分析
2021/06/07 Python
vue中的可拖拽宽度div的实现示例
2022/04/08 Vue.js