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实现鼠标点击后层展开效果的方法
May 13 Javascript
使用Function.apply()的参数数组化来提高 JavaScript程序性能的技巧
Dec 23 Javascript
谈谈JavaScript的New关键字
Aug 26 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
Sep 01 Javascript
JS给按钮添加跳转功能类似a标签
May 30 Javascript
vue 中自定义指令改变data中的值
Jun 02 Javascript
pm2 部署 node的三种方法示例
Oct 20 Javascript
详解JS函数stack size计算方法
Jun 18 Javascript
解决vue-cli webpack打包后加载资源的路径问题
Sep 25 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
Jan 05 jQuery
VUE.js实现动态设置输入框disabled属性
Oct 28 Javascript
在vue中使用el-tab-pane v-show/v-if无效的解决
Aug 03 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验证手机号码(支持归属地查询及编码为UTF8)
2013/02/01 PHP
JSON PHP中,Json字符串反序列化成对象/数组的方法
2018/05/31 PHP
PHP基于session.upload_progress 实现文件上传进度显示功能详解
2019/08/09 PHP
精选的10款用于构建良好易用性网站的jQuery插件
2011/01/23 Javascript
jquery的ajax跨域请求原理和示例
2014/05/08 Javascript
js实现简单秒表走动的时钟特效
2020/03/25 Javascript
jQuery Html控件基本操作(日常收集整理)
2016/03/11 Javascript
js 作用域和变量详解
2017/02/16 Javascript
jQuery实现获取h1-h6标题元素值的方法
2017/03/06 Javascript
jQuery插件FusionCharts绘制2D柱状图和折线图的组合图效果示例【附demo源码】
2017/04/10 jQuery
node.js中fs.stat与fs.fstat的区别详解
2017/06/01 Javascript
基于Vue2x的图片预览插件的示例代码
2018/05/14 Javascript
json数据传到前台并解析展示成列表的方法
2018/08/06 Javascript
JavaScript作用域、闭包、对象与原型链概念及用法实例总结
2018/08/20 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【矩形情况】
2018/12/13 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
在vue中使用setInterval的方法示例
2019/04/16 Javascript
JS回调函数 callback的理解与使用案例分析
2019/09/09 Javascript
jquery实现商品sku多属性选择功能(商品详情页)
2019/12/20 jQuery
js实现网页随机验证码
2020/10/19 Javascript
[49:28]VP vs Optic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python 字典(dict)遍历的四种方法性能测试报告
2014/06/25 Python
Python中关于字符串对象的一些基础知识
2015/04/08 Python
Python编写一个优美的下载器
2018/04/15 Python
TensorFlow 滑动平均的示例代码
2018/06/19 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
python做接口测试的必要性
2019/11/20 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
2020/02/29 Python
Python json模块与jsonpath模块区别详解
2020/03/05 Python
Python读取VOC中的xml目标框实例
2020/03/10 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
2020/10/19 Python
军训的自我鉴定
2013/12/10 职场文书
五好党支部事迹材料
2014/02/06 职场文书
保护环境建议书
2014/03/12 职场文书
运动会加油稿
2015/07/22 职场文书
详解JS ES6编码规范
2021/05/07 Javascript