Vue2 vue3 summary of each pass value

sequence:

The most common vue, which is easy to embarrass novices, should be the parameter passing between components, so this note will record the parameter passing, and record vue2 by the way.

1. vue3

1. From father to son

The parent component atherTitle, fatherMoney, fatherWifi, thisIsEmpty, etc. are all passed to the child component

<template>
<el-row class="mb-4">
	<el-button type="danger">props.vue传递父组件的参数到子组件,子组件用defineProps接收,fatherTitle和fatherMoney参数</el-button>
</el-row>
 
<!--写在父组件的子组件-->
<Son :fatherTitle="xxxxx" :fatherMoney="money" :fatherWifi="wifi" :thisIsEmpty="myEmptyStr" :fatherArr="myArr"></Son>
</template>
 
<script lang="ts" setup>
import { ref,reactive,watch,watchEffect } from 'vue'
import Son from "./son.vue"//引入子组件
 
const  xxxxx = ref("-----这是父组件的标题-----")
const money = ref(9999999999)
const wifi = reactive({pwd:222,name:"fffff"})
const myEmptyStr = ref("")
const myArr = reactive([{code:666,msg:"success"},{code:555,msg:"fail"}])
</script>

The child component receives defineProps() to receive the parameters passed by the parent component. defineProps can be used directly in the syntax sugar of setup without import

<template>
    <el-row class="mb-4">
        <el-button type="success">
            son.vue:{
   
   {sonTitle}}-------{
   
   {fatherTitle}}-----{
   
   {fatherMoney}}
    	</el-button>
        <el-button type="success">{
   
   {fatherWifi}}--{
   
   {fatherWifi.pwd}}--{
   
   {fatherWifi.name}}</el-button>
        <el-button type="danger">
            父传递的空字符串:{
   
   {myEmptyStr}}
    	</el-button>
    </el-row>
    <el-row class="mb-4">
      <el-button type="primary" v-for="(item,index) in fatherArr" :key="index">
          {
   
   {item}},{
   
   {item.code}}
      </el-button>
    </el-row>
 
</template>
<script lang="ts" setup>
import { ref,reactive} from 'vue'
const sonTitle = "This is  son title"
//接收父组件传过来的值,需要注意defineProps只能在setup语法糖里面使用,不需要import引入
const yyyy = defineProps({
	fatherTitle:{
		type:String,//类型字符串
		default:'当前Child.vue的默认值'//如果没有传递msg参数,默认值是这个
	},
	fatherMoney:{
		type:Number,//类型字符串
		default:0//如果没有传递msg参数,默认值是这个
	},
	fatherWifi:{
		type:Object,//类型字符串
		default:{id:999}//如果没有传递msg参数,默认值是这个
	},
	myEmptyStr:{
		type:String,
		default:"myEmptyStr默认值为空字符串"
	},
	fatherArr:{
		type:Object,//类型字符串
		//default:[]//如果没有传递msg参数,默认值是这个
	},
})
 
console.log(yyyy.fatherArr)
console.log("-------这是子组件---------")
console.log(yyyy.fatherWifi)
console.log(yyyy.fatherTitle)
 
</script>

TS-specific default method

withDefaults is a function and does not need to be introduced out of the box to accept a props function. The second parameter is an object to set the default value.

type Props = {
    title?: string,
    data?: number[]
}
withDefaults(defineProps<Props>(), {
    title: "张三",
    data: () => [1, 2, 3]
})

2, child father

Subassembly

<script lang="ts" setup>
import { ref,reactive} from 'vue'
 
//子组件调用父组件的方法,
//父组件的调用子组件的地方写上@onMySonFunc="fatherFunc"
const myEmit = defineEmits(["onMySonFunc"])//这样就调用到父组件的fatherFunc方法了
 
//传递参数: "调用父组件的方法"和666666
myEmit("onMySonFunc","调用父组件的方法",666666)


//如果用了ts可以这样两种方式
const emit = defineEmits<{
   (e: "onMySonFunc", name: string): void
   (e: "on-click", name: string): void
}>()
</script>

Parent component @onMySonFunc="funcToSon", so that the child component above can call the funcToSon() method of the parent component

<template>
<!--子组件调用父组件的funcToSon()方法-->
<Son  @onMySonFunc="funcToSon"></Son>
</template>
 
