key属性为什么要加

key -- api 解释

key的特殊属性主要用在vue的虚拟dom算法,如果不适用key,vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用Key,它会基于Key的变化重新排列元素顺序,并且会移除Key不存在的元素。

v-for为什么要加Key

<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div> <ul>
<li v-for="(item, i) in list">
<input type="checkbox">
{{item.name}}
</li>
</ul> <script>
// 创建vue实例,得到viewmodel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{id:1,name''}
]
},
methods: {
add() {
this.list.unshift({
id: this.newId,
name: this.name })
this.name=""
}
}
});
</script>
</div>

有key

  <div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div>
<ul>
<li v-for="(item, i) in list" :key="item.id">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: '' },
{ id: 2, name: '' },
{ id: 3, name: '' }
]
},
methods: {
add() {
//注意这里是unshift
this.list.unshift({ id: this.newId, name: this.name })
this.name = ''
}
}
});
</script>
</div>

为什么使用v-for时必须添加唯一的key?

const list = [
{
id: 1,
name: 'test1',
},
{
id: 2,
name: 'test2',
},
{
id: 3,
name: 'test3',
},
]
<div v-for="(item, index) in list" :key="index" >{{item.name}}</div>
const list = [
{
id: 1,
name: 'test1',
},
{
id: 2,
name: 'test2',
},
{
id: 3,
name: 'test3',
},
{
id: 4,
name: '我是在最后添加的一条数据',
},
]
const list = [
{
id: 1,
name: 'test1',
},
{
id: 4,
name: '我是插队的那条数据',
}
{
id: 2,
name: 'test2',
},
{
id: 3,
name: 'test3',
},
]

两个相同的组件产生类似的dom结构,不同的组件产生不同的dom结构。

同一层级的一组节点

特殊特性key

预期:number | string

key的特殊属性主要用在vue的虚拟dom算法,在新旧nodes对比时辨识vnodes。

<ul>
<li v-for="item in items" :key="item.id"></li>
</ul>

它可以用于强制替换元素,组件而不是重复使用它。

完整地触发组件的生命周期钩子触发过渡

<transition>
<span :key="text">{{text}}</span>
</transition>

ref被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs对象上。如果在普通的dom元素上使用,引用指向就是dom元素,如果用在子组件上,引用就指向组件实例:

<p ref="p"> hello </p>

<child-component ref="child"></child-component>

v-for用于元素或组件的时候,引用信息将包含dom节点或组件实例的数组

is用于动态组件且基于dom内模板的限制来工作

<component v-bind:is="currentView"></compoent>

<table>
<tr is="my-row"></tr>
</table>
data: function () {
return {
todos: [
{
id: 1,
text: '学习使用 v-for'
},
{
id: 2,
text: '学习使用 key'
}
]
}
}
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.text }}
</li>
</ul>

永远不要把 v-if 和 v-for 同时用在同一个元素上。

为了过滤一个列表中的项目

v-for="user in users" v-if="user.isActive"
v-for="user in users"
v-if="shouldShowUsers"
<ul>
<li v-for="user in users"
v-if="user.isActive"
:key="user.id">
{{ user.name }}
</li>
</ul>
this.users.map(function (user) {
if (user.isActive) {
return user.name
}
})
computed: {
activeUsers: function() {
return this.user.filter(function (user) {
return user.isActive
})
}
}
<ul>
<li v-for="user in activeUsers"
:key="user.id">
{{user.name}}
</li>
</ul>
<ul>
<li v-for="user in users" v-if="shouldShowUsers" :key="use.id">
{{user.name}}
</li>
</ul>
<ul>
<li v-for = "user in users"
v-if="user.isActive"
:key="user.id">
{{user.name}}
</li>
</ul> <ul>
<li v-for="user in users"
v-if="shouldShowUsers"
:key="user.id">
{{user.name}}
</li>
</ul>
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
<template>
<button class="btn btn-close">X</button>
</template> <style>
.btn-close {
background-color: red;
}
</style>
<template>
<button class="button button-close">X</button>
</template> <!-- 使用 `scoped` 特性 -->
<style scoped>
.button {
border: none;
border-radius: 2px;
} .button-close {
background-color: red;
}
</style>
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template> <!-- 使用 CSS Modules -->
<style module>
.button {
border: none;
border-radius: 2px;
} .buttonClose {
background-color: red;
}
</style>
<template>
<button :class="[$style.button, $style.buttonClose]">X</button>
</template> <!-- 使用 CSS Modules -->
<style module>
.button {
border: none;
border-radius: 2px;
} .buttonClose {
background-color: red;
}
</style>
<template>
<button class="c-Button c-Button--close">X</button>
</template> <!-- 使用 BEM 约定 -->
<style>
.c-Button {
border: none;
border-radius: 2px;
} .c-Button--close {
background-color: red;
}
</style>

