props、$emit 触发父亲的自定义事件
实际上是子传父、父传子的结合:利用父组件做中转站
<div id="app">
<test-com1 :pmsg="msg">test-com1>
<test-com2 @mod-msg="handler">test-com2>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 组件1与父组件之间的数据进行父传子
Vue.component('test-com1', {
props: ['pmsg'],
data: function () {
return {
msg: '我是组件1中的值' }
},
template: `组件1:{
{pmsg}}`
})
// 组件2与父组件之间的数据进行子传父
Vue.component('test-com2', {
data: function () {
return {
msg: '我是组件2中的值' }
},
template: ``
})
// 组件2中的数据提升到父组件(状态提升):利用父类来实现兄弟数据传输
const vm = new Vue({
el: '#app',
data: {
msg: '我是父组件中的值' },
methods: {
handler(val) {
this.msg = val
}
}
})
</script>
利用事件中心实现组件间自由传值:会引起传值紊乱。不知道‘谁’修改了数值
<div id="app">
<test-com1>test-com1>
<test-com2>test-com2>
<button @click="handler">销毁事件button>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 事件中心
const hub = new Vue()
// 组件1
Vue.component('test-com1', {
name: 'Tom',
data: function () {
return {
num: 1 }
},
template: `
Tom{
{num}}
`,
methods: {
handler() {
// 在事件中心下挂载tom 这里传的num是Tom
hub.$emit('tom-com', this.num)
}
},
// TODO: 通过hub.$on 去监听并触发事件
created() {
hub.$on('jerry-com', (val) => {
console.log(val)
this.num += val
})
}
})
// 组件2
Vue.component('test-com2', {
name: 'Jerry',
data: function () {
return {
num: 2 }
},
template: `
Jerry{
{num}}
`,
methods: {
handler() {
// 在事件中心下挂载jerry 这里传的num是Jerry
hub.$emit('jerry-com', this.num)
}
},
// TODO: 通过hub.$on 去监听并触发事件
created() {
hub.$on('tom-com', (val) => {
console.log(val)
this.num += val
})
}
})
// Vue实例对象
const vm = new Vue({
el: '#app',
methods: {
handler() {
hub.$off('jerry-com')
hub.$off('tom-com')
}
}
})
</script>
实现各组件间数据共享
state:共享数据源;
mutations:修改数据(state中的数据);
actions:异步请求;
getters:对共享数据进行包装(类似计算属性);
modules:模块化
vm.$refs 一个对象,持有注册过 ref attribute 的所有 DOM 元素和组件实例。
<input type="file" hidden ref="imgFile" @change="onUpdateAvatar" />
onUpdateAvatar() {
// this.$refs.imgFile 拿到对应的组件对象
// 拿到文件对象
const file = this.$refs.imgFile.files[0]
// 清空input框
this.$refs.imgFile.value = ''
}
<div id="app">
<p>{
{msg}}p>
<test>test>
<button @click="handleClick">change childbutton>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
<script>
// 儿子
Vue.component('test', {
data() {
return {
age: 18
}
},
template: `
{
{age}}
`,
methods: {
handleClick() {
this.$parent.changeMsg('ifer');
},
},
});
// 父亲
const vm = new Vue({
el: '#app',
name: 'App',
data: {
msg: 'hello world'
},
methods: {
changeMsg(msg) {
this.msg = msg;
},
handleClick() {
// this.$children[0] 第 1 个子组件
this.$children[0].age = 19;
}
}
});
</script>
<div id="app">
<test1>test1>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
<script>
// 父亲
Vue.component('test1', {
template: 'test1 '
});
// 儿子
Vue.component('test2', {
// #2 接受数据
inject: ['msg'],
template: 'test2 {
{msg}}'
});
// 爷爷
const vm = new Vue({
el: '#app',
name: 'App',
data: {
},
// #1 提供数据
provide: {
msg: 'hello'
},
});
</script>
vm.attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style除外)。
vm.$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。
<div id="app">
<test :msg="msg" @changemsg="changeMsg">test>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js"></script>
<script>
// 儿子
Vue.component('test', {
template: `
{
{$attrs.msg}}
`,
mounted() {
},
});
// 父亲
const vm = new Vue({
el: '#app',
name: 'App',
data: {
msg: 'hello'
},
methods: {
changeMsg(msg) {
this.msg = msg;
}
},
});
</script>
利用浏览器本地存储