<script lang="ts" setup>
import { ref,reactive} from 'vue'
import Son from "./son.vue"//引入子组件
 
const funcToSon = (name:any,id:number)=>{
	console.log("子组件调用了父组件的funcToSon()方法",id)
	return {message:name}
}
</script>

3. Intergenerational inheritance

The parent component provide passes parameters to other child and grandchildren components

<script lang="ts" setup>
import { provide } from 'vue'
provide('test001', "987654321")
//provide传递test001的参数,值是987654321到子孙节点
</script>

The son component uses inject to receive the parameters passed by the parent component

<script lang="ts" setup>
import {inject} from "vue"
 
//儿子组件用inject接收父组件传递过来的参数
const provideFatherStr = inject('thisFromGrandFather')
</script>

Grandchild components can also use inject to receive parameters passed by the parent component

<script lang="ts" setup>
import {inject} from "vue"
 
//孙子组件用inject接收它爷爷组件传递过来的参数
const provideFatherStr = inject('thisFromGrandFather')
</script>

4. The third library ( mitt || tiny-emitter)

Example of using mitt:

// eventBus.js
import mitt from 'mitt';

const emitter = mitt();

export default emitter;
// a.js
import emitter from './utils/eventBus'

emitter.emit('panda', {
    
    name: 'lokka', age: 2})
emitter.emit('flamingo', {
    
    name: 'disy', age: 1})
// b.js
import emitter from './utils/eventBus'
// 逐个监听
—————————————————————————————————————————
emitter.on('panda', (val) => {
    
    
	console.log(val)
})

emitter.on('flamingo', (val) => {
    
    
	console.log(val)
})

// 取消监听
funtion onFoo() {
    
    }
emitter.on('foo', onFoo)
emitter.off('foo', onFoo)
—————————————————————————————————————————
// 监听多个
emitter.on('*', (type, val) => {
    
    
	console.log(type, val)
})

// 取消监听多个
emitter.all.clear()

Encapsulating waterfall components

parent component:

<template>
    <waterFallVue :list="list"></waterFallVue>
</template>
 
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import waterFallVue from './components/water-fall.vue';
const list = [
    {
        height: 300,
        background: 'red'
    },
    {
        height: 400,
        background: 'pink'
    },
    {
        height: 500,
        background: 'blue'
    },
    {
        height: 200,
        background: 'green'
    },
    {
        height: 300,
        background: 'gray'
    },
    {
        height: 400,
        background: '#CC00FF'
    },
    {
        height: 200,
        background: 'black'
    },
    {
        height: 100,
        background: '#996666'
    },
    {
        height: 500,
        background: 'skyblue'
    },
    {
        height: 300,
        background: '#993366'
    },
    {
        height: 100,
        background: '#33FF33'
    },
    {
        height: 400,
        background: 'skyblue'
    },
    {
        height: 200,
        background: '#6633CC'
    },
    {
        height: 300,
        background: '#666699'
    },
    {
        height: 300,
        background: '#66CCFF'
    },
    {
        height: 300,
        background: 'skyblue'
    },
    {
        height: 200,
        background: '#CC3366'
    },
    {
        height: 200,
        background: '#CC9966'
    },
    {
        height: 200,
        background: '#FF00FF'
    },
    {
        height: 500,
        background: '#990000'
    },
    {
        height: 400,
        background: 'red'
    },
    {
        height: 100,
        background: '#999966'
    },
    {
        height: 200,
        background: '#CCCC66'
    },
    {
        height: 300,
        background: '#FF33FF'
    },
    {
        height: 400,
        background: '#FFFF66'
    },
    {
        height: 200,
        background: 'red'
    },
    {
        height: 100,
        background: 'skyblue'
    },
    {
        height: 200,
        background: '#33CC00'
    },
    {
        height: 300,
        background: '#330033'
    },
    {
        height: 100,
        background: '#0066CC'
    },
    {
        height: 200,
        background: 'skyblue'
    },
    {
        height: 100,
        background: '#006666'
    },
    {
        height: 200,
        background: 'yellow'
    },
    {
        height: 300,
        background: 'yellow'
    },
    {
        height: 100,
        background: '#33CCFF'
    },
    {
        height: 400,
        background: 'yellow'
    },
    {
        height: 400,
        background: 'yellow'
    },
    {
        height: 200,
        background: '#33FF00'
    },
    {
        height: 300,
        background: 'yellow'
    },
    {
        height: 100,
        background: 'green'
    }
 
]
</script>
 
