vue组件之间数据传递的几种方式_vue如果 组件分散较多 数据传递用那种方式

24 阅读2分钟
<body>
    <div id="app">
        {{countF}}
        <gp-18 @counterchanger='handlerChange'></gp-18>
    </div>
    <script type="text/template" id="gp-18Temp">
        <div>
            <h1>gp-counter</h1>
            <button @click='decrement(1)'>-</button>
            {{count}}
            <button @click='increment(1)'>+</button>
        </div>
    </script>
    <script>
        //全局组件
        Vue.component('gp-18',{
            template:'#gp-18Temp',
            data(){
                return{
                    count:0
                }
            },
            methods:{
                increment(num){
                    this.count++
                    this.$emit('counterchanger',this.count)
                },
                decrement(num){
                    this.count--
                    this.$emit('counterchanger',this.count)
                }
            }
        })
        var vm=new Vue({
            el:'#app',
            data:{
                countF:0
            },
            methods:{
                //子组件的值将作为第一个参数
                handlerChange(num){
                    this.countF=num
                }
            }
            
        })
    </script>
</body>

二、边界 this.rootthis.root — this.parent— this.$refs

缺点:refs只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 refs。

  • 在每个 new Vue 实例的子组件中,其根实例可以通过 $root 属性进行访问

r

o

o

t

root 类似,

root类似,parent 属性可以用来从一个子组件访问父组件的实例

  • 尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,可以通过 ref 这个 attribute 为子组件赋予一个 ID 引用,如(< compb ref=‘refcomb’ >< /compb >),然后通过this.$refs.refcomb来访问这个子组件实例
<body>
    <div id="app">
        <input type="text" ref='myinput'>
        <compa ></compa>
    </div>

    <script>
        const compb={
            data(){
                return{
                    title:"孙子组件的数据"
                }
            },
            template:'<h2>compb-{{$root.username}}</h2>',
            mounted(){
                //获取根组件的内容
                console.log(this.$root.username)
                //获取父组件的内容
                console.log(this.$parent.title)
                console.log(this.$parent.start())
            }
        }

        const compa={
            props:['user'],
            data(){
                return{
                    title:'父组件的数据'
                }
            },
            template:`
 <h1>
 compa
 <compb ref='refcomb'></compb>
 </h1>`,
            components:{
                compb
            },
            methods:{
                start(){
                    console.log('父组件的方法');
                }
            },
            mounted(){
                console.log(this.$refs.refcomb.title);
            }
        }
        var vm=new Vue({
            el:"#app",
            data:{
                username:'dny'
            },
            components:{
                compa
            },
            mounted(){
                console.log(this.$refs.myinput);
            }
        })
    </script>
</body>

三、provide inject (依赖注入)

缺点:依赖注入将应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的属性是非响应式的

<body>
    <div id="app">
        <input type="text" ref='myinput'>
        <compa></compa>
    </div>
<!-- 数据不是响应式的 -->
    <script>
        const compb = {
            inject: ['username'],
            template: '<h2>compb-{{username}}</h2>',
            mounted(){
            	console.log(this.foo()) // dny
            }
        }

        const compa = {
            template: `
 <h1>
 compa
 <compb ></compb>
 </h1>`,
            components: {
                compb
            },
        }
        var vm = new Vue({
            el: "#app",
            data: {
                username: 'dny'
            },
            //返回内容在子组件和孙子组件都可以访问到
            provide: function () {
                return {
                    username: this.username,
                    foo:()=>{
                    	return this.username
                    }
                }
            },
        })
    </script>
</body>

四、event-bus 事件总线

不支持响应式

<body>
    <div id="app">
        <compa></compa>
    </div>
    <script>

        var eventbus=new Vue()
        const compb = {
            template: '<h2>compb-</h2>',
            mounted(){
                eventbus.$on('message',function(msg){
                    console.log(msg);
                })
            }

        }

        const compa = {
            template: `
 <h1>
 compa
 <compb ></compb>
 </h1>`,
            components: {
                compb
            },
        }
        var vm = new Vue({
            el: "#app",
            data: {
                username: 'dny'
            },
            components: {
                compa
            },
            methods:{
                handleback(){
                    eventbus.$emit('message','hello world')
                }
            }
        })
    </script>
</body>

五、slot插槽

六、.sync修饰符

在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源。这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js"></script>
</head>
<body>
    <div id="app">
        <parent-component></parent-component>
    </div>
    <script>
        let ChildComponent={
            props:['title'],
            template:`
 <h1>-Child------</h1>
 `,
            mounted(){
                this.$emit('update:title',"def")
            }
        }
        let ParentComponent={
            template:`
 <div>
 <h1>parent-component-----{{title}}</h1>
 <child-component v-bind:title.sync='title'></child-component>
 </div>
 `,
            data(){
                return{
                    title:"abc"
                }
            },
            components:{
                ChildComponent
            }
        }
        
        var vm= new Vue({
            el:"#app",
            components:{
                ParentComponent
            }
        })
    </script>
</body>
</html>

七、vuex

支持响应式,但是数据的读取和修改需要按照流程来操作,不适合小型项目

<body>
    <div id="app">
        <counter-btn type='decrement'></counter-btn>
        <counter-span></counter-span>
        <counter-btn type='increment'></counter-btn>
    </div>


##### 框架相关

原生JS虽能实现绝大部分功能,但要么就是过于繁琐,要么就是存在缺陷,故绝大多数开发者都会首选框架开发方案。现阶段较热门是React、Vue两大框架,两者工作原理上存在共通点,也存在一些不同点,对于校招来说,不需要两个框架都学得特别熟,一般面试官会针对你简历中写的框架进行提问。

在框架方面,**生命周期、钩子函数、虚拟DOM这些基本知识是必须要掌握的**,在学习的过程可以结合框架的官方文档



**Vue框架**

>**知识要点:**
>**1. vue-cli工程**
>**2. vue核心知识点**
>**3. vue-router**
>**4. vuex**
>**5. http请求**
>**6. UI样式**
>**7. 常用功能**
>**8. MVVM设计模式**

![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a3da9fe8aa6c4ff1a6aa1b706c36dd30~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771414939&x-signature=AokbcQmeGw08%2Brbue%2BpvGxiUQbI%3D)


**React框架**

>**知识要点:**
>**1. 基本知识**
>**2. React 组件**
>**3. React Redux**
>**4. React 路由**

![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/bd7f0cf7276e482aa2b6aa59d2583e1d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771414939&x-signature=H%2FgzL47dN5TfHIqtxShtt8kX4IE%3D)


**开源分享:https://docs.qq.com/doc/DSmRnRGxvUkxTREhO**