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 相关文章推荐
统一接口:为FireFox添加IE的方法和属性的js代码
Mar 25 Javascript
Firefox+FireBug使JQuery的学习更加轻松愉快
Jan 01 Javascript
jquery1.5.1中根据元素ID获取元素对象的代码
Apr 02 Javascript
node.js中的fs.writeFile方法使用说明
Dec 14 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
js淡入淡出的图片轮播效果代码分享
Aug 24 Javascript
JavaScript设计模式之单体模式全面解析
Sep 09 Javascript
浅析JS中对函数function的理解(基础篇)
Oct 14 Javascript
基于mpvue的小程序项目搭建的步骤
May 22 Javascript
JS Math对象与Math方法实例小结
Jul 05 Javascript
element-ui点击查看大图的方法示例
Dec 14 Javascript
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
详解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
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
在windows平台上构建自己的PHP实现方法(仅适用于php5.2)
2013/07/05 PHP
在Yii2特定页面如何禁用调试工具栏Debug Toolbar详解
2017/08/07 PHP
php使用json-schema模块实现json校验示例
2019/09/28 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
2020/02/12 PHP
javascript判断office版本示例
2014/04/11 Javascript
jQuery解析XML与传统JavaScript方法的差别实例分析
2015/03/05 Javascript
Spring mvc 接收json对象
2015/12/10 Javascript
jquery中ajax处理跨域的三大方式
2016/01/05 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
JS实现的简单轮播图运动效果示例
2016/12/22 Javascript
vue2.0中goods选购栏滚动算法的实现代码
2017/05/17 Javascript
React-router中结合webpack实现按需加载实例
2017/05/25 Javascript
如何在Angular应用中创建包含组件方法示例
2019/03/23 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
linux 下以二进制的方式安装 nodejs
2020/02/12 NodeJs
python实现定时播放mp3
2015/03/29 Python
在Python中使用HTML模版的教程
2015/04/29 Python
Python的Django框架中的URL配置与松耦合
2015/07/15 Python
Python使用requests及BeautifulSoup构建爬虫实例代码
2018/01/24 Python
python中几种自动微分库解析
2019/08/29 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
全球知名旅游社区法国站点:TripAdvisor法国
2016/08/03 全球购物
英国健身超市:Fitness Superstore
2019/06/17 全球购物
英国自行车商店:AW Cycles
2021/02/24 全球购物
团日活动策划书
2014/02/01 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
司仪主持词两篇
2014/03/22 职场文书
庆元旦文艺演出主持词
2014/03/27 职场文书
对孩子的寄语
2014/04/09 职场文书
深入详解JS函数的柯里化
2021/06/09 Javascript
Python办公自动化之教你如何用Python将任意文件转为PDF格式
2021/06/28 Python
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL
Spring JPA 增加字段执行异常问题及解决
2022/06/10 Java/Android