<style  lang='less'>
#app,
html,
body {
    height: 100%;
}
 
* {
    padding: 0;
    margin: 0;
}
</style>

Subassembly:

<template>
    <div class="wraps">
        <div :style="{height:item.height+'px',background:item.background,top:item.top+'px',left:item.left + 'px'}"
            v-for="item in waterList" class="items"></div>
    </div>
</template>
 
<script setup lang='ts'>
import { ref, reactive, onMounted } from 'vue'
const props = defineProps<{
    list: any[]
}>()
const waterList = reactive<any[]>([])
const init = () => {
    const heightList: any[] = []
    const width = 130;
    const x = document.body.clientWidth
    const column = Math.floor(x / width)
 
    for (let i = 0; i < props.list.length; i++) {
        if (i < column) {
            props.list[i].top = 10;
            props.list[i].left = i * width;
            heightList.push(props.list[i].height + 10)
            waterList.push(props.list[i])
        } else {
            let current = heightList[0]
            let index = 0;
            heightList.forEach((h, inx) => {
                if (current > h) {
                    current = h;
                    index = inx;
                }
            })
            console.log(current,'c')
            props.list[i].top = (current + 20);
            console.log(props.list[i].top,'top',i)
            props.list[i].left = index * width;
            heightList[index] =  (heightList[index] + props.list[i].height + 20);
            waterList.push(props.list[i])
        
        }
    }
    console.log(props.list)
}
 
onMounted(() => {
    window.onresize = () => init()
    init()
})
 
</script>
 
<style scoped lang='less'>
.wraps {
    position: relative;
     height: 100%;
    .items {
        position: absolute;
        width: 120px;
    }
}
</style>

insert image description here

Two, vue2

1. From father to son

parent component

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <Son
          str="我是字符串"
          isPublished
          :num=5
          :obj="{cont:'我是一个对象'}"
          :func="()=>{this.hello()}"
          :arr="arr"></Son>
    </div>
</template>
<script>
    import Son from './Son'
    export default {
        name: "Father",
        data(){
            return{
                arr:[1,2,3]
            }
        },
        methods:{
            hello(){
                console.log("hello world!")
            }
        },
        components:{  Son  }
    }
</script>

Subassembly

<template>
    <div>我是Son组件</div>
</template>
<script>
    export default {
        name: "Son",
        props:{//props列表
            arr:Array,//定义参数类型
            num:Number,
            isPublished: Boolean,
            str:String,
            str2:{
                type:String,
                default:"我是默认字符串"//定义参数默认值
            },
            func:{
                type:Function,
                required:false//定义参数是否必须值
            },
            obj:{
                type: Object,
                required:false
            }
        },
        created() {
            console.log(this.str);//我是字符串
            console.log(this.str2);//我是默认字符串
            console.log(this.num);//5
            console.log(this.isPublished);//true
            console.log(this.func);//hello(){console.log("hello world!");}
            console.log(this.arr);//[1,2,3]
            console.log(this.obj);//{cont:'我是一个对象'}
            this.func();//hello world!
        }
    }
</script>

2, child father

2.1、$emit

parent component

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <Son @func="speak" ></Son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Father",
        methods:{
           speak(msg){
               console.log(msg);//我是子组件发送的消息!
           }
        },
        components:{
            Son
        }
    }
</script>

Subassembly

<template>
    <div>
        <div>我是Son组件</div>
    </div>
</template>

<script>
    export default {
        name: "Son",
        mounted() {
             //func 是绑定的事件名
            this.$emit('func',"我是子组件发送的消息!");
        }
    }
</script>

2.2, direct transmission

parent component

