Vue Interview (3)-Advanced vue features

The vue advanced features of the regular test (knowledge points)

1. Custom v-model

<template>
    <div>
        <p>vue 高级特性</p>
        <hr>
        <!-- 自定义 v-model -->
        <p>{{name}}</p>
        <CustomVModel v-model="name"/>
        <MixinDemo/>
    </div>
</template>
<script>
 export default {
    components: {
        CustomVModel
    },
    data() {
        return {
            name: 'name'
        }
    }
}
</script>

Color selector two-way data binding

customVModel.vue

<template>
    <!-- 例如:vue 颜色选择 -->
    <input type="text"
        :value="text1"
        @input="$emit('change1', $event.target.value)">
    <!--
        1. 上面的 input 使用了 :value 而不是 v-model
        2. 上面的 change1 和 model.event1 要对应起来
        3. text1 属性对应起来
    -->
</template>

<script>
export default {
    model: {
        prop: 'text1', // 对应 props text1
        event: 'change1'
    },
    props: {
        text1: String,
        default() {
            return ''
        }
    }
}
</script>

2. $nextTick

  vue is asynchronous rendering,

  After the data changes, the DOM will not be rendered immediately,

  $ nextTick will be triggered after DOM rendering to get the latest DOM node

<template>
  <div id="app">
    <ul ref="ul1">
        <li v-for="(item, index) in list" :key="index">
            {{item}}
        </li>
    </ul>
    <button @click="addItem">添加一项</button>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
      return {
        list: ['a', 'b', 'c']
      }
  },
  methods: {
    addItem() {
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)
        // 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
        // 2. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次(使用一次$nextTick)
        this.$nextTick(() => {
          // 获取 DOM 元素
          const ulElem = this.$refs.ul1
          // eslint-disable-next-line
          console.log( ulElem.childNodes.length )
        })
    }
  }
}
</script>

(Define ref = ul1 in the DOM element , then you can use this. $ Refs.ul1 to get the DOM element)

The effect of not using $ nextTick: Click once to output 3, click the second to output 6

In order to get the rendering result immediately after clicking: use $ nextTick

3. slot

  The role of the component slot: the parent component passes the content to the child component (the content of the template)

  Slot location: located in the template of the subcomponent

(1) Basic use

<template>
    <div>
        <p>vue 高级特性</p>
        <!-- slot -->
        <SlotDemo :url="website.url">
            {{website.title}}
        </SlotDemo>
    </div>
</template>

<script>
import SlotDemo from './SlotDemo'
export default {
    components: {
        SlotDemo
    },
    data() {
        return {
            name: '姓名',
            website: {
                url: 'http://imooc.com/',
                title: 'imooc',
                subTitle: '程序员的梦工厂'
            }
        }
    }
}
</script>

SlotDemo.vue

<template>
    <a :href="url">
        <slot>
            显示默认内容,即父组件没设置内容时
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {}
    }
}
</script>

(Effect: The link will be displayed in the form of a label and display the title content)

(2) Scope slot

<template>
    <a :href="url">
        <slot :slotData="website">
            {{website.subTitle}} <!-- 父组件不传内容时默认值显示 subTitle  -->
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {
            website: {
                url: 'http://wangEditor.com/',
                title: 'wangEditor',
                subTitle: '轻量级富文本编辑器'
            }
        }
    }
}
</script>

(If the value {{website.subTitle}} } is not passed in , the default subtitle of the subcomponent will be displayed)

Use : The scoped data in the child component allows the parent component to get it

<ScopedSlotDemo :url="website.url">
            <template v-slot="slotProps">
                {{slotProps.slotData.title}}
            </template>
 </ScopedSlotDemo>

Effect: The page displays subcomponent content wangEditor

(Thoughts: Define the dynamic attribute slotData in the slot, and then define it on the website, which contains the title and subtitle. Then use the ScopedSlotDemo in the index to define v-slot = " slotProps " . Then you can use slot Props.slot DaTa Get the content of the website in the ScopedSlotDemo component, so you can get the title of the website)

(3) Named slot

Named slots-match based on content-no name will match by default

When the parent component passes the content to the child component, it needs to correspond to the good name

4. Dynamic components and asynchronous components

(1) Dynamic components

  Usage: : is = component-name

  Scenes that need to be dynamically rendered based on data. That is, the component type is not determined. (Generally, the component type is determined)

Example usage scenario: news detail page. (The position or type of the component is uncertain. That is, you do n’t know what kind of component to render, only the data. You need to determine the type of the component based on the data, then you need to use the dynamic component)

