文档章节

Vue的Key属性,v-for和v-if,v-if/v-show,v-pre不渲染,v-once只渲染一次

达达前端
 达达前端
发布于 2019/11/03 21:09
字数 2272
阅读 42
收藏 0

3 月,跳不动了?>>>

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>

file

file

file

file

file

为什么使用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属性的作用

file

file

file

file

file

<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是如果触发组件更新的

file

file

file

<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();
 }
}
};

file

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

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

计算属性: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的生命周期的应用场景和函数式组件

生命周期:

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

file

创建阶段: beforeCreate created beforeMount render mounted

更新阶段 beforeUpdate render updated

销毁阶段 beforeDestory destoryed

file

创建阶段: beforeCreate created beforeMount render mounted

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

file

更新阶段多次更新的阶段

更新阶段

beforeUpdate render updated

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

file

销毁阶段: beforedestory destoryed

file

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

file

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

函数式组件: file

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

自定义指令: bind inserted update componentUpdated unbind

生命周期钩子

常用的高级特性provide/inject

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

属性,通信 事件,通信

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

引用信息

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

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

file

file

自动通知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之间的区别

file

file

file

如何在vue中使用vuex

file

file

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
 }
}

file

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到响应式数据中

file

file

vuex最佳实战

file

使用常量替代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

file vue touter的使用场景

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

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

提供多种方式改变Url的api

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

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

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

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

file

Nuxt解决了哪些问题?

file

file

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

file

file

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

file

提升开发效率

Vetur,ESLint,Prettier,Vue DevTools file

file

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

file

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

计算属性computed实现getters缓存

beforeCreate中混入$store的获取方式

file

file


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


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

欢迎关注达达的简书!

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

博客

© 著作权归作者所有

达达前端
粉丝 4
博文 226
码字总数 368531
作品 0
广州
程序员
私信 提问
加载中

评论(0)

前端与移动开发之vue-day1(3)

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

czbkzmj
2018/11/14
0
0
vue小白入手(二),对你多多少少会有一点帮助的

王叔叔又来了,小白第二篇为大家献上 一, 列表循环 功能:根据一组数据的选项列表进行渲染(自动for循环)。 语法: value,key in items / value,key for items vue.js 的循环渲染是依赖于 ...

王盼盼
2019/10/14
0
0
为什么v-for循环时要写上key

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保...

南蓝NL
2019/03/20
0
0
Vue 3.0 源码开放,看看都有哪些新特性

当大多数国人还在庆祝国庆节的时候,尤雨溪大大在昨天凌晨发布了 Vue 3.0 源代码,源码地址:github.com/vuejs/vue-n… 。虽然目前还 处于 Pre-Alpha 版本,但是可以预见后面的 Alpha、Beta ...

xiangzhihong
2019/10/06
0
0
浅析Vue.js 中的条件渲染指令

1 应用于单个元素 Vue.js 中的条件渲染指令可以根据表达式的值,来决定在 DOM 中是渲染还是销毁元素或组件。 html: <div id="app"><p v-if="type===1">拌面</p><p v-else-if="type===2">扁肉......

开元中国2015
2018/12/11
40
0

没有更多内容

加载失败,请刷新页面

加载更多

Flutter 强大的MediaQuery控件

注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 MediaQuery 通常情况下,不会直接将MediaQuery当作一个控件,而是使用MediaQuery.of获取当...

老孟程序员
24分钟前
22
0
【实战】2.如何写周报

如何写周报 一、周报的目的 以一个时间节点为准,同时做到向上汇报和向下汇报。向上汇报要做到整体项目的概况,让上级领导知道当前项目的整体状态。向下汇报要做到我们当前做了什么,紧接着的...

卖小女孩的小火柴
31分钟前
18
0
美颜重磅技术之GPUImage源码分析

说到基于GPU的图像处理和实时滤镜,大家肯定会想到鼎鼎大名的GPUImage,这个项目确实为后续开发提供了很多方便,基本的图像处理工具一应俱全。但是学习借鉴GPUImage的项目结构,可以为我们提...

码农突围
37分钟前
7
0
mapbox

Mapbox是一个可以跨行业使用的开发平台,我们可以利用它对地图进行创建和定制,以解决地图、数据和空间分析等问题。 Leaflet 轻量 WebGIS 前端类库 Leaflet 是一个为建设移动设备友好的互动地...

东东笔记
44分钟前
32
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部