Getting Started with Vue Scaffolding Development

Getting Started with Vue Scaffolding Development

Install scaffolding and initialize the project

skip

Subsequent use of the project is a newly built project

communication between components

father to son

Check out the article "Vue Initializes Project Loading Logic"
Parent Component
insert image description here
Sub Component
insert image description here

child's father

Scenario: For example, in your shopping cart, there are many products in it. Each product is a small component, and each component has an element of price. The price of other small components is not clear between each component. Now I want to calculate the total Price, the total price of the shopping cart is in the big component of the shopping cart, so now I need to pass the value of the price of each small component to the big component of the shopping cart

For example, we can use the HelloWorld of the new project, and delete some other messy things

Actions for subcomponents

<template>
  <div class="hello">
    <!--点击按钮,触发方法,方法里有自定义事件-->
    <button @click="handler">按钮</button>
  </div>
</template>

<script>
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  data(){
    
    
    return{
    
    
      childCount:0 //没有特殊含义,只是用来标识这个值来自于子类,见名知意,后续将这个值传给父组件
    }
  },
  methods:{
    
    
    handler(){
    
    
      this.childCount++
      this.$emit('child-count-change',this.childCount)  //子传父,需要通过自定义事件来处理,这里就是自定义事件设置,通过this.$emit()来触发自定义事件
      //第一个参数,我们先随便编造一个事件,就叫child-count-change
      //第二个参数,就是事件要传入的数据
      //总结一下,就是只要一触发child-count-change事件,就会将this.childCount传入进去
      //那这个时间由谁来做一个响应的处理呢,就需要去父组件里进行一个监听
    }
  }
}
</script>

<style scoped>
h3 {
    
    
  margin: 40px 0 0;
}
ul {
    
    
  list-style-type: none;
  padding: 0;
}
li {
    
    
  display: inline-block;
  margin: 0 10px;
}
a {
    
    
  color: #42b983;
}
</style>

Actions of the parent component

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld 
    msg="Welcome to Your Vue.js App"
    @child-count-change="handlerFather" 
    ></HelloWorld>
    <!--1、这里的@child-count-change,就是我们在子组件里的自定义实践,绑定到了handlerFather这个方法上,在methods里实现-->
    <p>父组件中接受的插值是: {
    
    {
    
    childData}}</p>
    <!--3、用来展示从子组件传递过来的值,只是方便观察-->
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
    
    
  name: 'HomeView',
  data(){
    
    
    return{
    
    
      childData: 0  //2、定义一个响应式数据,之后用来承接子组件传过来的值
    }
  },
  components: {
    
    
    HelloWorld
  },
  methods:{
    
    
    //4、还记得我们在子组件里将childCount这个值传进来了
    handlerFather(childCount){
    
    
        this.childData=childCount  //5、将子组件传进来的值复制给父组件的响应式数据,按常理这里一定是更复杂的操作,例如求和等等,这样写只是为了方便而已
    }
  }
}
</script>

Result display

The button is a child component, and the copy is a parent component
insert image description here

component slot

For example, now there is only one button in the helloworld component, which is its core function, but for example, if we want to have a different presentation every time we use this component

default slot

The original look of the child component

<template>
  <div class="hello">
    <button @click="handler">按钮</button>
  </div>
</template>

the content of the parent component

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld 
    msg="Welcome to Your Vue.js App"
    @child-count-change="handlerFather" 
    ></HelloWorld>
    <p>{
    
    {
    
    childData}}</p>
    <!--1、多写几个helloworld组件,想要展示有所不同,像下面再双标签中间写的内容就是给插槽的内容,可以在子组件中规定你给插槽的内容在哪里去展示-->
    <HelloWorld>这是默认内容1</HelloWorld>
    <HelloWorld>这是默认内容2</HelloWorld>
    <HelloWorld>这是默认内容3</HelloWorld>    
    <HelloWorld></HelloWorld>    

  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
    
    
  name: 'HomeView',
  data(){
    
    
    return{
    
    
      childData: 0  
    }
  },
  components: {
    
    
    HelloWorld
  },
  methods:{
    
    
    
    handlerFather(childCount){
    
    
        this.childData=childCount  
    }
  }
}
</script>


Now the page looks like this
insert image description here

Next define the content of the slot in the child component

<template>
  <div class="hello">
    <!--1、比如我想要将父组件传进来的值放在前面,这个slot并不是一个真正的标签,如果父组件给值了,那就展示父组件的值,没给值,那就展示我们给的默认的-->
    <slot>基础的默认内容</slot>
    <button @click="handler">按钮</button>
  </div>
</template>

<script>
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  data(){
    
    
    return{
    
    
      childCount:0 
    }
  },
  methods:{
    
    
    handler(){
    
    
      this.childCount++
      this.$emit('child-count-change',this.childCount)  
    }
  }
}
</script>

<style scoped>
h3 {
    
    
  margin: 40px 0 0;
}
ul {
    
    
  list-style-type: none;
  padding: 0;
}
li {
    
    
  display: inline-block;
  margin: 0 10px;
}
a {
    
    
  color: #42b983;
}
</style>

insert image description here
Simpler than props, you can also write "this is the default content" as html

The meaning of the slot

In addition to being more convenient than prop, it also means that part of the child component is open to the parent component, rather than all defined by the child component, which is more flexible

named slot

There is a problem with the default slot, that is, this one. If there are multiple slots, how do we distinguish the value passed from the parent component, which slot is displayed in the child component, which requires a named slot

Subcomponent changes