<template>
    <div>
        <p>vue 高级特性</p>
        <!-- 动态组件 -->
        <!-- <component :is="NextTickName"/> -->
        <div v-for="(index, value) in newsData" :key="index">
            <component :is="value.type"></component>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            name: 'name',
             // NextTickName: "NextTick",
            newsData: {
                1: {type: 'text'},
                2: {type: 'text'},
                3: {type: 'image'},
            }
        }
    }
}
</script>

(Render based on the acquired components (text, image))

(2) Asynchronous components

  Import function

  Load large components on demand and asynchronously

(Whenever you use it, you load it at any time. If you do n’t use it, it will never load. It is suitable for larger and more complex components, which will optimize performance)

Use the statement import SlotDemo from './SlotDemo' to load synchronously

<!-- 异步组件 -->
        <FormDemo v-if="showFormDemo"/>
        <button @click="showFormDemo = true">show form demo</button> 

// 然后在components里面写
components: {
       FormDemo: () => import('../BaseUse/FormDemo'),
    }

Effect: FormDemo will not be loaded when there is no click, it will be loaded and rendered after clicking

5.keep-alive

  Cache component

  Frequent switching, no need to repeat rendering

  Vue common performance optimization

KeepAlive.Vue introduces three components KeepAliveAtageA, KeepAliveAtageB, KeepAliveAtageC are three buttons

Click on the BC effect in turn:

Do not use keep alive

Use keepalive

A mounted

A destroyed

B mounted

B destroyed

C mounted

C destroyed

A mounted

A created

B created

C created

<KeepAliveStageA v-if="state === 'A'"/> 

<KeepAliveStageB v-if="state === 'B'"/>

<KeepAliveStageC v-if="state === 'C'"/>

 

<keep-alive> <!-- tab 切换 -->

            <KeepAliveStageA v-if="state === 'A'"/>

            <KeepAliveStageB v-if="state === 'B'"/>

            <KeepAliveStageC v-if="state === 'C'"/>

 </keep-alive>

The difference between using keep-alive and v-show:

v-show is controlled by native CSS (usage: tags are relatively simple)

Keepalive is the rendering of JS objects at the vue framework level (use case: complex component switching with level or tab switching)

<template>
    <div>
        <button @click="changeState('A')">A</button>
        <button @click="changeState('B')">B</button>
        <button @click="changeState('C')">C</button>

        <keep-alive> <!-- tab 切换 -->
            <KeepAliveStageA v-if="state === 'A'"/> <!-- v-show -->
            <KeepAliveStageB v-if="state === 'B'"/>
            <KeepAliveStageC v-if="state === 'C'"/>
        </keep-alive>
    </div>
</template>

<script>
import KeepAliveStageA from './KeepAliveStateA'
import KeepAliveStageB from './KeepAliveStateB'
import KeepAliveStageC from './KeepAliveStateC'

export default {
    components: {
        KeepAliveStageA,
        KeepAliveStageB,
        KeepAliveStageC
    },
    data() {
        return {
            state: 'A'
        }
    },
    methods: {
        changeState(state) {
            this.state = state
        }
    }
}
</script>

keepAliveStateA.vue

<template>
    <p>state A</p>
</template>

<script>
export default {
    mounted() {
        // eslint-disable-next-line
        console.log('A mounted')
    },
    destroyed() {
        // eslint-disable-next-line
        console.log('A destroyed')
    }
}
</script>

6. mixin

  Multiple components have the same logic, extracted from them

  Mixin is not the perfect solution, there will be problems

  The composition API proposed by Vue 3 aims to solve these problems

(Mixin is a piece of js code)

Problems with Mixin

(1) The source of the variable is unknown, which is not conducive to reading

(2) Multiple mixins may cause naming conflicts

(3) There may be a many-to-many relationship between Mixin and components, with high complexity

<template>
    <div>
        <p>{{name}} {{major}} {{city}}</p>
        <button @click="showName">显示姓名</button>
    </div>
</template>

<script>
import myMixin from './mixin'

export default {
    mixins: [myMixin], // 可以添加多个,会自动合并起来
    data() {
        return {
            name: 'zs',
            major: 'web'
        }
    },
    methods: {
    },
    mounted() {
        // eslint-disable-next-line
        console.log('component mounted', this.name)
    }
}
</script>

mixin.js

export default {
    data() {
        return {
            city: '北京'
        }
    },
    methods: {
        showName() {
            // eslint-disable-next-line
            console.log(this.name)
        }
    },
    mounted() {
        // eslint-disable-next-line
        console.log('mixin mounted', this.name)
    }
}

 

Published 26 original articles · won 6 · views 1393

Guess you like

Origin blog.csdn.net/Sabrina_cc/article/details/105366601