1、使用vue中的v-for时,为什么要绑定:key?如果不绑定会有什么效果?**
因为vue组件高度复用,增加Key可以标识组件的唯一性,为了更好的区别组件,key的作用主要是为了高效的更新虚拟DOM保持数据的唯一,如果不绑定会造成数据混乱,不利于维护,不绑定会导致所有列表DOM重新渲染。
这个问题涉及到了虚拟Dom的更新过程和策略。当渲染的数据发生改变时,会生成新的虚拟Dom树和老的虚拟Dom树进行比较,返回对Dom树的更新操作。
以列表渲染为例,如果数据项的顺序被改变,为了尽量减少Dom的渲染操作,Vue将不是移动DOM元素来匹配数据项的改变(更不是全部销毁重新渲染),而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素,即就地复用策略。
比如:
在BC中间插入一个新的节点,如果不指定key,在页面Dom的真实变更如下:
原来ACBDE的Dom其实没有变化,只是在最后增加一个Dom,将原来显示C的Dom显示的内容改为显示F,依次类推。就是说,原来显示C对应的Dom假设在浏览器中的ID是C_dom,更新后显示C的Dom对应的ID就变成D_dom了。这样的方式其实不是更新的最优解。
有一个严重的问题就是,v-for如果不指定key,如果列表不只是展示功能,而是有勾选选中功能时,更新前后会导致选中项的错误变化。比如下面这个例子,一个可勾选的列表,可以动态的在列表顶端增加项。
2、v-show和v-if的作用和区别,v-bind和v-model的作用和区别?
v-show和v-if作用:都是用来控制元素的隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css-display:none,dom元素还在。
v-bind和v-model的作用如下图:
v-model:
绑定text
<input type="text" v-model="val" />
<p> {{val}} </p>
绑定checkBox单个勾选框,最终的值为逻辑值true和false
<input type="checkbox" v-model="checkVal" />
<label for="checkbox">{{checkVal}} </label>
v-bind:
绑定属性
<p v-bind:src="http://..."> </p>
<p v-bind:class="http://..."> </p>
<p v-bind:style=./xxx.css> </p>
区别:v-bind用来绑定数据和属性以及表达式,缩写为‘:’
v-model使用在表单中,实现双向数据绑定的,在表单元素之外使用不起作用
3、vue组件通信如何实现,至少列举3种方式并说明各自的局限性?
1.父传子:
子组件代码:`
Users.vue子组件
<template>
<div class="hello">
<ul>
<li v-for="(item,i) in users"
:key="(item,i)"> {{i}}--{{item}} </li>
</ul>
</div>
</template>
<script>
export default {
name:'Helloworld',
props:{
users:{
type:Array,
require:true
}
}
}
</script>
App.vue父组件
<template>
<div id="app">
<Users v-bind:users="users"> </Users>
</div>
</template>
<script>
import Users from './components/Users.vue'
export default {
name: 'App',
data(){
return{
users:["Henry","Bucky","Emily"]
}
},
components: {
Users
}
}
</script>
<style>
</style>
main.js文件
import Vue from 'vue'
import App from './App.vue'
import Users from './components/Users.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
2、子组件向父组件传值(通过事件形式)
接下来我们通过一个例子,说明子组件如何向父组件传递值:当我们点击“Vue.js Demo”后,子组件向父组件传递值,文字由原来的“传递的是一个值”变成“子组件向父组件传值”,实现子组件向父组件值的传递。
点击Vue.js Demo之前
点击Vue.js Demo之后显示的结果如下图:
Header.vue子组件代码:
<template>
<header>
<h1 @click="changeTitle">{{title}}</h1>
</header>
</template>
<script>
export default {
name:'app-header',
data() {
return {
title:"Vue.js Demo"
}
},
methods:{
changeTitle() {
this.$emit("titleChanged","子组件向父组件传值");
}
}
}
</script>
App.vue父组件代码:
<template>
<div id="app">
<app-header v-on:titleChanged="updateTitle"> </app-header>
<h2>{{title}} </h2>
</div>
</template>
<script>
import Header from './components/Header.vue'
export default {
name: 'App',
data(){
return{
title:"传递的是一个值"
}
},
methods:{
updateTitle(e){
this.title = e;
}
},
components: {
"app-header":Header,
}
}
</script>
<style>
</style>
main.js代码:
import Vue from 'vue'
import App from './App.vue'
import Header from './components/Header.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
方法二、
e
m
i
t
/
emit/
emit/on
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。
4、div 中id和class使用讲解
在div 标签中,我们比较常见的属性是id 和class,那么这两个属性有什么区别吗?今天就来看看这两者的区别。其实id 和class是大部分标签都有的属性。其作用是让CSS或者JavaScript找到DOM元素并操作。
首先看看这两个属性在html中是如何使用的。
<div id="part1"> </div>
<div class="student"> </div>
解释上面的代码,
id=“part1”,意思是定义了一个id,它的值是“part1”;
class=“student” 意思是定义了一个类,它的类名是“ student”;
那么这两个属性是使用的时候有什么区别吗?什么时候用id?什么时候用class呢?请看下文。
1.定义区别。
(1).id具有唯一性,在一个网页中只能定义一次;
(2).class命名的类,可以出现多次。
2.使用区别。
(1).id在css中是以“#”开头的命名的;
(2).class在css中是以“.”开头命名的;
PS:
1.一般来说,id是元素的唯一代号,给某个元素赋予一个id后,通常不会再有其他元素有一样的id。CSS和JavaScript可以使用id来单独操作某一个元素;而class是一组(多于一个)元素的共同代号,通常网页中会有一组元素具有一样的class。CSS和JavaScript中对某个class的操作会反映到每一个对应的元素上。
<style lang="less" scoped>
//下面是student类的css结构
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
2.ID是一个标签,用于区分不同的结构和内容,就象名字,如果一个屋子有2个人同名,就会出现混淆;class是一个样式,可以套在任何结构和内容上,就象一件衣服;
从概念上说就是不一样的:id是先找到结构/内容,再给它定义样式;class是先定义好一种样式,再套给多个结构/内容。