局部组件与全局组件
局部组件
// 这是一个局部组件
const App = {
template: `
<div>
<h3>{{msg}}</h3>
<button @click="handleClick">按钮</button>
</div>
`,
// 组件中的data必须是一个函数,并返回一个对象,避免数据冲突
data() {
return {
msg: 'App组件'
}
},
methods: {
handleClick() {
this.msg = 'App组件Changed'
}
}
}
new Vue({
el: "#app",
data: {
},
components: {
// 在此处挂载子组件
// 等价于App:App
App
}
})
全局组件
使用Vue.component
创建的组件是全局注册的,它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue
) 的模板中
<body>
<div id="app">
<App></App>
<!-- 这里使用MyHeader会报错 -->
<my-header></my-header>
</div>
</body>
<script src="./vue.js"></script>
<script>
// 全局组件
Vue.component('MyHeader', {
template: `
导航组件
`
})
// 此处使用MyHeader可以正常运行
const App = {
template: `
`,
data() {
return {
msg: 'App组件'
}
},
methods: {
handleClick() {
this.msg = 'App组件Changed'
}
}
}
new Vue({
el: "#app",
data: {
},
// 全局组件不需要在components中挂载,直接使用
components: {
App
}
})
</script>
组件通信
父组件向子组件传值
- 在子组件中声明props接收父组件传递的值
- 在父组件中绑定自定义的属性
<script>
Vue.component('Child', {
template: `
`,
props: ['childData']
})
const App = {
template: `
`,
data() {
return {
msg: '父组件传递的值'
}
},
methods: {}
}
</script>
子组件向父组件传值
- 在父组件中 子组件上绑定自定义事件
- 在子组件中 触发原生的事件,在事件函数中通过this.$emit触发自定义的事件
<script>
Vue.component('Child', {
template: `
<div>
<h3>子组件</h3>
<input type="text" @input="handleInput"/>
</div>
`,
methods: {
handleInput(e) {
this.$emit('childSendMsg', e.target.value);
}
}
})
const App = {
template: `
<div>
<Child @childSendMsg = 'handleGetChildMsg'></Child>
<h3>{{childSendData}}</h3>
</div>
`,
data() {
return {
childSendData: ''
}
},
methods: {
handleGetChildMsg(msg) {
this.childSendData = msg
}
}
}
</script>
平行组件通信-中央事件总线
- 新建一个空的Vue实例作为中央事件总线
- 在组件B创建的钩子函数中添加监听事件
- 在组件A中触发事件
<script>
// 新建一个bus Vue实例对象
const bus = new Vue();
Vue.component('A', {
template: `
`,
methods: {
handleClick() {
bus.$emit('add', 1);
}
}
})
Vue.component('B', {
template: `
`,
data() {
return {
count: 0
}
},
created() {
// 用bus而不是this,this指向当前组件
bus.$on('add', n => {
this.count += n;
})
},
// 最好在组件销毁前,清除事件监听
beforeDestroy() {
bus.$off('add');
}
})
const App = {
template: `
`
}
</script>
provide与inject
- 在父组件中使用provide提供变量
- 在子组件中通过inject来注入变量,无论组件嵌套多深
<script>
// A组件引入了B组件
Vue.component('A', {
template: `
<div>
<B></B>
</div>
`
})
// B组件通过inject获取了App组件的数据
Vue.component('B', {
template: `
<div>
<h3>{{msg}}</h3>
</div>
`,
inject: ['msg']
})
// App 组件引入了A组件,使用provide提供了数据
const App = {
template: `
<div>
<A></A>
</div>
`,
provide() {
return {
msg: 'APP组件数据'
}
}
}
</script>
$parent与$children
通过this.$parent
获取父组件
通过this.$children
获取子组件数组
异步组件加载
以工厂函数的方式引入组件
组件文件 Test.js
export default {
data() {
return {
msg: '子组件'
}
},
template: `
<h3>{{msg}}</h3>
`
}
<script type='module'>
const App = {
template: `
`,
data() {
return {
isShow: false
}
}
components: {
Test: ()=>import('./Test.js') // 使用import引入
},
methods: {
asyncLoad() {
this.isShow = true;
}
}
}
</script>
当点击按钮时,才会加载Test组件,而不是立即加载
对象变更检测
Vue不能检测对象属性的添加和删除
解决方法:
// Vue.$set(object, key, value)添加响应式属性 this.$set(this.user, age, 20)
- ```javascript this.user = Object.assign({}, this.user, { age: 20, phone: 123455 })
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!