虚拟Dom以及Key属性的作用

<template>
<div id="app">
<input v-model="message" >
<input :value="message" @input="handleChange">
{{message}} {{message * message}}
<div :id="message"></div>
<todo-list>
<todo-item @delete="handleDelete" v-for="(item, index) in list" :key="index" :title="item.title" :del="">
<template v-slot:pre-icon="{value}">
<span>{{value}}</span>
</template>
</todo-item>
</todo-list>

vue是如果触发组件更新的

<script>
export default{
name: " ",
props: {
info: Object,
name: String,
list: Array
},
data(){
return {
a: ' ',
b: ' '
};
},
updated() {
console.log(' ');
},
methods: {
handleBChange() {
this.b = "vue" Date.now();
}
}
};

合理应用计算属性和侦听器

减少模板中计算逻辑数据缓存依赖固定的数据类型(响应式数据)

计算属性:computed

<p>{{ reversedMessage1 }}</p>
<p>{{ reversedMessage2() }}</p>
<p> {{ now }} </p>
<button @click="() => $forceUpdate()">forceUpdate</button>
<br/>
<input v-model="message"/> export default {
data() {
return {
message: 'hello'
};
}, computed: {
// 计算属性的getter
reversedMessage1: function() {
return this.message
.split("")
.reverse()
.join("");
},
now: function() {
return Date.now();
}
},
methods: {
reversedMessage2: function() {
return this.message
.split("")
.reverse()
.join("");
}

侦听器watch更加灵活,通用watch中可以执行任何逻辑,如函数节流,ajax异步获取数据

<div>
{{$data}}
<br/>
<button @click="() => (a = 1)"><button>
</div> wxport default {
data: function() {
return {
a: 1,
b: {c:2,d:3},
e: {
f: {
g: 4
}
},
h: []
};
},
watch: {
a: function(val, oldVal) {
this.b.c = 1;
},
"b.c": function(val, oldVal) {
this.b.d = 1;
},
"b.d": function(val, oldVal) {
this.e.f.g = 1;
}

computed vs watch

computed能做的,watch都能做,反之不行能computed的尽量用computed

<div>
{{ fullName }}
<div> firstName: <input v-model="firstName"/></div>
<div> lastName: <input v-model="lastName"/></div>
</div> export default {
data: function() {
return {
firstName: 'foo',
lastName: 'bar'
};
},
computed: {
fullName: function() {
return this.firstName " " this.lastName;
}
},
watch: {
fullName: function(val, oldVal) {
console.log("new",val,oldVal);
}
}

vue的生命周期的应用场景和函数式组件

生命周期:

创建阶段,更新阶段,销毁阶段

创建阶段:beforeCreatecreatedbeforeMountrendermounted

更新阶段beforeUpdaterenderupdated

销毁阶段beforeDestorydestoryed

创建阶段:beforeCreatecreatedbeforeMountrendermounted

初始化事件和生命周期beforeCreate数据观测,属性,侦听器配置created模板编译到renderbeforeMountrendermounted异步请求,操作dom,定时器等

更新阶段多次更新的阶段

更新阶段

beforeUpdaterenderupdated

依赖数据改变或$forceUpdate强制刷新beforeUpdate移除已经添加的事件监听器等万万不可更改renderupdated操作dom添加事件监听器等万万不更改依赖数据

销毁阶段:beforedestorydestoryed

watch: {
start() {
this.startClock();
}
},

函数式组件:functional:true无状态,无实例,没有this上下文,无生命周期

函数式组件:

vue指令的本质

v-text

v-html

v-show

v-if

v-else

v-else-if

v-for

v-on

v-bind

v-model

v-slot

v-pre

v-cloak

v-once

自定义指令:bindinsertedupdatecomponentUpdatedunbind

生命周期钩子

常用的高级特性provide/inject

解决的问题为组件的通信问题

属性,通信事件,通信

如何优雅地获取跨层级组件实例:拒绝递归

引用信息

<p ref="p">hello</p>

<child-component ref="child"></child-component>

自动通知setXXXref主动获取getxxxref

<button @click="getEH3Ref"></button

export default {
components: {
ChildrenB,
ChildrenC,
ChildrenD
},
provide() {
return {
setChildrenRef: (name, ref) => {
this[name] = ref;
},
getChildrenRef: name => {
return this[name];
},
getRef: () => {
return this;
}
};
},
<ChildrenH v-ant-ref="c => setChildrenRef("childrenH", c)"/>

export default {
components: {
ChildrenG,
ChildrenH,
ChildrenI
},
inject: {
setChildRef: {
default: () = {}
}
}
};

template和jsx之间的区别

如何在vue中使用vuex

import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue' Vue.use(Vuex)
Vue.config.productionTip = false const store = Vue.Store({
state: {
count: 0,
}
}) new Vue({
store,
render: h => h(App),
}).$mount('#app')
increment({commit}) {
setTimeout(()=>{
commit('increment')
}, 3000)
}
<template>
<div id="app">
{{count}}
</div>
</template> <script>
export default {
name: 'app',
computed: {
count() {
return this.$store.state.count
}
}
}
</script>
<button @click="$store.commit('increment', 2)">count  </button>
mutations: {
increment(state, n) {
state.count = n
}
}

vuex核心概念以及底层原理

核心概念state->this.$store.state.xxx取值getter->this.$store.getters.xxx取值

mutation->this.$store.commit("xxx")赋值action->this.$store.dispatch("xxx")赋值

module

底层原理:State:提供一个响应式数据Getter:借助Vue的计算属性computed来实现缓存

mutation:更改state方法action:触发mutaion方法module:Vue.set动态添加state到响应式数据中

vuex最佳实战

使用常量替代mutation事件类型

// mutation-type.js
export const SOME_MUTATION="SOME_MUTATION“ // store.js
import Vuex from 'vues'
import { SOME_MUTATION } from '' const store = new Vuex.Store({
state: { ... },
mutations {
[SOME_MUTATION] (state) {
}
}
})

传统开发模式

www.xxx.com - index.html
www.xxx.com/about -about.html

vue touter的使用场景

监听url的变化,并在变化前后执行相应的逻辑

不同的url对应不同的不同的组件

提供多种方式改变Url的api

使用方式:提供一个路由配置表,不同url对应不同组件的配置初始化路由实例new VueRouter()

挂载到vue实例上提供一个路由占位,用来挂载Url匹配到的组件

选择何种模式的路由以及底层原理

hash模式:丑,无法使用锚点定位

Nuxt解决了哪些问题?

Nuxt核心原理,SSR的核心原理

Ui组件对比Element UI,ANT design vue,iview

提升开发效率

Vetur,ESLint,Prettier,Vue DevTools

Vuex是通过什么方式提供响应式数据的?

扩展简化版的min-vuex,实现getters,并实现Vuex的方式注入$store

计算属性computed实现getters缓存

beforeCreate中混入$store的获取方式

若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。

请点赞!因为你们的赞同/鼓励是我写作的最大动力!

欢迎关注达达的简书!

这是一个有质量,有态度的博客

Vue的Key属性,v-for和v-if,v-if/v-show,v-pre不渲染,v-once只渲染一次的更多相关文章

  1. VUE router-view key 属性解释

    router-view 作用, 你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的. <template> <section clas ...

  2. Vue指令之`v-for`和`key`属性

    2.2.0+ 的版本里,**当在组件中使用** v-for 时,key 现在是必须的. 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “**就地复用**” 策略.如果数据项 ...

  3. Vue学习笔记【9】——Vue指令之v-for和key属性

    迭代数组(普通数组.对象数组) <ul> <li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name ...

  4. vue v-for循环中key属性的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. (转)Vue种key的作用

    https://blog.csdn.net/qq_41861679/article/details/80659278 https://cn.vuejs.org/v2/api/#key 其实不只是vue ...

  6. Vue2.x源码学习笔记-Vue实例的属性和方法整理

    还是先从浏览器直观的感受下实例属性和方法. 实例属性: 对应解释如下: vm._uid // 自增的id vm._isVue // 标示是vue对象,避免被observe vm._renderProx ...

  7. Vue(十二)vue实例的属性和方法

    vue实例的属性和方法 1. 属性 vm.$el vm.$data vm.$options vm.$refs <!DOCTYPE html> <html lang="en& ...

  8. vue实例的属性和方法

    vue实例的属性和方法 1. 属性 vm.$el #指定要绑定的元素 vm.$data #Vue 实例的数据对象 vm.$options #获取自定义属性的值 new Vue({ customOpti ...

  9. vue 使用key唯一令牌解决表单值混乱

    vue在渲染元素时,出于效率考虑,会尽可能地复用已有元素的而非重新渲染,如果你不希望这样可以使用Vue中提供的key属性,它可以让你决定是否要复用元素,key值必须是唯一的 代码: <!doct ...

随机推荐

  1. SUSE12Sp3-安装DockerCE和Docker-compose

    最近在写脚本.发现还是很方便的. Docker下载地址:https://download.docker.com/linux/static/stable/x86_64/ 执行以下脚本即可安装完毕. #! ...

  2. c# Windows服务管理

    .NET Framework中提供的类库可以很方便的实现对windows服务的安装.卸载.启动.停止.获取运行状态等功能.这些类都在System.ServiceProcess命名空间下. 所以,在开始 ...

  3. 2019 草花手游java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.草花手游等公司offer,岗位是Java后端开发,因为发展原因最终选择去了草花手游,入职一年时间了,也成为了面 ...

  4. xcode模拟器使用常用的命令。

    1.查看模拟器的udid用的 xcrun instruments -s xcrun simctl list 2.启动这个模拟器: xcrun instruments -w 'B39EC2FF-8A8B ...

  5. Vue相关知识点记录

    1.安装 vue不支持ie8以下版本(无法模拟ECMAScript5特性),支持所有兼容ECMAScript5的浏览器. 浏览器安装Vue Devtools, 可以在更友好的界面中审查和调试Vue应用 ...

  6. npm安装时-S -D作用及区别

    -S 即--save(保存) 包名会被注册在package.json的dependencies里面,在生产环境下这个包的依赖依然存在 -D 即--dev(生产) 包名会被注册在package.json ...

  7. JS项目练习之求和(包含正则表达式验证)

    最近在准备专升本,抽一点时间敷衍一下大家!!!嘿嘿嘿!!! 话不多说,上代码: <!DOCTYPE html> <html lang="zh-CN"> &l ...

  8. 关于web浏览器的Web SQL和IndexedDB

    虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数 ...

  9. git https解决免ssL和保存密码

    1.打开windows的git bash set GIT_SSL_NO_VERIFY=true git clonegit config --global http.sslVerify false  2 ...

  10. 设计模式 结构型 - 适配器模式 Adapter

    Adapter(适配器模式) ---- 加个“适配器”以便于复用 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 应用场景 如果 ...