目录
4.$children $parent 非响应式 作为访问组件的应急方法
1.props 父组件向子组件传值
1.在子组件标签上绑定一个自定义属性 自定义属性值为要传递的数据
<child :zdy='user' :good='goods'></child>
2.在子组件对象中使用 prop属性 来接收父组件传递过来的自定义属性
props: {
num: Object,
// 验证多个数据类型
str: {
type: [String, Number]
})
3.使用props属性接收的自定义属性使用方式和data中数据使用方式一样
当需要验证自定义属性数据时,props可以为一个对象 当props属性为一个数组时,表示可以接收任意数据类型 当props属性为一个对象时,表示需要对接收的自定义属性进行数据类型校验
父组件 完整代码
<div id="app">
<!-- 在子组件标签上绑定一个自定义属性 自定义属性值为要传递的数据 -->
<child :zdy='user' :good='goods'></child>
</div>
<template id="child">
<div class="cc">
<h1>我是子组件</h1>
<h3>props接收的自定义属性 {{zdy}} {{good}}</h3>
<mya :nums='num'></mya>
</div>
</template>
<template id="a">
<div>
<h1>我是a组件{{nums}}</h1>
</div>
</template>
</body>
<script src="../vue.js"></script>
<script>
let a = {
template: "#a",
props: ["nums"]
}
let child = {
template: '#child',
props: ['zdy', 'good'],
components: {
"mya": a
},
data() {
return {
num: 0
}
}
}
new Vue({
el: "#app",
data: {
user: "roy",
goods: {
name: "水杯",
price: 12
}
},
components: {
child
},
})
</script>
子组件 完整代码
<body>
<div id="app">
<child :num='num' :str='str'></child>
</div>
<template id="child">
<div>
<h1>我是子组件 {{num}} {{str}} {{like}}</h1>
</div>
</template>
</body>
<script src="../vue.js"></script>
<script>
let child = {
template: '#child',
props: {
num: Object,
// 验证多个数据类型
str: {
type: [String, Number]
},
// 若props接收不到属性时,可以设置一个默认值
like: {
type: String,
// 设置默认值
default: function () {
return "打篮球"
}
}
}
}
Vue.component('child', child);
new Vue({
el: "#app",
data: {
num: {
user: "张三"
},
str: '1',
like: ""
}
})
</script>
2.$emit $on 子组件向父组件传值
使用$emit属性向父组件发送一个自定义事件 参数一自定义事件名称 参数二要传递的数据 参数三要传递的数据.... 参数可以是任意数据类型
this.$emit('getmsg', this.msg, this.name, this.goods)
在父组件中 绑定一个子组件发送过来的自定义事件 自定义事件不可以有大写字母
<child @getobj='getmsg'></child>
父组件 完整代码
<body>
<div id="app">
<my-parent></my-parent>
</div>
<!-- 子组件 -->
<template id="par">
<!-- 在组件模板中有且只能有一个根元素 -->
<div>
<h2>评论人:</h2>
<input type="text" v-model='name'>
<h2>评论内容:</h2>
<textarea rows="10" v-model='content'></textarea>
<button @click='send()'>发表</button>
</div>
</template>
<!-- 父组件 -->
<template id="child">
<div>
<!--1. 子组件 绑定自定义事件接受参数 @getobj='getmsg' -->
<child @getobj='getmsg'></child>
<h1>留言板</h1>
<div>
<div v-for='(item,index) in list' class="list">
<div>
作者:{{item.name}}
</div>
<div>
内容:{{item.content}}
<button class="remove" @click='remove(index)'>删除</button>
<div style="clear: both;"></div>
</div>
</div>
<p v-show='list.length==0'>
暂无数据~~~
</p>
</div>
</div>
</template>
</body>
<script src="../vue.js"></script>
<script>
let child = {
template:"#par",
data() {
return {
name:"",
content:"",
obj:{}
}
},
methods: {
send(){
this.obj = {
name:this.name,
content:this.content
}
//2. 发送自定义事件
this.$emit('getobj', this.obj);
this.name='';
this.content = ''
}
},
}
let parent = {
template:"#child",
components:{
child
},
data() {
return {
list:[
{
name:"小明",
content:"小明是个帅哥"
},{
name:"小红",
content:"小红是个美女"
}
],
}
},
methods: {
// 3. 接收信息
getmsg(value){
console.log(value)
this.list.push(value)
},
remove(index){
this.list.splice(index,1)
}
},
}
// 小驼峰命名的组件名称使用时大写变小写并用-连接
Vue.component("myParent",parent)
new Vue({
el:"#app",
data:{
},
})
</script>
3.$bus 非父子组件传值
1.创建一个新的vue实例 bus.js
let bus = new Vue();
2.在组件中使用新的vue实例$emit发送自定义事件
bus.$emit("getobj",this.obj)
3.在要接受数据的组件中使用新的vue实例$on方法监听自定义事件调用
bus.$on("getobj",(value)=>{
console.log(value)
this.list.push(value)
})
非父子 完整代码
<body>
<div id="app">
<my-parent></my-parent>
<child></child>
</div>
<template id="par">
<!-- 在组件模板中有且只能有一个根元素 -->
<div>
<h2>评论人:</h2>
<input type="text" v-model='name'>
<h2>评论内容:</h2>
<textarea rows="10" v-model='content'></textarea>
<button @click='send()'>发表</button>
</div>
</template>
<template id="child">
<div>
<h1>留言板</h1>
<div>
<div v-for='(item,index) in list' class="list">
<div>
作者:{{item.name}}
</div>
<div>
内容:{{item.content}}
<button class="remove" @click='remove(index)'>删除</button>
<div style="clear: both;"></div>
</div>
</div>
</div>
</div>
</template>
</body>
<script src="../vue.js"></script>
<script>
// 1.定义一个新的vue实例
let bus = new Vue();
let child = {
template:"#child",
props:["msg"],
data() {
return {
list:[
{
name:"小明",
content:"小明是个帅哥"
},{
name:"小红",
content:"小红是个美女"
}
],
}
},
created() {
// 3. $on监听自定义事件
bus.$on("getobj",(value)=>{
console.log(value)
this.list.push(value)
})
},
methods: {
remove(index){
this.list.splice(index,1)
}
},
}
let parent = {
template:"#par",
data() {
return {
name:"",
content:"",
obj:{}
}
},
methods: {
send(){
this.obj = {
name:this.name,
content:this.content
};
// 2. $emit发送自定义事件
bus.$emit("getobj",this.obj)
}
},
}
// 小驼峰命名的组件名称使用时大写变小写并用-连接
Vue.component("myParent",parent)
Vue.component("child",child)
new Vue({
el:"#app",
data:{
},
})
</script>
4.$children $parent 非响应式 作为访问组件的应急方法
$children 获取当前组件的所有子组件,以数组形式存在,从而可以操作子组件数据
this.$children.属性名 = ...
$parent 获取当前组件的父组件,从而可以操作父组件数据
如果组件没有父组件,他的$parent为undefined,App组件(根组件)的$parent不是undefined,也不是App本身。
如果组件有多个父亲,$parent只能找到一个
this.$parent.属性名 = ...
父组件
<template>
<div style="background-color: #999">
<h2>儿子金钱:{{ sonMoney }}</h2>
<button @click="giveFatherMoney(100)">给父亲100</button>
</div>
</template>
<script>
export default {
name: "Son",
props: ["fatherMoney"],
data() {
return {
sonMoney: 20000,
};
},
methods: {
giveFatherMoney(money) {
this.$parent.fatherMoney += money;
this.sonMoney -= money;
},
},
};
</script>
<style>
</style>
5.ref
ref
被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs
对象上
组件元素只能通过 ref 获取的标签方法、变量、.... ;
普通的元素标签可以使用 ref或者id或者... 获取标签 ;
使用方法:this.$refs.名称
<button ref="qw"> //子组件
this.$refs.qw = ... // 父组件
6.$attrs $listeners
$attrs
与$listeners
的主要应用是实现多层嵌套传递。
1.$attrs 组件的一个属性,可以获取到父组件传递过来的props数据,和props作用一样
console.log(this.$attrs) == props:["数据"]
不能获取class、
style
和事件属性,在嵌套层级比较深的组件中$attr
s拿值更加便捷,可以通过 v-bind="$attrs"
传入内部组件
<child-com class="com" name="attr" :foo="foo" :boo="boo" @click="test"></child-com>
...
data() {
return {
foo: 'Hello World!',
boo: 'Hello Javascript!',
}
},
...
// child-com.vue
export default {
name: 'childCom',
components: {
childCom2
},
created() {
console.log(this.$attrs)
// {name: "attr", foo: "Hello World!", boo: "Hello Javascript!"}
}
}
$attrs
只代表的是那些没有被声明为props
的属性,如果某个prop
被子组件中声明了(就是这个属性已经在子组件的props中了),在子组件中的$attr
会把声明的prop
剔除
<child-com class="com" name="attr" :foo="foo" :boo="boo" @click="test"></child-com>
...
data() {
return {
foo: 'Hello World!',
boo: 'Hello Javascript!',
}
},
...
// child-com.vue
export default {
name: 'childCom',
props: ['foo'], // foo被声明
components: {
childCom2
},
created() {
console.log(this.$attrs)
// {name: "attr", boo: "Hello Javascript!"}
// foo已被props声明,所以$attrs拿不到foo
}
}
2.$listeners 属于组件的一个属性,可以获取到父组件传递过来的事件(如点击事件等)
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
通过在自己的子组件上使用v-on=$listeners”
,进一步把值传给自己的子组件。如果子组件已经绑定$listene
r中同名的监听器,则两个监听器函数会以冒泡的方式先后执行。
父组件 完整代码
<template>
<div class="test">
<child v-bind="{name, sex, age}" v-on="{changeName,changeAge}"></child>
</div>
</template>
<script>
import child from './child'
export default {
data() {
return {
name: '张三',
sex: '男',
age: 11,
}
},
components: {
child
},
methods: {
changeName(name) {
this.name = name
},
changeAge(age) {
this.age = age
}
}
}
</script>
子组件 完整代码
<template>
<div class="child">
child组件的$attrs {{$attrs}}
// v-bind v-on 不能替换为 : 和 @
<child-child v-bind="$attrs" v-on="$listeners" @showAttrs="showAttrs"></child-child>
</div>
</template>
<script>
import childChild from './child-child'
export default {
name: "child",
props: ['name'],
inheritAttrs: false,
created() {
console.log('child', this.$listeners)
},
components: {
childChild
},
methods: {
showAttrs() {
console.log(this.$attrs)
}
}
}
</script>
孙组件 完整代码
<template>
<div class="child-child">
child-child组件的$attrs {{$attrs}}
</div>
</template>
<script>
export default {
name: "child-child",
inheritAttrs: false,
created() {
console.log('child-child',this.$listeners)
}
}
</script>
7. .sync属性修饰符
父组件监听子组件更新props的请求,实现父子组件的数据同步
1.在父组件中的子组件添加: :child-value.sync ='value'
<table-case
:child-value.sync ='value'
// :case-list.sync="solutionInfo.caseListJson"
/>
2.Vue看到 .sync关键字会自动为子组件创建一个叫做 update:childValue或update:child-value的事件,(这两种事件名都可以成功调用) 这个事件可以接受参数,并自动将参数赋给父组件的 value
3.在子组件想要修改时使用$emit触发事件并传入新的值,让父组件进行修改
<button @click="$emit("update:child-value","要改变的数据")"></button>
// this.$emit("update:case-list" , "要改变的数据")
8.$event 事件
获取原生DOM事件的事件对象
在DOM事件的回调函数中传入参数$event(@change="updateProduct($event)")
,可以获取到该事件的事件对象
<button data-get="数据按钮" @click="getRvent($event)">获取事件对象</button>
//script中 获取事件对象event
getRvent(e){
console.log(e);
// e.srcElement.style.background="red";
}
9.v-model 双向数据绑定
数据改变视图更新,视图更新数据改变
双向数据绑定v-model 只能作用在表单标签中!!!!!!
v-model实质上就是v-bind和v-on的一个语法糖
不使用v-model实现双向数据绑定的过程:
1.绑定一个value属性(v-bind(:))
2.绑定一个input事件(v-on(@))
<body>
<div id="app">
<input type="text" v-model="msg">
<!-- 输入框内容发生改变 改变data中的数据 -->
<p>{{msg}}</p>
</div>
</body>
<script src="../vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
msg:"roy"
}
})
</script>