官网:https://cn.vuejs.org/v2/guide/index.html
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。
视频教程:https://scrimba.com/g/glearnvue
- 介绍
- 实例
- 模版语法template
- computed, watch
- v-if, v-show
- v-for, 一个组件的v-for.
查看我的codepen案例: https://codepen.io/chentianwei411/pen/EemeMg?editors=1010
基础
关键知识点:
- JS中 new Vue({el: '#id', data: { message: "Hello Vue!"}})
- v-bind:property #property可以是自定义特性也可以是HTML特性。用于在DOM上应用响应式行为
- v-if="xxx" 条件: xxx的结果是true/false
- v-for="xxx in xxxs" 循环: ⚠️写法
- v-on:click='methods_name' 这是类似addEventListener()添加事件监听v-on
- v-model='message' 用于实现表单输入input和应用状态之间的双向绑定
- 等同于用vailina javascript: 使用oninput事件 (点击见案例)
- ⚠️ oninput, 和onchange有区别:
- oninput专门用于<input>,<textarea>tag,输入即变化
- onchange用于当元素的value发生变化且元素失去focus后执行。
-
Vue.component('todo-item', {
template: '<li>这是个待办项</li>'
}) - 一个组件本质上是一个拥有预定义选项的一个 Vue 实例,上面定义的主机todo-item可以用在DOM中了。
- props: ['todo'], props用于定义组件特性property,类似HTML元素的特性。
- ⚠️如果组件和new Vue写在一个脚本内,则注意,先写组件,再写new Vue
组件和自定义元素的关系:
- 类似但有区别,兼容所有浏览器。
- Vue.component比纯自定义元素有优势,如跨组件数据流、自定义事件通信以及构建工具集成。
Vue实例
一个 Vue 应用由一个通过 new Vue
创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。举个例子,一个 todo 应用的组件树可以是这样的:
根实例
|
new Vue({
//options;
})
数据属性 data 和 method
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data
对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
注意: 只有当实例被创建时 data
中存在的属性才是响应式的, 后添加的属性不是响应式的。
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
Object.freeze()阻止修改现有的属性,也意味着响应系统无法再追踪变化。
Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $
,以便与用户定义的属性区分开来。例如:
var data = { a: 1 }
|
钩子函数
如 created, mounted
、updated
和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue 实例。
不要在选项属性或回调上使用箭头函数
模版语法
Vue 将模板编译成虚拟 DOM 渲染函数。
如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。
插值
Mustache 即{{}}用双大括号,绑定数据, 数据转换为普通文本。
v-html 接受原始html元素。但尽量别用,容易遭到xss攻击。
Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令
Vue.js 都提供了完全的 JavaScript 表达式支持
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }} #支持三元语法,但不能用if,这是控制流。
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
⚠️,不能声明变量,声明变量是语句,不是表达式。
指令v-
预期值是单个js表达式。v-for是例外。
指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
参数
部分指令可以接收参数(HTML特性,自定义特性)
<a v-bind:href= 'url'>...</a>, 这里的参数是href,v-bind将元素a的href特性和表达式url的值绑定。
修饰符
以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
.prevent
会调用event.preventDefault();
<form v-on:submit.prevent="onSubmit">...</form>
|
缩写
v-bind: 缩写是:
v-on 缩写是@
计算属性和侦听器
computed
由模版语法{{}}扩展而来,比较复杂的表达式,由于不方便维护,所以产生了computed属性。
注意⚠️ 用到return
计算属性的功能也可以用method属性方法实现,但有本质区别:
- computed的结果是缓存的。
- ethod在每次重新触发渲染后都会从新执行函数。
methods: {
reversedMessage: function(){
return this.message.split('').reverse().join("")
}
}
插值加上括号(): {{ reversedMessage() }}
计算属性的setter
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
在表达式内使用get和set函数:
运行 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
watch 侦听属性
用于观察和响应 Vue 实例上的数据变动 。
然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。
大多数时候computed时候,有时候也需要用自定义的watch。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
Class 与 Style 绑定
在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
绑定class
对象语法:
问题?见下面2图,无法产效果。
数组语法:
绑定内联样式:
数组语法:
CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名
如: fontSize 或 'font-size'
HTML:
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">你好</div>
JS:
new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 50
}
})
对象语法:
问题: 不明白:用绑定一个样式对象的方法在codepen上不成功,不知道原因。
问题???无论是
条件渲染 v-if="", v-else , v-else-if=""
HTML:
<div id="h1">
<h1 v-if='ok'>Welcome to Beijing</h1>
<h1 v-else>Sorry, Closed</h1>
</div>
JS:
new Vue({
el: '#h1',
data: {
ok: false
}
})
解释: ok 可以是判断表达式。如ok: Math.random() > 0.5
template可以当作不可见包裹元素和 v-if一起使用。
用 key 可以区别复用的元素
V-show: 简单地切换元素的 CSS 属性 display
。没有其他作用。不支持<template>元素。
v-show vs v-if
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
- 只有当v-if条件为真时,才会渲染。
- 而用v-show, 总会渲染,条件只是控制css#display
v-if with v-for
同node下,v-for的优先级比v-if高。除非,把v-if放在父节点。
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
具体看列表渲染: https://cn.vuejs.org/v2/guide/list.html#v-for-with-v-if
列表渲染
用v-for 把一个数组对应为一组元素
v-for
指令需要使用 item in items
形式的特殊语法。
items
是源数据数组。item
是数组元素迭代的别名。
在 v-for
块中,我们拥有对父作用域属性的完全访问权限。
v-for
还支持一个可选的第二个参数为当前项的索引。v-for="(item, index) in items"- index是隐藏索引,从0开始
可以使用of替代in, v-for="(item, index) of items"
一个对象(就是hash)的 v-for
对象可以有三个参数, v-for="value, key, index in object"
注意第二个参数是 key
key
建议尽可能在使用 v-for
时提供 key。
在用数组时,这么写:<div v-for='item in items' :key='item.id'></div>
注意: Vue不能检查这两个数组的变化:
- 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
替代:
-
Vue.set(vm.items, indexOfItem, newValue)
-
vm.items.splice(newLength)
对象更改检测注意事项
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
1.Vue 不能检测对象属性的添加或删除
2.对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。
但是,可以使用 Vue.set(object, key, value)
方法向嵌套对象添加响应式属性
Vue.set(vm.userProfile, 'age', 27)
3.Vue为一个对象增加多个新的响应式属性:
用Object.assign(target, ...source) 为对象target分配新的属性...source。(点击看API)
需要这么用: 用两个对象的属性生成一个新的对象,然后赋值给原对象。
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
显示过滤/排序结果
显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。
在这种情况下,可以创建返回过滤或排序数组的计算属性。
在计算属性不适用的情况下 (例如,在嵌套 v-for
循环中) 你可以使用一个 method 方法:
<li v-for="n in even(numbers)">{{ n }}</li>
|
也可以取整数:v-for='n in 10'
v-for可以使用<template> tag
<ol id='app'>
<template v-for="item in items">
<li>{{ item.msg }}</li>
</template>
</ol>