利用Props可以进行组件之间数据传递(类似于React的Props)。
每一个组件都有作用域的限制,所以不可以在子组件内直接使用父组件的数据。
若要让子组件使用上父组件的数据,则必须通过子组件的Props选项。
静态Props
子组件要显式的使用props选项声明其所期待的数据:
在父组件之中,把数据传入:
<child message="hello">child>
从而在子组件中,声明props来接受传入的数据:
Vue.component('child', {
//声明了props
props: ['message'],
//就像data一样,prop也可以在模板之内使用
//同样也可以在vm实例中类似“this.message“这样使用
template: '<span>{{message}}span>'
}
)
注意:在声明props和插入节点的时候,利用驼峰命名,在HTML中使用-
进行连接。
在父组件中,把数据通过v-bind:msg
传入给子组件。
<template>
<div id="post">
<post-body :msg="msg">post-body>
div>
template>
<script>
import PostBody from './PostBody'
export default {
name: 'post',
data: () => ({
msg: '哈哈'
}),
components: { PostBody }
}
script>
在props中添加了元素之后,就不用再data中继续添加变量了,在子组件中,如何拿到传入的数据?
首先声明props,把得到的数据赋值给props,就可以直接渲染了。
<template>
<div class="post-body">
{{ msg }}
//渲染到页面上
div>
template>
<script>
export default {
name: 'post-body',
props: ['msg']
// 声明 props
}
script>
子组件主要是通过事件传递数据给父组件。
子组件:
首先声明了一个方法setnum,然后使用$emit
来遍历父组件传递过来的addnum事件,并且返回了字符串的数量:
<script>
export default {
name: 'post-body',
methods: {
setnum: function () {
this.$emit('addnum', '数量:')
}
}
}
script>
当按钮被点击的时候,会触发v-on:click
事件,调用绑定的setnum方法,并且把数据传递给父组件。
<template>
<div class="post-body">
<input type='button' value='+1' @click='setnum'/>
div>
template>
父组件:
在负组件中,利用addnum事件调用getnum方法,从而获取到子组件传递过来的参数string。
<template>
<div id="post">
<p>{{ str }}{{ num }}p>
<post-body @addnum='getnum'>post-body>
div>
template>
getnum 方法中的参数 str 就是从子组件传递过来的参数 string。
<script>
import PostBody from './PostBody
export default {
name: 'post',
data: () => ({
num: 0,
str:
}),
methods: {
getnum: function (str) {
this.str = str
this.num ++
}
},
components: { PostBody }
script>
这样点击子组件的+1
按钮,就可以做到父组件的显示的数值改变,并且完成 +1 的操作。
Vue没有直接向子对子传参的方法,建议把需要传递数据的子组件,合并成为一个组件,若一定需要子对子传参,则可以先传到父组件,传到子组件。
为了便于开发,Vue推出了一个状态管理的工具,乘坐Vuex
,可以方便实现组件之间的参数传递。
每一个Vue实例都会带起其data对象里的所有属性,相当于React的State。
data
注意:data必须是函数,这里的data只是一个特殊的原始属性。
var data = { a: 1 }
var vm = new Vue({
data: data
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
data.a = 3
vm.a // -> 3
注意只有这些被代理的属性是响应的,也就是说值的任何改变都是触发视图的重新渲染。如果在实例创 建之后添加新的属性到实例上,它不会触发视图更新。我们将在后面详细讨论响应系统。
除了data属性,Vue实例也暴露了一些有用的实例属性和方法,这些属性和方法都有前缀$
,用来和代理的data属性做区分,例如:
var data = { a: 1 }Properties and Methods
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
})
注意:不要在实例属性或者回调函数中使用箭头函数,因为箭头函数绑定父级上下文,所以this不会和预想的一样指向该vue实例。
vm.$watch('a', newVal => this.myMethod())
// this.myMethod 会是一个 undefined
data 数据写在 vue 实例里面,类型是一个 Function
<script>
export default {
name: 'comment-box',
data: () => ({
comments: [
{ text: 'hello git' },
{ text: 'hello vuejs' }
]
})
}
script>
data:
注意:因为箭头函数绑定了父级作用域的上下文,所以this指向不会指向到该Vue实例。
data: () => { return { a: this.myProp }}
// this.myProp 将会是 undefined
把需要运算的data数据放在computed中,然后进行渲染。
{ [key: string]: Function | { get: Function, set: Function } }
export default {
name: 'comment-box',
data: () => ({
comments: [
{ text: 'hello git' },
{ text: 'hello vuejs' }
]
}),
computed: {
reversedMessage: function () {
return this.comments.slice().reverse()
}
}
}
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果实例范畴之外的依赖 (比如非响应式的 not reactive) 是不会触发计算属性更新的。
vue的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进DOM。
数据绑定最常见的形式就是使用 “Mustache” 语法(双大括号)的文本插值:
<template>
<div class="comment-box">
{{ comment.text }}
div>
template>
Mustache 标签将会被替代为对应数据对象上 comment.text 属性的值。无论何时,绑定的数据对 象上 comment.text 属性发生了改变,插值处的内容都会更新。