Daily brick moving, project value transfer is very common behavior, I listed the vUE involved in the use of value transfer scenarios, summarized in VUE must use the form of value transfer.
Components by value
Parent and child components pass values
props
/ / parent component < I - a MSG = "angel yan jing ke qin offered figure" > < / I > a / / subcomponents props: [' MSG ']Copy the code
on/emit
// Parent <! - custom components used on listening to send the event -- -- > < I - a @ on = "gx" > < / I > a / / subcomponents enclosing $emit (' gx) / / use emit sent from custom event: gxCopy the code
$parent/$children
This.$parent gets the parent instance. This.$children gets the child instanceCopy the code
ref
<template> <div id="app"> <! < I -a ref="ia" /> <! <p > </p> </div> </template> <script> export default {methods: {rename() {this.$refs.ia // Retrieves custom component instances that can be used to call methods or data on child components. This.$refs.p1 // get the p tag, the normal dom node},},}; </script>Copy the code
Descendant components pass values
- Provoid/Inject Brother The provoid/ Inject brother must be used together.
- | provoid object returns an object function.
- Inject | string array object.
Case 1
Prerequisites: There are four components: A, B, C, and D. A nested B, B nested C, and C nested D. Introduce the A component in app.vue.
// App.vue <template> <div id="app"> <i-a></i-a> </div> </template> <script> import A from "./components/A"; Export default {name: "App", components: {"i-a": a,}, provide: {name: "daqin ",}}; <template> <div class="hello"> A: {{ name }} <div> <i-b></i-b> </div> </div> </template> <script> import B from "./B"; export default { name: "A", inject: ["name"], components: { "i-b": B, }, }; </script>Copy the code
The result of name is then inherited by all descendants.
Case 2
You should note that the name in provide is a dead character. Normally, this value is mostly retrieved from data. To access this, provide must be a function that returns an object.
// app.vue provide() {return {name: this.name}}, data: function () {return {name: "daqin empire ",}; },Copy the code
Case 3
Since they are descendants, for app, A, B, C and D are all descendants, and for A, B, C and D are all descendants… , if provide is used in component A, can its background also get data? The answer: crotch on fire. – Crotch on fire (of course).
}, // b.vue \ c.vue \ d.vue inject: ["name", "wuchenghou"],Copy the code
Case 4
If both parents have the same value, who should I listen to? The answer is: listen to whoever is near you!
// app.vue provide: {shoudu: "Xiyang ",} // a.vue provide: {Wuchenghou:" Shoudu: "Wang Jian ",}, // ABCD component inject: ["name", "wuchenghou", "shoudu"] <! {{shoudu}}</p>Copy the code
Case 5
Inject supports objects in addition to string arrays. As an object, key is the local binding name and value is.
- Search for the key(string or Symbol) used in the available injection content, or
- An object of which:
from
Property is the key (string or Symbol) to search for in the available injection contentdefault
Property is the value used in the degraded case
Rewrite the inject of component B:
inject: {
name: "name",
wuchenghou: {
from: "wuchenghou",
default: "--",
},
shoudu: "shoudu",
},
Copy the code
Case 6
Have you ever wondered how well provide works when using asynchronous data? Suppose we need to change the value in provide under certain circumstances, is that as expected?
// app.vue <template> < button@click ="rename"> </button> {{this.name}} <hr /> </template> Return {name: shoudu: "shoudu ",}; }, methods: {rename() {this.name = "ying Zong "; }},Copy the code
Then click the “Qin Wang Zheng” button
The name in app.vue has changed, but its descendant gate has not. Provide and Inject binding are not responsive. If a listening object is passed in, the object’s property is still responsive. That is, if you want descendant to respond to asynchronously received values, the value corresponding to key in provide must be a reference type.
// app.vue provide() {return {name: this.name, shoudu: "xianyang ", qin: this.qin,}; }, data: the function () {return {name: "daqin empire," qin: {ge: "qin wang,"},}; }, methods: {rename() {this.name = "ying Zong "; This.qin. Ge = "first emperor ying Zheng "; }, }, // A.vue inject: ["name", "shoudu", "qin"] <! -- Use --> <p> asynchronous data: {{qin.ge}}</p>Copy the code
At this time to pass down the asynchronous data is: Qin Wang Zheng. Click qin Wang Zheng button, dynamic change to: first emperor Ying Zheng.
View the demo
Sibling/sibling components pass values
vuex
observable
EventBus
Sibling/sibling components, which have no direct affiliation, usually use Vuex, EventBus, and Observable to transfer values to such components.
The main focus here is EventBus, also known as EventBus or central EventBus. At the end of the day, Vue uses its own $ON and $emit.
Prerequisites: There are two sibling components A and B, with A common parent component (usually $root or A common parent component).
// App.vue
<template>
<div id="app">
<i-a />
<i-b />
</div>
</template>
<script>
import A from "./components/A";
import B from "./components/B";
export default {
name: "App",
components: {
"i-a": A,
"i-b": B,
},
};
</script>
Copy the code
Create a new Vue instance in main.js to ensure that all components can access it.
// The new instance is mounted on the Vue prototype, Prototype.$bus = new Vue() // a.vue created() {this.$bus.$on("amsg", (msg) => { this.msg = msg; }); }, methods: {setMsg() {// You can also submit A custom event this.$bus.$emit(" BMSG ", "A-> hW: hW "); }}, / / B.v ue created () {/ / custom events to monitor this. $bus. $on (" BMSG ", (MSG) = > {this. MSG = MSG; }); }, methods: {setMsg() {// You can also submit a custom event this.$bus.$emit("amsg", "B-> amSG "); }},Copy the code
Click the corresponding button to pass your information to other components.In fact, this method is not limited to sibling components, as long as any two components have a common parent or sibling component.
Note that when destroying the component, remember to remove the $ON bound event to avoid repeated listening.
BeforeDestroy () {this.$bus.$off(" BMSG ") // this.$bus.$off() Removes all bound events if no event name is specified. }Copy the code
View the demo
Routing by value
Operation URL implementation
location
ue-route: query
vue-route: params
After routing
// location location.href = 'https:// $routes. Push ({name: 'xx', query: {MSG: 'xx'}}) // vue-route: {routes: {routes: 'xx'}}) Params this.$routes. Push ({name: 'xx', params: {MSG: 'xx'}}) {path: '/ bw / : name, name:' bw} this. $routes. Push ({name: 'bw, params: {name: "chu overlord"}}) enclosing $routes. Push ({name: 'Bw', params: {name: 'xiang yu '}})Copy the code
Front-end storage implementation
localStorage
sessionStorage
cookie
indexedDB
Window by value
This is special, vUE is basically a single page application, rarely open two Windows at the same time, but also need to pass value processing. However, if this thing is embedded in the app, it is another story.
For some special use scenarios, the route jump embedded in app will be intercepted and the location jump will be used uniformly. Without opening a page, a new instance is created, and vuex and other internal things are invalid.
- LocalStorage updates the value by listening to the storage (ios webView is not aborting the event)
// Mounted () {window.addeventListener ('storage', this.setValfun, false)} methods: { setValFun(e) { if (e.storageArea? .val === '1') { //... Localstorage.removeitem ('val')}}} // B localStorage.setietm ('val', '1')Copy the code
The polling function queries the stored value
/ / A component mounted () {enclosing setValFun ()} the methods: {setValFun () {if (getCookie (' val) = = = '1') {/ /... DelCookie (' val)} setTimeout () = > {enclosing setValFun ()}, 1000)}} / / B component setCookie (' val ', '1', '1 d)Copy the code
One day
Minimalist encapsulates Observable
// store/index.js
const store = {
state: Vue.observable({
name: ''
}),
commit: {
setName(n) {
store.state.name = n
},
}
}
export default {
install: function() {
Vue.prototype.$store = store
}
}
// main.js
import store from './store'
Vue.use(store)
Copy the code