父传子
1、父组件使用子组件,子组件动态绑定父组件 data 里的数据
2、子组件使用 props 属性来接收 简写的方式直接写一个数组,全面的写法可以写一个对象,可以设置变量数据类型和默认值
<div id="app">
<child message="msg"></child>
</div>
<template id="child">
<div>
<!-- 同样也可以在 vm 实例中像 “this.message” 这样使用 -->
<h1>{{message}}</h1>
</div>
</template>
<script>
// 注册
Vue.component('child', {
// 声明 props,接收父组件传过来的值 msg
// 简写形式
// props: ['message'],
// 全面的写法,有默认值
props:{
message:{
type:String,
default:'默认值'
},
},
template: '#child'
})
// 创建根实例
new Vue({
el: '#app',
msg: 'hello!'
})
</script>
复制代码
子传父
1、子组件绑定事件例change
2、在子组件的 methods 属性中定义方法 change,在 change 方法中使用Vue里面的$emit方法发送一个自定义事件例如 childchange
3、在父组件中使用子组件时使用 @childchange="ctrl" 绑定自定义事件,触发父组件的ctrl方法
4、在父组件的 methods 属性中定义方法 ctrl,在父组件中的ctrl方法内把父组件的msg的值给改了
注意: 子组件的 data 必须是一个函数,如果这样写的和父组件一样 都是对象 会对父组件的data的内容造成污染,data采用函数的方式 会产生局部作用域 里面的数据是组件私有的不会对全局造成影响怎么获取数据呢?采用return 一个对象的方式来获取组件里面的数据
<!-- 父组件 -->
<div id="app">
<h1>这是父组件里面的msg:{{msg}}</h1>
<!-- 把msg传入给子组件 -->
<!-- 自定义事件不要写成驼峰命名 因为浏览器会全部解析成小写 -->
<child :cmsg="msg" :list="list" @childchange="ctrl" @listchange="listchange"/>
</div>
<!-- 子组件 -->
<template id="child">
<div>
<h1 @click="change">{{cmsg}}</h1>
<ul>
<!-- 点击li 改变相对应的li中的数据 改成 'xxxxxxx' -->
<li v-for="(v,i) in list" :key="i" @click="fn(i)" :style="{'textDecoration': v.flag?'line-through':''}">{{v.content}}</li>
</ul>
<h2>{{msg}}</h2>
</div>
</template>
<script src="./vue.min.js"></script>
<script>
new Vue({
el:"#app",
data:{
msg:"任务列表",
list:[]
},
methods:{
listchange(i){
console.log(i)
/* 先给数组的所有对象加上flag属性 值为false */
this.list.forEach(r=>{r.flag=false})
/* 再把选中的莫一项的flag改成true */
// this.list[i].flag = true;
/* ★vue2的缺陷 不可以给对象里面添加属性
可以添加 但是 页面不会渲染响应的结果 */
/* $set的三个参数 第一个参数是目标对象 this.list */
/* 第二个参数 是目标参数的索引 */
/* 第三个参数 是具体要修改的内容 */
this.$set( this.list, i,{content:this.list[i].content,flag:true})
console.log(this.list)
/* 第一种修改方法 */
// this.list[i].content = 'xxxxxx'
/* 数组的方法splice三个参数的作用 第一个是 索引从哪里开始
第二个是从当前的索引删除几个 第三个参数是 添加的内容*/
/* 第二种修改方法 */
// this.list.splice(i,1,{content:'xxxxx'})
/* 删除具体的某一个 */
// this.list.splice(i,1)
},
ctrl(v){
// console.log(v,b,c)
console.log(v.value1)
console.log(v.value2)
console.log(v.value3)
this.msg = v.value1;
}
},
created(){
setTimeout(()=>{
this.list = [{
content:"卷王涛涛长时间坐电脑面前导致腰间盘突出"
},{
content:"某学生深夜还在学习感动了老师"
},{
content:"某女同学上课打瞌睡影响了学习"
}]
},500)
},
components:{
child:{
template:"#child",
/* 子组件使用props使用cmsg来接收 简写的方式 */
// props:['cmsg','list']
/* 全面的写法 有默认值的写法 */
props:{
cmsg:{
type:String,
default:'默认值'
},
list:{
type:Array,
default:[{content:"xxxx"},{content:"xxxx"}]
}
},
/* 如果这样写的和父组件一样 都是对象 会对父组件的data的内容造成污染 */
// data:{
// msg:'我是child的人'
// }
/* data采用函数的方式 会产生局部作用域 里面的数据是组件私有的不会对全局造成影响
怎么获取数据呢?采用return 一个对象的方式来获取组件里面的数据 */
data:function(){
return {
msg:'我是child的人'
}
},
created(){
console.log(this.cmsg)
},
methods:{
fn(i){
this.$emit('listchange',i)
},
change(){
/* 在子组件里面直接改父组件的值 是不可以的
因为违反了 Vue里面的单向数据流的原理(类似于瀑布)
直接改在父组件里面的数据还是没有被改变*/
// this.cmsg = '子改父'
/* 子改父的步骤 */
/* ①使用Vue里面的$emit方法发送一个自定义事件childchange */
/* ②在组件上使用@childchange="ctrl" 绑定自定义事件 触发父组件的ctrl方法*/
/* ③在父组件中的ctrl方法内把父组件的msg的值给改了 */
/* 传多个可以在后面加参数 */
// this.$emit('childchange','子改父','baba','erzi')
this.$emit('childchange',{value1:'子改父',value2:'爸爸',value3:'儿子'})
}
}
}
}
})
/* 父组件有个数组格式如下
[{content:'xxxx'},{content:'xxxx'},{content:'xxxx'}]
传给子组件来渲染出来*/
</script>