<template>
  <div class="parent">
    <child :fatherMethod='fatherMethod'></child>// 父组件把方法传入子组件中,在子组件里直接调用这个方法
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        methods:{
            fatherMethod() {
                alert('我是父组件的know方法');
            }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

Subassembly

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        props:{
            fatherMethod: {
                type: Function,
                default: null
            }
        },
        methods:{
            childClick(){
                this.fatherMethod()
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }
</style>

2.3、$refs

parent component

<template>
    <div class="wrap">
        <div>我是Father组件</div>
        <!-- ref绑定节点 -->
        <Son ref="son">
          <!-- @click.stop  阻止冒泡 -->
          <button @click.stop="UGG">按钮</button>
        </Son>
    </div>
</template>

<script>
    import Son from './Son'
    export default {
        name: "Father",
        mounted(){
          //获取节点
            this.$refs['son'].$on('func',(msg)=>{
                console.log(msg);
            })
        },
        methods:{
            UGG(){
              //调用节点里的方法
              this.$refs['son'].show()
            }
        },
        components:{
            Son
        }
    }
</script>

Subassembly

<template>
    <div>
        <div>我是Son组件</div>
        <button @click="$emit('func','我是子组件传递的消息1!')">Send1</button>
        <button @click="sendMsg">Send2</button>
        <!-- 插槽 -->
        <slot></slot>
    </div>
</template>

<script>
    export default {
        name: "Son",
        methods:{
            sendMsg(){
                //func 是绑定的事件名
                this.$emit('func','我是子组件传递的消息2!');
            },
            show(){
                console.log('显示')
            }
        }
    }
</script>

2.4、$parent

$root$parentBoth can achieve access to the properties and methods of the parent component. The difference between the two is that if there are multi-level subcomponents, the parent component is obtained through parent access, and the root parent component (App) is obtained through root access. .vue) so do not use $root when there is component nesting

parent component

<template>
  <div class="parent">
    <child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
  </div>
</template>

<script>
    import child from '../base/child'
    
    export default {
        data() { // 组件的data必须是函数
          return {
            msg:'父组件数据测试'
          }
        },
        methods:{
          fatherMethod() {
            alert('我是父组件的方法')
          }
        },
        components:{
            child
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

Subassembly

<template>
  <div class="child" @click='childClick'>
  </div>
</template>

<script>

    export default {
        data() {
            return {
                msg: '我是子组件传递过来的数据'
            }
        },
        methods:{
            childClick(){
                this.$parent.fatherMethod()
                console.log(this.$parent.msg)
        }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .child{
    width: 100px;
    height: 100px;
    background-color: blue;
  }
</style>

3. Brother pass value

Mount the global EventBus in main.js

Vue.prototype.$EventBus = new Vue()

A component

<template>
    <div class="wrap">
        <div>我是组件A</div>
        <button @click="sendMsg">发送</button>
    </div>
</template>

<script>
    export default {
        name: "A",
        methods:{
            sendMsg(){
               this.$EventBus.$emit('sendMsg',"这是组件A发送的消息!")
            }
        }
    }
</script>

B component

<template>
    <div>
        <div>我是组件B</div>
    </div>
</template>

<script>
    export default {
        name: "B",
        mounted(){
            this.$EventBus.$on('sendMsg',(msg)=>{
                console.log(msg);//这是组件A发送的消息!
            })
        },
    }
</script>

4. Intergenerational value passing ( provide/ inject)

Provide is the attribute/method that the parent component needs to pass to the descendant component

//选项一
provide: {
    
    
  content: 'hello world'
}

//选项二
provide(){
    
    
  return {
    
    
    content: 'hello world'
  }
}

Inject is used by descendant components to receive properties/methods of parent components

//选项一
inject: ['content']

//选项二
inject: {
    
    
  content: 'content'
}

//选项三
inject: {
    
    
  content: {
    
    
    from:'content',
    default:'hello world'
  }
}

a.vue

<template>
    <div>
        <span>{
   
   {a}}</span>
        <aa></aa>
    </div>
</template>

<script>
    import aa from './aa';
    
    export default {
        data(){
            return {
                a: "我是a组件中数据"
            }
        },
        provide() {
            return {
                msg: this.a
            }
        },
        components: {
            aa
        }
    }
</script>

aa.vue

<template>
    <div>
    </div>
</template>

<script>
    export default {
        inject: ['msg'],
        created() {
            console.log(this.msg); // 我是a组件中数据
        }
    }
</script>

5. Cross-level ( $attrs/ $listeners)

  • ** attrs: ∗ ∗ Contains attribute bindings (except class and style) that are not recognized (and acquired) by prop in the parent scope. When a component does not declare any props, all parent scope bindings (except class and style) will be included here, and can be passed v − bind = " attrs: ** contains parent scopes that are not recognized by props ( and access) feature bindings (except class and style). When a component does not declare any props, all parent scope bindings (except class and style) will be included here, and can be passed v-bind="attrs∗ Contains attribute bindings ( except c l a ss and style ) that are not recognized ( and acquired ) by pro p in the parent scope . When a component does not declare any p ro p , it will contain all parent scope bindings ( except c l a ss and s ty l e ) , and can pass vbind=" attrs" is passed into the internal component. Usually used in conjunction with the interitAttrs option.
  • ** listeners : ∗ ∗ Contains the v − on event listeners in the parent scope (without the . native decorator). It can be passed v − on = " listeners: **Includes the v-on event listener in the parent scope (without the .native decorator). It can be passed v-on="listeners∗ Contains v in the parent scope ( without the . na t i v e modifier )o nEvent listener. it can be passed von=" listeners" passed into the internal component

parent component

<template>
    <div>
        <span>{
   
   {name}}</span>
        <span>{
   
   {price}}</span>
        <aa
        :name="name"
        :price="price"
        :size="size"
        ></aa>
    </div>
</template>

<script>
    import aa from './aa';   
    export default {
        data(){
            return {
                name: "可乐",
                price: 3,
                size: "500ml"
            }
        },
        provide() {
            return {
                msg: this.a
            }
        },
        components: {
            aa
        }
    }
</script>

Subcomponent aa.vue

<template>
    <div>
        <span>{
   
   {name}}</span>
        <aaa v-bind="$attrs"></aaa>
    </div>
</template>

<script>
    import aaa from './aaa';    
    export default {
        props: ['name'],
        components: {
            aaa
        }
    }
</script>

Subcomponent aaa.vue

<template>
    <div>
    </div>
</template>

<script>    
    export default {
        created() {
            console.log(this.$attrs); // {price: 3, size: "500ml"}
        }
    }
</script>

Summary: $attrs and listeners are two objects, listeners are two objects,l i s t e n ers are two objects, attrs store the non-Props properties bound in the parent component, and $listeners store the non-native events bound in the parent component.

6. Plug-in pass value

Install pubsub-jsplug-ins : npm i pubsub-js -sglobal parameter passing can be realized

  • publishSyncSend messages synchronously
  • publishSend messages synchronously
  • subscribesubscribe news
  • unsubscribeUninstall a specific subscription
  • clearAllSubscriptionsclear all subscriptions

Component A

<template>
    <div class="wrap">
        <div>我是组件A</div>
        <button @click="sendMsg">发送</button>
    </div>
</template>

<script>
    import  pubsub from 'pubsub-js'
    export default {
        name: "A",
        methods:{
            sendMsg(){
                //publishSync  同步发送消息
                pubsub.publishSync("sendMsg","这是A组件发布的消息!");
            }
        }
    }
</script>

Component B

<template>
    <div>
        <div>我是组件B</div>
    </div>
</template>

<script>
    import pubsub from 'pubsub-js'
    export default {
        name: "B",
        mounted(){
            //subscribe    订阅消息
            pubsub.subscribe("sendMsg",(e,msg)=>{
                console.log(e,msg);//sendMsg 这是A组件发布的消息!
            })
        },
    }
</script>

7. Route value transfer

7.1, page direct parameter transfer

<router-link :to="{ path:'./attachment',query:{order_id: task.ORDERID}}">
    <mt-button type="primary" size="small">查看附件</mt-button>
</router-link>

7.2. Passing parameters through methods

methods: {
    
    
    society() {
    
    
        //console.log('society');
        this.$router.push({
    
    
            name:'society',
            query:{
    
    value:1}
        })
},

7.3, connection value

methods:{
    
    
    loadData:function(){
    
    
    	this.id = this.$route.query.order_id;
    	axios.get("http://testqywx.origimed.com:18082/weixin-qy/order/Order/userOrderFilesList.json?usercode=sysadmin&orderId="+this.id)
    	.then(response=>this.tasks=response.data.reason);
    }
},

Oops, I'm tired, I didn't expect to sum it up, there are still a lot, let's put so much for now, I will update when I have it~

Guess you like

Origin blog.csdn.net/MoXinXueWEB/article/details/127098394