<template>
  <div class="hello">
    <slot>基础的默认内容</slot>
    <button @click="handler">按钮</button>
    <!--新建一个插槽,但是插槽带了一个name属性,并且给一个默认值是:footer的默认内容-->
    <slot name="footer">footer的默认内容</slot>
  </div>
</template>

<script>
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  data(){
    
    
    return{
    
    
      childCount:0 
    }
  },
  methods:{
    
    
    handler(){
    
    
      this.childCount++
      this.$emit('child-count-change',this.childCount)  
    }
  }
}
</script>

<style scoped>
h3 {
    
    
  margin: 40px 0 0;
}
ul {
    
    
  list-style-type: none;
  padding: 0;
}
li {
    
    
  display: inline-block;
  margin: 0 10px;
}
a {
    
    
  color: #42b983;
}
</style>

Changes to the parent component

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld 
    msg="Welcome to Your Vue.js App"
    @child-count-change="handlerFather" 
    ></HelloWorld>
    <p>{
    
    {
    
    childData}}</p>
    <HelloWorld>这是默认内容1</HelloWorld>
    <HelloWorld>这是默认内容2</HelloWorld>
    <HelloWorld>这是默认内容3</HelloWorld>    
    <HelloWorld></HelloWorld>    
    <!--新建一个子组件,通过template标签,里面的v-slot:footer(或者#footer也可以)来将标签里的内容绑定给子组件名为footer的插槽,而不是其他插槽-->
    <HelloWorld>
      <template v-slot:footer>这是专门给子组件footer插槽的内容</template>
    </HelloWorld>
    <!--或者,将v-slot:替换成#-->
    <HelloWorld>
      <template #footer>这是专门给子组件footer插槽的内容2</template>
    </HelloWorld>
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
    
    
  name: 'HomeView',
  data(){
    
    
    return{
    
    
      childData: 0  
    }
  },
  components: {
    
    
    HelloWorld
  },
  methods:{
    
    
    
    handlerFather(childCount){
    
    
        this.childData=childCount  
    }
  }
}
</script>

insert image description here

Use the data of the child component through the slot in the parent component

<template>
  <div class="hello">
    <slot>基础的默认内容</slot>
    <button @click="handler">按钮</button>
    <slot name="footer" >footer的默认内容</slot>
  </div>
</template>

As far as the slot of the subcomponent above is concerned, this slot belongs to the subcomponent rather than the parent component. If the parent component wants to use the data of the subcomponent, it needs to use the scope slot method to make a setting

Subassembly

<template>
  <div class="hello">
    <slot>基础的默认内容</slot>
    <button @click="handler">按钮</button>
    <!--现在我们在子组件的插槽中,绑定了一个响应式数据-->
    <slot name="footer" :childCount="childCount">footer的默认内容</slot>
  </div>
</template>

<script>
export default {
    
    
  name: 'HelloWorld',
  props: {
    
    
    msg: String
  },
  data(){
    
    
    return{
    
    
      childCount:0 
    }
  },
  methods:{
    
    
    handler(){
    
    
      this.childCount++
      this.$emit('child-count-change',this.childCount)  
    }
  }
}
</script>

<style scoped>
h3 {
    
    
  margin: 40px 0 0;
}
ul {
    
    
  list-style-type: none;
  padding: 0;
}
li {
    
    
  display: inline-block;
  margin: 0 10px;
}
a {
    
    
  color: #42b983;
}
</style>

parent component

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld 
    msg="Welcome to Your Vue.js App"
    @child-count-change="handlerFather" 
    ></HelloWorld>
    <p>{
    
    {
    
    childData}}</p>
    <!-- 我们通过 #footer="dataObj"的方式,获取了从子组件传进来的值,并重命名为dataObj,这个值,定义了就一定要使用,要不然会报错的-->
    <!-- 虽然子组件传进来的看起来是一个值,其实是一个对象 -->
    <HelloWorld>
      <template #footer="dataObj">这是专门给子组件footer插槽的内容{
    
    {
    
    dataObj }}</template>
    </HelloWorld>
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
    
    
  name: 'HomeView',
  data(){
    
    
    return{
    
    
      childData: 0  
    }
  },
  components: {
    
    
    HelloWorld
  },
  methods:{
    
    
    
    handlerFather(childCount){
    
    
        this.childData=childCount  
    }
  }
}
</script>

insert image description here
You see, what is passed in is
{ "childCount": 0 }
instead of a value of
0
if you only want to use a certain value

parent component

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld 
    msg="Welcome to Your Vue.js App"
    @child-count-change="handlerFather" 
    ></HelloWorld>
    <p>{
    
    {
    
    childData}}</p>
    <!-- 我们通过 dataObj.字段名的方式来获取某一个值-->
    <HelloWorld>
      <template #footer="dataObj">这是专门给子组件footer插槽的内容{
    
    {
    
    dataObj.childCount }}</template>
    </HelloWorld>
    <!-- 或者,直接在绑定的时候就绑定其中的某一个字段 -->
    <HelloWorld>
      <template #footer="{childCount}">这是专门给子组件footer插槽的内容二{
    
    {
    
    childCount }}</template>
    </HelloWorld>  
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
    
    
  name: 'HomeView',
  data(){
    
    
    return{
    
    
      childData: 0  
    }
  },
  components: {
    
    
    HelloWorld
  },
  methods:{
    
    
    
    handlerFather(childCount){
    
    
        this.childData=childCount  
    }
  }
}
</script>

insert image description here

Guess you like

Origin blog.csdn.net/qq13933506749/article/details/131539992