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 相关文章推荐
jQuery不间断滚动效果(模拟百度新闻支持文字/图片/垂直滚动)
Feb 05 Javascript
jquery 跳到顶部和底部动画2句代码简单实现
Jul 18 Javascript
JavaScript设计模式之工厂模式和构造器模式
Feb 11 Javascript
jquery事件的ready()方法使用详解
Nov 11 Javascript
angularjs自定义ng-model标签的属性
Jan 21 Javascript
Bootstrap中表单控件状态(验证状态)
Aug 04 Javascript
微信小程序授权获取用户详细信息openid的实例详解
Sep 20 Javascript
微信上传视频文件提示(推荐)
Nov 22 Javascript
JS中实现浅拷贝和深拷贝的代码详解
Jun 05 Javascript
vue 解决数组赋值无法渲染在页面的问题
Oct 28 Javascript
JavaScript直接调用函数与call调用的区别实例分析
May 22 Javascript
VUE中setTimeout和setInterval自动销毁案例
Sep 07 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
SSI指令
2006/11/25 PHP
浅析php单例模式
2014/11/25 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
PHP抓取远程图片(含不带后缀的)教程详解
2016/10/21 PHP
CI框架入门之MVC简单示例
2016/11/21 PHP
php微信开发之关注事件
2018/06/14 PHP
js 数值项目的格式化函数代码
2010/05/14 Javascript
js类型检查实现代码
2010/10/29 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
jQuery简单验证上传文件大小及类型的方法
2016/06/02 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
angular json对象push到数组中的方法
2018/02/27 Javascript
Vue keepAlive 数据缓存工具实现返回上一个页面浏览的位置
2019/05/10 Javascript
小程序Request的另类用法详解
2019/08/09 Javascript
Vue实现多标签选择器
2019/11/28 Javascript
[56:18]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Pyramid将models.py文件的内容分布到多个文件的方法
2013/11/27 Python
python实现dict版图遍历示例
2014/02/19 Python
python中list循环语句用法实例
2014/11/10 Python
python中的迭代和可迭代对象代码示例
2017/12/27 Python
200 行python 代码实现 2048 游戏
2018/01/12 Python
Python按钮的响应事件详解
2019/03/04 Python
python 基于dlib库的人脸检测的实现
2019/11/08 Python
Python图像处理库PIL的ImageEnhance模块使用介绍
2020/02/26 Python
CSS3实现水平居中、垂直居中、水平垂直居中的实例代码
2020/02/27 HTML / CSS
拉夫劳伦爱尔兰官方网站:Ralph Lauren爱尔兰
2020/04/10 全球购物
如何用Java实现列出某个目录下的所有子目录
2015/07/20 面试题
土木工程专业自荐信
2013/10/04 职场文书
文明宿舍获奖感言
2014/02/07 职场文书
物流业务员岗位职责
2014/02/08 职场文书
合作意向协议书范本
2014/03/31 职场文书
2016年师德先进个人事迹材料
2016/02/29 职场文书
修辞手法有哪些?
2019/08/29 职场文书
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
2021/11/17 Servers
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技