用key管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做,除了使 Vue 变得非常快之外,还有一些有用的好处。
例如,如果你允许用户在不同的登录方式之间切换
//html
<div id="app">
<div>
<template v-if="username">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
<button v-on:click='switchButton'>Toggle login type</button>
</div>
</div>
//js
<script type='text/javascript'>
var vm=new Vue({
el:'#app',
data:{
username: true
},
methods: {
switchButton: function() {
if(vm.username)
vm.username=false;
else vm.username=true;
}
}
})
</script>
当然,在不用复用元素的时候,就可以用key
来写值,使得重新渲染新的元素
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-show VS v-if
v-show是一开始就会渲染好,之后改变的属性是类似于display属性的切换
v-if是惰性的,只有在第一次条件为真时才会开始渲染
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。
对象属性检测更改
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。
<ul id="app">
<li>{{birthTime}}</li>
</ul>
<script type='text/javascript'>
var vm=new Vue({
el:'#app',
data:{
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
Vue.set(vm, 'birthTime', '20170928');
</script>
像这样,如果动态添加根节点vm的属性就会报错。那么,如果真的要改变根节点属性时该怎么办呢???值得探讨
可以这么想象其原理,建筑一座城堡时,先筑好一个地基包围起来即元素,就可以动态的往城墙里面添加东西,但是地基无法改变,因为一动起来其他各个部门都有可能收到不同程度的干扰或损伤。
非根节点就可以动态添加属性
<ul id="app">
<li>{{mianmian.birthTime}}</li>
</ul>
<script type='text/javascript'>
var vm=new Vue({
el:'#app',
data:{
mianmian:{
name: 'mianmian'
}
}
})
Vue.set(vm.mianmian, 'birthTime', '20170928');
</script>
动态添加多个属性
应该用
vm.mianmian = Object.assign({}, vm.mianmian, {
age: 20,
birthTime: '20170928'
})
而不应该用
Object.assign(vm.mianmian, {
age: 20,
birthTime: 20170928
})
下面这样的方法不会报错,但是没什么效果。
问题: template和div这些元素有什么不一样,为什么总要单独拿出来说?
template是模板,特别是运用在组件的时候,作为模板,是最外层框架。另外,在搭建项目时,也是一般作为组件的最外层元素
v-model VS v-bind
感觉上的话可以把v-model类似于绑定一个容器,你可以通过这个容器得到容器里面的值,而v-bind就是绑定容器内具体的部分,是具体的值。
<div id="app">
<input type='checkbox' v-model='toggle' v-bind:true-value='a' v-bind:false-value='b'>
<span>{{ toggle }}</span>
</div>
var vm=new Vue({
el:'#app',
data:{
toggle: '',
a: 'hello ',
b: 'world'
}
})
组件
组件要先定义,在vue元素创建之前就要先定义好组件,这样才能被vue元素使用。要确保在初始化根实例之前注册了组件
is属性
浏览器中一些标签元素比如<table>
,<ul>
,<ol>
,<select>
这些元素其内部包含的元素是有限制的,而<option>
这样的元素就只能出现在其他元素的内部。
因此,一些自定义的组件在这些元素内使用的时候是无法得到渲染的。
这个时候,is就出现了
Q:什么时候报错了?怎么我没遇到?
触发emit和监听on
一般来说,是可以先触发某个事件,从而引起对该事件的监听。
props是组件中的,在根元素很少出现prop属性。
在html中输出root根元素的时候只会输出data里的数据,默认就是data里的
在每一个vue组件中都可以定义各自的css,js,如果希望组件内写的css只对当前组件起作用,只需要在style中写入scoped
,即:
<style scoped></style>
在html中也有scope
,因此scope的意思应该是绑定的意思,绑定为子组件的属性
//html
<div id='app'>
<app-layout>
<template scope='props'>
<span>hello from app</span>
<span>{{ props.text }}</span>
<span>{{ header }}</span>
</template>
</app-layout>
</div>
//js
//组件
Vue.component('app-layout', {
template: ' <div class="container">\
<slot text="hello from app-layout"></slot>\
</div>'
})
//根元素
new Vue({
el: '#app',
data: {
header: '旷野无人'
}
})
作用域插槽没看懂最后一步
ref和id
感觉起来ref和id的功能有一点点相似之处,都是进行索引。但是ref查找的是组件里的数据,而id在vue中一般都是在根元素才有的。
transition(过渡类名)
使用@keyframes
规则,你可以创建动画。
创建动画是通过逐步改变从一个CSS样式设定到另一个。
在动画过程中,您可以更改CSS样式的设定多次。
指定的变化时发生时使用%,或关键字"from"和"to",这是和0%到100%相同。
0%是开头动画,100%是当动画完成。
@keyframes fade-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
Q:为什么有些性质有个:
,有些性质没有个:
A:加:
是该性质的值是绑定在vue元素上的,是由vue元素提供的。就像v-on:click
,v-bind
,这些后面也是加了冒号表明其值与vue元素上的属性值有关。特别在css属性中的src
,如果是在vue元素上,就要用:src=''
<transition> 只能使用在单一元素,<transition-group> 可以使用在元素列表.
小知识
切换两种状态时可以考虑? :
符号,比如
<button v-bind:key="isEditing" v-on:click="isEditing = !isEditing">
{{ isEditing ? 'Save' : 'Edit' }}
</button>
watch Vs computed Vs methods
watch和computed是以数据变化为依赖的,当数据发生变化时,就会自动调用相关的函数去实现数据的变动
methods是用来定义函数的,是需要手动调用函数才能执行的。computed是计算属性,使用上是和data对象里的数据属性一样的,不要当成函数调用
3.watch是一个对象,类似于监听机制和事件机制。
watch: {
firstName: function (val) { this.fullName = val + this.lastName }
}
firstName是就是data里的属性,firstName改变了这个事件才会触发,而firtstName对应的函数就是监听属性变化后会执行的方法。
watch和computed之间不一样的地方
watch擅长于一个数据影响多个数据的场景
computed擅长一个数据受多个数据影响的场景