向子组件传递对象
使用v-bind形式向子组件传递对象:
<template><ul class="todo-main"><!-- 使用:todo,利用v-bind内容是js表达式的方式,将todoObj传递给子组件MyItem --><MyItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj"/></ul></template><script>import MyItem from './MyItem'export default {name:'MyList',components: {MyItem},data() {return {todos: [{id:'0001', title:'吃饭', done:true},{id:'0002', title:'睡觉', done:false},{id:'0003', title:'看电视', done:true},]}},}</script>
子组件接收对象,并进行显示:
<template><li><label><input type="checkbox" :checked="todo.done"/><span>{{todo.title}}</span></label><button class="btn btn-danger" style="display:none">删除</button></li></template><script>export default {name: 'MyItem',props:['todo'] // 接收父组件传入的对象}</script>
生成唯一流水号
可以使用UUID生成唯一流水号,但是UUID组件比较重,可以使用轻量版的nanoid代替:
npm i nanoid
用法:
import {nanoid} from 'nanoid'let id = nanoid();
调用父组件的方法,给父组件传值
父组件定义方法,并传递给子组件:
<template><div id="app"><div class="todo-container"><div class="todo-wrap"><!-- 将addTodo方法传递给子组件MyHeader --><MyHeader :addTodo="addTodo"/></div></div></div></template><script>import MyHeader from './components/MyHeader'export default {name: 'App',components: {MyHeader},data() {return {todos: [{id:'0001', title:'吃饭', done:true},{id:'0002', title:'睡觉', done:false},{id:'0003', title:'看电视', done:true},]}},methods: {// 定义addTodo方法addTodo(todo) {this.todos.unshift(todo)}}}</script>
子组件中接收函数,并在需要时调用:
<template><div class="todo-header"><input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="add"/></div></template><script>import {nanoid} from 'nanoid'export default {name:'MyHeader',props: ['addTodo'], // 接收父组件的addTodo方法methods: {add(e) {const todoObj = {id:nanoid(), title:e.target.value, done:false};// 调用父组件的addTodo方法,参数也可以通过父组件方法正常传递给父组件this.addTodo(todoObj);}}}</script>
复选框的操作
方式1:
使用:checked显示复选框是否被选中。使用@change绑定事件当选择状态变化时触发方法
<template><div class="todo-footer" v-show="total"><!-- 使用:checked显示当前复选框是否被选中。 当选中的状态改变时触发checkAll事件 --><input type="checkbox" :checked='isAll' @change="checkAll"/></div></template><script>export default {name:'MyFooter',computed: {// 定义计算属性isAll, 用来展示复选框是否被选中isAll() {return (this.total === this.checkedCount) && (this.total > 0);},},methods: {// 复选框选中或取消选择时触发该事件checkAll(e) {this.checkAllTodo(e.target.checked);}}}</script>
方式2:
使用v-model双向绑定:
<template><div class="todo-footer" v-show="total"><!-- 使用v-model进行双向绑定 --><input type="checkbox" v-model='isAll'/></div></template><script>export default {name:'MyFooter',computed: {// 使用计算属性的完整写法,给出getter/setterisAll: {get(){return (this.total === this.checkedCount) && (this.total > 0);},set(value) { // 获取复选框是否被选中this.checkAllTodo(value);}},}}</script>
总结
组件化编码流程:
- 拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突
实现动态组件:考虑好数据的存放位置,数据是一个组件在用还是一些组件在用:
- 一个组件在用:放在组件自身即可
- 一些组件在用:放在他们共同的父组件上(即状态提升)
- 实现交互:从绑定事件开始
props适用于:
- 父组件到子组件的通信
- 子组件到父组件的通信(要求父组件先给子组件传递一个函数)
使用v-model是要注意:v-model绑定的值不能是props传过来的值,因为props是不可以修改的
props传过来的值如果是对象类型的值,修改对象中的属性时vue不会报错,但是不推荐这么做。
