详细讲解vuecli中的vue组件化与父子通信
程序员文章站
2024-03-25 09:31:22
...
1 简介
- vuecli 中提供一种简单的方式进行组件化开发。
- 注意
- 引入 js 模块和引入 vue 模块是不一样的。引入 js 模块是全局引入,而引入 vue 模块是局部引入。在不同模块下引入相同的 js 模块,当修改js模块中的变量时,会在全局影响,所有引入该模块的文件都能察觉该改动。但是修改 vue 模块中的变量,是不会影响全局的。
2 定义组件
- 组件可以使用ES6模块化规范的写法,通过 import 引入其他vue或者js模块。
- data 部分必须是方法而不是json对象!
<template>
<div>
{{msg}}
</div>
</template>
<script>
export default {
// 其他组件
components: {},
// 生命周期
created() {},
mounted() {},
// vue 变量
data() {
return {
msg: 'hello world',
}
},
// 方法
methods: {},
// 来自父组件的消息
props: {},
}
</script>
3 父组件中使用
- 注意,子组件的名称与引入时起的名称有关与文件名无关。引入的时候必须采取驼峰命名法。标签使用的时候必须全小写,单词之间用"-"分割
- 需要进行以下事情
- 定义子组件的.vue文件
- 在父组件中通过ES6模块化规范引入
- 在 components 中注册
- HTML代码中使用指定的标签名
// 引入
import helloWorlds from "@/views/demo1/hello-world.vue"
export default {
name: 'Home',
components: {
// 注册组件
helloWorlds
}
}
- HTML代码中使用
<template>
<div class="home">
<hello-worlds></hello-worlds>
</div>
</template>
4 父组件和子组件沟通
4.1 (*)父组件提供对象
- 通过传递对象来进行沟通
- 需要做以下事情
- 父组件中定义要传递的对象
- 在父组件使用子组件的标签处传递该对象
- 子组件在props中注册父组件传来的对象
- 关于父子通信
- 父组件传递给子组件的变量,如果在父组件中进行了修改,可以直接影响子组件
- 子组件无法直接修改父组件传递的变量。但是父组件可以提供修改该变量的方法。
- 这是父组件
<template>
<div class="home">
<hello-worlds :msg="msgInParent" :demo="demoInParent" ></hello-worlds>
</div>
</template>
<script>
import helloWorlds from '@/views/demo1/hello-world.vue'
export default {
name: 'Home',
data() {
return {
msgInParent: '你好',
}
},
methods:{
demoInParent(){
console.log("Home!!!")
}
},
components: {
helloWorlds,
},
}
</script>
- 这是子组件
- type 可以为String 、Number、Boolean、Array、Object、Date、Function、Symbol
- 注意,不允许子组件修改该值,但是你可以传递给子组件修改某个值的方法。
<template>
<div>
{{ msg }}
</div>
</template>
<script>
export default {
// 其他组件
components: {},
// 生命周期
created() {
this.demo()
},
mounted() {},
// vue 变量
data() {
return {
}
},
// 方法
methods: {},
// 来自父组件的消息
props: {
msg: {
type: String,
default: '我是默认值,父组件没有传给我msg'
},
demo:{
type: Function,
default: function(){
console.log("并没有传递进方法")
}
}
},
}
</script>
4.2 父组件提供方法
- 注意,由于方法也是对象,你可以直接使用4.1中的方法进行传递。建议只用4.1中的方法进行传递。
- 这里提供另一种传递的方法,需要做一下事情
- 在父组件中定义一个方法,在html代码中的子组件标签上注册该方法
- 在子组件中可以直接使用该方法
- 这是父组件
<template>
<div class="home">
<hello-worlds :msg="msgInParent" @demo-in-child="demoInParent"></hello-worlds>
</div>
</template>
<script>
import helloWorlds from '@/views/demo1/hello-world.vue'
export default {
name: 'Home',
mounted() {},
data() {
return {
msgInParent: '你好',
}
},
methods: {
// 被注册的方法
demoInParent() {
console.log('Home!!!')
},
},
components: {
helloWorlds,
},
}
</script>
- 这是子组件
- 在子组件中直接使用this.$emit(‘在父组件中注册的名称’,参数列表)来调用传递过来的方法
<template>
<div>
{{ msg }}
</div>
</template>
<script>
export default {
// 其他组件
components: {},
// 生命周期
created() {
this.$emit('demo-in-child')
},
mounted() {},
// vue 变量
data() {
return {
}
},
// 方法
methods: {},
// 来自父组件的消息
props: {
msg: {
type: String,
default: '我是默认值,父组件没有传给我msg'
},
},
}
</script>
4.3 子组件提供对象和方法
- 不需要子组件做额外操作,可以全权由父组件完成。
- 注意:这里的操作会增加代码的耦合性,不建议使用这里的操作。建议使用 4.1 中的方法,让父组件提供一个对象,子组件进行修改。
- 父组件可以直接调用子组件的方法,也可以直接修改子组件中的变量
- 步骤
- 需要在父组件的html代码中的子组件上绑定 ref 作为子组件的id
- 此时子组件的对象为 this.$refs.子组件id,可通过该对象对子组件进行修改
- 这里是父组件
<template>
<div class="home">
<hello-worlds ref="helloWorld"></hello-worlds>
</div>
</template>
<script>
import helloWorlds from '@/views/demo1/hello-world.vue'
export default {
name: 'Home',
mounted() {
// 调用子组件的方法console.log()
this.$refs.helloWorld.demo()
// 查询子组件的值
this.$refs.helloWorld.msg = "你好"
console.log(this.$refs.helloWorld.msg)
},
data() {
return {}
},
methods: {},
components: {
helloWorlds,
},
}
</script>
- 这里是子组件
<template>
<div>
{{ msg }}
</div>
</template>
<script>
export default {
// 其他组件
components: {},
// 生命周期
created() {},
mounted() {},
// vue 变量
data() {
return {
msg: 'hahah',
}
},
// 方法
methods: {
demo() {
console.log('hello-world!!!')
},
},
}
</script>
5 证明导入js模块和导入vue模块的不同
5.1 导入vue模块
- 实验思路:
* 在两个不同的模块A和B中引入一个共用的vue模块,在模块A中修改这个共用vue模块的变量,如果在模块 B 中再次查询该模块变量的时候能够察觉到被修改了,则说明是全局引入,否则是局部引入 - 新建一个模块demo.vue
<template>
<div>
{{ msg }}
</div>
</template>
<script>
export default {
data() {
return {
demodata: 1,
}
},
props: {
msg: {
default: '我是demo',
type: String,
},
},
}
</script>
- 在两个模块中引入
- 模块一
<template>
<div class="home">
<hello-worlds ref="helloWorld"></hello-worlds>
<demo ref="demo1"></demo>
</div>
</template>
<script>
import helloWorlds from '@/views/demo1/hello-world.vue'
import demo from '@/components/demo.vue'
export default {
name: 'Home',
mounted() {
console.log(this.$refs.demo1.demodata)
setTimeout(()=>{
this.$refs.demo1.demodata = 2000
},1000)
setTimeout(()=>{
console.log(this.$refs.demo1.demodata)
},2000)
},
data() {
return {}
},
methods: {},
components: {
helloWorlds,
demo
},
}
</script>
- 模块二
<template>
<div>
{{ msg }}
<br>
<demo ref="demo1" :msg="'我是demo1——来自hello-world'"></demo>
</div>
</template>
<script>
import demo from '@/components/demo.vue'
export default {
// 其他组件
components: {
demo
},
// 生命周期
created() {},
mounted() {
console.log(this.$refs.demo1.demodata)
setTimeout(()=>{
console.log(this.$refs.demo1.demodata)
},2000)
},
// vue 变量
data() {
return {
msg: 'hahah',
}
},
// 方法
methods: {
demo() {
console.log('hello-world!!!')
},
},
}
</script>
- 结果是
1
1
1
2000
- 这说明是局部引入
5.2 导入js模块
- 实验思路
- 在两个不同的模块A和B中引入一个共用的js模块,在模块A中修改这个共用js模块的变量,如果在模块 B 中再次查询该模块变量的时候能够察觉到被修改了,则说明是全局引入,否则是局部引入
- js模块
export default{
msg:15
}
- 模块一
<template>
<div class="home">
<hello-worlds ref="helloWorld"></hello-worlds>
</div>
</template>
<script>
import helloWorlds from '@/views/demo1/hello-world.vue'
import demo1Api from '@/utils/demo1.js'
export default {
name: 'Home',
mounted() {
console.log(demo1Api.msg)
setTimeout(()=>{
console.log(demo1Api.msg)
},2000)
},
data() {
return {}
},
methods: {},
components: {
helloWorlds,
},
}
</script>
- 模块二
<template>
<div>
{{ msg }}
</div>
</template>
<script>
import demo1Api from '@/utils/demo1.js'
export default {
// 其他组件
components: {},
// 生命周期
created() {},
mounted() {
console.log(demo1Api.msg)
setTimeout(()=>{
demo1Api.msg = 2000
},1000)
setTimeout(()=>{
console.log(demo1Api.msg)
},2000)
},
// vue 变量
data() {
return {
}
},
// 方法
methods: {},
// 来自父组件的消息
props: {
msg: {
type: String,
default: '我是默认值,父组件没有传给我msg'
},
},
}
</script>
- 结果是
15
15
2000
2000
- 这意味着是全局导入
上一篇: OpenCV3学习