vue的组件传值分为三种方式:父传子、子传父、非父子组件传值
引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,emit向上传递,兄弟之间用bus。
子组件
<template>
<div class="child">
{{ message }}
</div>
</template>
<script>
export default {
name: "Child",
props: {
message: String,
},
};
</script>
父组件
<template>
<div class="father">
<Child :message="text" />
<input v-model="data" />
<button @click="changeChild">点我改变子组件的值</button>
</div>
</template>
<script>
import Child from "./Child";
export default {
name: "Father",
components: { Child },
data() {
return {
data: "",
text: "我是父组件的值",
};
},
methods: {
changeChild() {
this.text = this.data;
},
},
};
</script>
子组件
<template>
<div class="child">
<button @click="setTime">点击我获取父组件的方法</button>
</div>
</template>
<script>
export default {
name: "Child",
methods:{
setTime(){
this.$emit("getTime","可以传参");
}
},
};
</script>
父组件
<template>
<div class="father">
<Child @get-time="getTime" />
<input v-model="data" />
<p>{{ time }}</p>
</div>
</template>
<script>
import Child from "./Child";
import moment from "moment" //npm i moment -s 下载日期插件
export default {
name: "Father",
components: { Child },
data() {
return {
data: "",
time: "",
};
},
methods: {
getTime(data) {
this.time = moment().format('YYYY年MM月DD日, hh:mm:ss')
this.data = data;
},
},
};
</script>
关于父子组件传值遇到的坑可以看vue修改父组件传值报错
父组件引入两兄弟
<template>
<div class="father">
<Child />
<ChildTwo />
</div>
</template>
<script>
import Child from "./Child";
import ChildTwo from "./ChildTwo";
export default {
name: "Father",
components: { Child, ChildTwo },
};
创建一个bus文件夹下面新建一个bus.js文件
bus.js代码
import Vue from 'vue'
var bus = new Vue();
export default bus;
兄弟组件一号
<template>
<div class="child">
<h1>我是1号兄弟组件</h1>
<button @click="changeTwo">点击我改变2号的值</button>
</div>
</template>
<script>
import Bus from "@/bus/bus"
export default {
name: "Child",
methods:{
changeTwo(){
Bus.$emit("changeName","可以选填的值")
}
},
};
</script>
兄弟组件二号
<template>
<div class="child-two">
<h1>我是2号兄弟组件</h1>
<p>{{ name }}</p>
</div>
</template>
<script>
import Bus from "@/bus/bus";
export default {
name: "ChildTwo",
data() {
return {
name: "uzi",
};
},
mounted() {
Bus.$on("changeName", (data) => { this.name = data });
},
};
</script>
注:用bus传值,父组件引入子组件,子组件需要传值的用Bus. e m i t ( ) , 接 收 方 用 B u s . emit(),接收方用 Bus. emit(),接收方用Bus.on()。
最后看效果图
改变后
官网是这么解释的
意思就是孙子组件的传值问题可以选择不使用props传值而通过$attrs传递
部分代码
//父组件
<template>
<div class="father">
<compOne :message="message"/>
</div>
</template>
<script>
import compOne from "@/views/Component/compOne";
export default {
name: "father",
components: {
compOne,
},
data() {
return {
message: "父组件传过去的值",
};
},
inheritAttrs: false,
methods: { },
};
</script>
//子组件
<template>
<div class="comp-one">
<compOneChild v-bind="$attrs"/>
</div>
</template>
<script>
import compOneChild from "./compOneChild.vue";
export default {
name: "compOne",
components: { compOneChild },
inheritAttrs: false,
created() {
console.log("我是子组件", this.$attrs);
},
methods: {},
};
</script>
//孙子组件
<template>
<div class="comp-one-child"> </div>
</template>
<script>
export default {
name: "compOneChild",
created() {
console.log("我是孙组件", this.$attrs);
},
inheritAttrs: false,
};
</script>
打印结果
官网是这么解释的
$listeners可以将孙组件的事件和参数传递给父组件
//父组件
<template>
<div class="father">
<compOne
v-on="$listeners"
@compOneChild="compOneChild"/>
</div>
</template>
<script>
import compOne from "@/views/Component/compOne";
export default {
name: "father",
components: {
compOne,
},
data() {
return { };
},
inheritAttrs: false,
methods: {
compOneChild(val) {
console.log("我是父组件", val);
},
},
};
</script>
//子组件
<template>
<div class="comp-one">
<compOneChild v-on="$listeners"/>
</div>
</template>
<script>
import compOneChild from "./compOneChild.vue";
export default {
name: "compOne",
inheritAttrs: false,
methods: {},
};
</script>
//孙子组件
<template>
<div class="comp-one-child">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="姓名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.pass"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "compOneChild",
data() {
return {
form: {
name: "",
pass: "",
},
};
},
inheritAttrs: false,
methods: {
onSubmit() {
this.$listeners.compOneChild(this.form);
//this.$emit("compOneChild", this.form); //也可以用这种向上方式传值
},
},
};
</script>
官网概念:
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
官网链接provide / inject
用法举例
//祖先组件(刚登陆首页的组件)
data() {
return {
userName: "李潇潇",
};
},
provide() {
return {
newName: () => this.userName,
};
},
//子孙组件(随便跳转详情的组件)
inject: ["newName"],
mounted() {
console.log(this.newName());
console.log(this.userName());
},
methods: {
userName() {
return this.newName();
},
}
最后看跳转子孙的打印值
在使用VUEX时先弄懂几个概率。
VUEX是用来干嘛的?
答:vuex是一个状态管理工具存储应用所有组件的状态。
构成:
实现的功能:有两个组件A和B,有一个公共的名字(默认为UZI),想要使组件A改变名字,组件B名字也改变为一样的,组件B改变反之A也改变。
这是文件目录,为了方便后期管理将store下面新建文件夹与文件,每个文件管理一个或几个状态,这里name.js管理name
store下面的index.js代码
import Vue from 'vue'
import Vuex from 'vuex'
import name from './name/name'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
name,
}
})
name.js代码
const state = { //基本数据,变量
userName: "UZI" //默认值
}
const actions = { //提交mutations
changeNameOne({ commit }, name) {
return commit("changeNameOne", name)
},
changeNameTwo({commit }, name) {
return commit("changeNameOne", name)
}
}
const getters ={ //计算属性
userName(state){
return state.userName
}
}
const mutations = { //同步的数据
changeNameOne(state, obj) {
state.userName = obj
},
changeNameTwo(state, obj) {
state.userName = obj
},
}
export default {
state,
actions,
getters,
mutations
}
NameOne组件
<template>
<div>
<P class="title">组件A</P>
<P class="titleName">名字:{{ userName }}</P>
<div>
<input v-model="name" placeholder="请输入名字" />
<button @click="changeNameOne(name)">修改名字</button>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters } from "vuex";
export default {
name: "NameOne",
data() {
return {
name: "JackLove",
};
},
methods: {
...mapActions(
["changeNameOne"] //提交这个方法===this.$store.dispatch('changeNameTwo')
),
},
computed: {
...mapGetters(
["userName"] //计算属性===this.$store.getters.userName
),
},
};
</script>
mapActions和mapGetters是vuex的语法糖
NameTwo组件
<template>
<div>
<P class="title">组件B</P>
<P class="titleName">名字:{{ userName }}</P>
<div>
<input v-model="name" placeholder="请输入名字" />
<button @click="changeNameTwo(name)">修改名字</button>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters } from "vuex";
export default {
name:"NameTwo",
data() {
return {
name: "ClearLove",
};
},
methods: {
...mapActions(
["changeNameTwo"] //提交这个方法===this.$store.dispatch('changeNameTwo')
),
},
computed: {
...mapGetters(
["userName"] //计算属性===this.$store.getters.userName
),
},
}
</script>
最后看效果图,当修改A组件的名字的时候
当修改B组件的名字的时候
PS:最后再加了个组件C,看效果图
PS:还可以这样传参
this.$store.commit(‘name/changeNameOne’,res) (res是需要传的参数)
这样接收参数
this.$store.getters[“workStore/getToken”]
这种有没有方便
新建两个文件分别为setStorage.vue和getStorage.vue,一个用来储存一个用来获取数据。由于sessionStorage、localStorage使用的方法一样这里用sessionStorage来做的示范。
<template>
<div>
<input v-model="data" />
<button @click="setData()">点击我分发数据</button>
</div>
</template>
<script>
export default {
name:"setStorage",
data(){
return{
data:""
}
},
methods:{
setData(){
sessionStorage.setItem('myData',this.data) //用来储存data数据,myData自定义的名字
}
},
}
</script>
getStorage.vue组件
<template>
<div>
<label>{{data}}</label>
<button @click="getData()">点击我获取数据</button>
</div>
</template>
<script>
export default {
name:"getStorage",
data(){
return{
data:""
}
},
methods:{
getData(){
let item= sessionStorage.getItem('myData') //获取到myData储存的数据
this.data=item //赋值
}
},
}
</script>