- Have you encapsulated components??
- Talk about component packaging????
- How do you package components in the project?????
...
The above questions are the most frequently asked by interviewers? So how should you answer?
A: all the projects I developed with vue are developed with the idea of component. Generally, when I build a project, I will create a views directory, a common directory and a feature directory. In the views directory, I will put page level components, in common, I will put public components (such as head, foot, etc.), and in the feature directory, I will put functional components (such as swiper, tabbar, etc.) List (pull up to load more functional components)
First, components can improve the development efficiency of the whole project. It can abstract the page into several relatively independent modules, which solves the problems of our traditional project development: low efficiency, difficult maintenance and low reusability.
Benefits of using components
Components are reusable
Easy to maintain
Encapsulated and easy to use
Reduce repeatability between components in large projects
Global components
Reference global component my header
<body> <div id="main1"> <!-- During normal template parsing, the user-defined tags will not be interpreted, but the parameters in the self-defined components will be interpreted, that is, the following template Medium h1 label --> <my-header></my-header> </div> <div id="main2"> <!-- Custom components are reusable --> <my-header></my-header> </div> <div id="main3"> <my-header></my-header> </div> </body>
Register the global component my header
//Global component: label component that can be used anywhere, in any way and anywhere vue.component("my-header", { // The h1 tag is the tag of the parameter written in the user-defined primary key template: '<h1>title{{msg}}</h1>', data(){ return {msg:100} } }) new Vue({ el: '#main' }); new Vue({ el: '#main2' }); new Vue({ el: '#main3' });
Local component
Local component: it will only take effect within the scope specified by us.
<body> <div id="main"> <my-header></my-header> <my-header></my-header> </div> </body> new Vue({ el: '#main', components: { "my-header": { template: '<h1>title{{vue}}</h1>' } } })
be careful:
When defining a component with # kebab case, you must also use # kebab case when referencing this custom element, such as < My component name >
When defining a component with PascalCase (hump naming), you can use both naming methods when referring to this custom element. in other words
< My component name > and < mycomponentname > are acceptable. Note, however, that only kebab case is valid when used directly in DOM (i.e. non string templates)
//Middle dash usage syntax: < My component name >` Vue.component('my-component-name', { /* ... */ }) //Hump usage syntax: < My component name > ` and ` < mycomponentname > ` are OK Vue.component('MyComponentName', { /* ... */ })
Components in scaffold Vue cli
We usually develop projects through scaffolding vue cli, and each vue single file is a component. You need to define a child component in pronets and register the data in the child component. After the child component modifies the data, it wants to pass the data to the parent component. You can use the $emit method to trigger custom event delivery parameters.
Father to son (props)
The definition of prop should be as detailed as possible, and at least its type needs to be specified
<!-- Parent component --> <template> <div> <my-child :parentMessage="parentMessage"></my-child> </div> </template> <script> import MyChild from '@components/common/MyChild' export default { components: { MyChild }, data() { return { parentMessage: "I am a message from the parent component" } } } </script>
<!-- Subcomponents --> <template> <div> <span>{{ parentMessage }}</span> </div> </template> <script> export default { props: { parentMessage: { type: String, default: 'Information displayed by default' // require: true / / required } } } </script>
Pass parent component method through $on
Passing the parent component method through $on is a common method in component communication. It can achieve the same effect as passing through props. Compared with props passing function, it is more intuitive and shows the calling relationship
<!-- Parent component --> <template> <div> <my-child @childEvent="parentMethod"></my-child> </div> </template> <script> import MyChild from '@components/common/MyChild' export default { components: { MyChild, }, data() { return { parentMessage: 'I am a message from the parent component', } }, methods: { parentMethod() { alert(this.parentMessage) } } } </script>
<!-- Subcomponents --> <template> <div> <h3>Subcomponents</h3> </div> </template> <script> export default{ mounted() { this.$emit('childEvent') } } </script>
$parent gets the parent component and then uses the data in the parent component (not recommended)
To be exact, this method does not belong to data transmission, but an active search. The parent component does not actively transfer data to the child component, but the child component obtains the data of the parent component through its association with the parent component.
Although this method can obtain the data in the parent component, it is not recommended because vue advocates one-way data flow. Only the data handed over by the parent component to the child component can be used by the child component, and the child component is not allowed to obtain the data of the parent component without permission. In the relationship between father and son, neutron should be in a passive relationship
// this here is a sub component instance this.$parent
Pass parent component data through $emit (recommended)
Used in conjunction with $on in parent-child component communication, parameters can be passed to the method triggered in the parent component for use by the parent component
<!-- Parent component --> <template> <div> <my-child @childEvent="parentMethod"></my-child> </div> </template> <script> import MyChild from '@components/common/MyChild' export default { components: { MyChild }, data() { return { parentMessage: 'I am a message from the parent component' } }, methods: { parentMethod({ name, age }) { console.log(this.parentMessage, name, age) } } } </script>
<!-- Subcomponents --> <template> <div> <h3>Subcomponents</h3> </div> </template> <script> export default { mounted() { this.$emit('childEvent', { name: 'zhangsan', age: 10 }) } } </script>
refs get
You can add a ref attribute to the sub component, and then you can get the instance of the sub component through the ref attribute name. To be exact, this way is similar to this$ parent
The same does not belong to data transmission, but an active search.
Try to avoid using this method. Because in the process of parent-child component communication. The parent component is in a high position and has control, while the child component should be a pure view component in most cases, which is only responsible for the display of the view and the logical operation of its own view. The right of external interaction should be controlled by the parent component. Therefore, the parent component should transfer the view data to the child component, and the child component is responsible for the display. The external interaction of child components triggers the corresponding methods in the parent component through $emit, and then the parent component processes the corresponding logic
<!-- Parent component --> <template> <div> <my-child ref="child"></my-child> </div> </template> <script> import MyChild from '@components/common/MyChild' export default { components: { MyChild }, mounted() { console.log(this.$refs['child'].getData()); } } </script>
<!-- Subcomponents --> <script> export default { methods: { getData() { // do something... } } } </script>
Component style modification {style penetration
css parent component modifies styles in child components
If you want a selector in the scoped style to work "deeper", such as affecting sub components, you can use the > > > operator:
<style scoped> .a >>> .b { /* ... */ } </style>
The above code will be compiled into:
.a[data-v-f3f3eg9] .b { /* ... */ }
Syntax in sass
Some preprocessors like sass cannot parse > > > correctly. In this case, you can use the / deep / operator instead - it's an alias for > > > and works as well
<style scoped> .a /deep/ .b { /* ... */ } </style>