1. vue assembly
1.1 vue components_ concept
Componentization: the idea of encapsulation encapsulates the reusable parts of the page into components, so as to facilitate the development and maintenance of the project
A page can be divided into components. A component is a whole. Each component can have its own independent structure style and behavior (html, css and js)
1.2 vue components_ Basic use
Pithy formula: which part of the label is reused, which part is encapsulated in the component
(important): a template within a component can only have one root label
(important): data in the component must be a function with independent scope
Steps:
- Create component components/Pannel.vue
Encapsulation label + style + js - components are independent for reuse
- Registration component: it needs to be registered before use
The global entry is in main.js and registered on new Vue
Syntax:
import Vue from 'vue' import Component object from 'vue File path' Vue.component("Component name", Component object)
main.js - demo now
// Target: global registration (one definition everywhere) // 1. Create component - file name.vue // 2. Lead in components import Pannel from './components/Pannel' // 3. Global - register components /* Syntax: Vue.component("Component name (component object) */ Vue.component("PannelG", Pannel)
After the PannelG component name is registered globally, it can be used as a label in any Vue file template
Both single and double labels can be in lowercase plus - form. After running, the user-defined label will be parsed as a component and replaced to this position with the label encapsulated in the component
Local - registered useSyntax:
import Component object from 'vue File path' export default { components: { "Component name": Component object } }
1.3 vue component scoped function
Requirement: div tag name selector, setting background color
Problem: it is found that both the div in the component and the div outside the component are effective
Solution: add scoped attribute to style tag in Pannel.vue component
<style scoped>
Adding the scoped attribute to the style will add a randomly generated attribute starting with data-v to the label of this component, and it must be the element of the current component to have this custom attribute and be affected by this style
2. vue component communication
Because the variables and values of each component are independent
Component communication first focuses on the transfer of parent to child, and child to parent
Parent: vue files that use other components
Sub: introduced component (embedded)
For example: app.vue (parent) myproduct.vue (child)
2.0 vue component communication parent to child - props
Requirement: encapsulate a commodity component MyProduct.vue - externally input the specific data to be displayed, as shown in the following figure
Steps:
-
Create component components/MyProduct.vue - copy the label below
-
The props defined variable inside the component is used to receive the value passed in from the outside
-
The registration component is introduced into App.vue. When used, specific data is passed in to the component for display
components/MyProduct.vue - prepare label
<template> <div> <h3>title: {{ title }}</h3> <p>Price: {{ price }}element</p> <p>{{ intro }}</p> </div> </template> <script> export default { props: ['title', 'price', 'intro'] } </script> <style> .my-product { width: 400px; padding: 20px; border: 2px solid #000; border-radius: 5px; margin: 10px; } </style>
Use and pass in data in App.vue
<template> <div> <!-- target: father(App.vue) -> son(MyProduct.vue) Enter by value transfer respectively demand: Each component displays different data information step(Pithy formula): 1. Subcomponents - props - variable (Ready to receive) 2. Parent component - Pass the value in --> <Product title="Delicious salivary chicken" price="50" intro="Grand reward for opening, 20% off"></Product> <Product title="What a lovely adorable" price="20" intro="The boss is not at home, 10% off the court"></Product> <Product title="What an expensive Beijing roast duck" price="290" :intro="str"></Product> </div> </template> <script> // 1. Create a component (. vue file) // 2. Lead in components import Product from './components/MyProduct' export default { data(){ return { str: "How expensive, Come on, yummy" } }, // 3. Register components components: { // Product: Product // key and value variables have the same name - short form Product } } </script> <style> </style>
2.1 vue component communication parent-child cooperation cycle
data
list: [ { id: 1, proname: "Super delicious lollipop", proprice: 18.8, info: 'Grand reward for opening, 20% off' }, { id: 2, proname: "Super delicious big chicken leg", proprice: 34.2, info: 'Delicious but not greasy, Come and buy it' }, { id: 3, proname: "Super invincible ice cream", proprice: 14.2, info: 'hot summer , Have an ice cream' }, ],
<template> <div> <MyProduct v-for="obj in list" :key="obj.id" :title="obj.proname" :price="obj.proprice" :intro="obj.info" ></MyProduct> </div> </template> <script> // Target: recycle components - pass in data separately // 1. Create component // 2. Lead in components import MyProduct from './components/MyProduct' export default { data() { return { list: [ { id: 1, proname: "Super delicious lollipop", proprice: 18.8, info: "Grand reward for opening, 20% off", }, { id: 2, proname: "Super delicious big chicken leg", proprice: 34.2, info: "Delicious but not greasy, Come and buy it", }, { id: 3, proname: "Super invincible ice cream", proprice: 14.2, info: "hot summer , Have an ice cream", }, ], }; }, // 3. Register components components: { // MyProduct: MyProduct MyProduct } }; </script> <style> </style>Unidirectional data flow
The principle of one-way data flow should be followed in vue
- When the data of the parent component changes, the child component will automatically change
- The child component cannot directly modify the props passed by the parent component. Props is read-only
An object is passed from the parent component to the child component. When the child component modifies the properties of the object, it will not report an error. The object is a reference type and updates each other
2.2 Vue component communication one-way data flow
Target: the data flow from parent to child is called one-way data flow
Cause: the child component is modified without notifying the parent, resulting in data inconsistency
If the commodity price in the first MyProduct.vue is modified to 5.5, but 18.8 is still recorded in App.vue - the data is inconsistent
So: Vue specifies that the variables in props are read-only
2.3 Vue component communication child to parent
Requirements: in the example above, click the bargaining function to realize the random bargaining-1 function
Syntax:
- Parent: @ custom event name = "parent methods function"
- Child: this.$emit("custom event name", value transfer) - execute the function code in the parent methods
components/MyProduct_sub.vue
<template> <div> <h3>title: {{ title }}</h3> <p>Price: {{ price }}element</p> <p>{{ intro }}</p> <button @click="subFn">Treasure knife-Cut 1 yuan</button> </div> </template> <script> import eventBus from '../EventBus' export default { props: ['index', 'title', 'price', 'intro'], methods: { subFn(){ this.$emit('subprice', this.index, 1) // Son to father eventBus.$emit("send", this.index, 1) // Cross component } } } </script> <style> .my-product { width: 400px; padding: 20px; border: 2px solid #000; border-radius: 5px; margin: 10px; } </style>
App.vue
<template> <div> <!-- target: Son to father --> <!-- 1. Parent component, @Custom event name="father methods function" --> <MyProduct v-for="(obj, ind) in list" :key="obj.id" :title="obj.proname" :price="obj.proprice" :intro="obj.info" :index="ind" @subprice="fn" ></MyProduct> </div> </template> <script> import MyProduct from './components/MyProduct_sub' export default { data() { return { list: [ { id: 1, proname: "Super delicious lollipop", proprice: 18.8, info: "Grand reward for opening, 20% off", }, { id: 2, proname: "Super delicious big chicken leg", proprice: 34.2, info: "Delicious but not greasy, Come and buy it", }, { id: 3, proname: "Super invincible ice cream", proprice: 14.2, info: "hot summer , Have an ice cream", }, ], }; }, components: { MyProduct }, methods: { fn(inde, price){ // Logic code this.list[inde].proprice > 1 && (this.list[inde].proprice = (this.list[inde].proprice - price).toFixed(2)) } } }; </script> <style> </style>
2.4 vue component communication - EventBus
The relationship between the two components is very complex, and it is very troublesome to communicate through parent-child components. At this time, a general component communication scheme: event bus can be used
Core grammar
EventBus/index.js - defines the event bus object
import Vue from 'vue' // Export blank vue objects export default new Vue()
List.vue registration event - waiting to receive the value to be haggled - prepare brother page
<template> <ul> <li v-for="(item, index) in arr" :key="index"> <span>{{ item.proname }}</span> <span>{{ item.proprice }}</span> </li> </ul> </template> <script> export default { props: ['arr'], } </script> <style> .my-product { width: 400px; padding: 20px; border: 2px solid #000; border-radius: 5px; margin: 10px; } </style>
components/MyProduct_sub.vue
<template> <div> <h3>title: {{ title }}</h3> <p>Price: {{ price }}element</p> <p>{{ intro }}</p> <button @click="subFn">Treasure knife-Cut 1 yuan</button> </div> </template> <script> import eventBus from '../EventBus' export default { props: ['index', 'title', 'price', 'intro'], methods: { subFn(){ this.$emit('subprice', this.index, 1) // Son to father eventBus.$emit("send", this.index, 1) // Cross component } } } </script> <style> .my-product { width: 400px; padding: 20px; border: 2px solid #000; border-radius: 5px; margin: 10px; } </style>
List.vue code (EventBus receiver)
<template> <ul> <li v-for="(item, index) in arr" :key="index"> <span>{{ item.proname }}</span> <span>{{ item.proprice }}</span> </li> </ul> </template> <script> // Target: value transfer across components // 1. Introduce a blank vue object (EventBus) // 2. Receiver - $on listening event import eventBus from "../EventBus"; export default { props: ["arr"], // 3. After the component is created, listen to the send event created() { eventBus.$on("send", (index, price) => { this.arr[index].proprice > 1 && (this.arr[index].proprice = (this.arr[index].proprice - price).toFixed(2)); }); }, }; </script> <style> .my-product { width: 400px; padding: 20px; border: 2px solid #000; border-radius: 5px; margin: 10px; } </style>