Vue 学习笔记
介绍
作为前端主流框架之一,vue.js 生态系统日益完善。了解和学习 vue.js,可以学到很多新的思维观念。
参考
入门
在 HTML 中引入 vue.js 文件即可使用。
下载到本地或使用远程 CDN
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id='app'>
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
</div>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split(' ').reverse().join(' ');
}
}
})
语法
实例化 Vue 对象
const vm = new Vue(options)
vm
(ViewModel) 为 Vue 的实例,在 options 的函数中可以通过this
访问定义在实例上的数据和方法。
标签内容
绑定对象
<tag>{{ variable }}</tag>
<div id="app">
{{ message }}
</div>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
标签属性/事件
绑定对象
<tag v-bind:attr="variable" v-on:event="expression/method">...</tag>
:
后面为指令的参数,可以通过[argument]
动态计算。
v-bind:
, v-on:
可以简写为:
和@
。
v-bind:title => :title
v-on:click => @click
<span v-bind:title="message">
Hover your mouse over me for a few seconds
to see my dynamically bound title!
</span>
<button v-on:click="reverseMessage">Reverse Message</button>
条件和循环
v-if
v-show
v-for
<span v-if="seen">Now you see me</span>
<li v-for="todo in todos">
{{ todo.text }}
</li>
const app = new Vue({
el: '#app-3',
data: {
seen: true,
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
]
}
})
data 中数组、对象修改
对于数组、对象等复杂数据结构,使用的都是这些变量的引用
。修改时需要做额外处理,以实现 UI 的即时刷新。
-
使用 Vue 内部处理过的方法:
push(), pop(), shift(), unshift(), splice(), sort(), reverse()
-
使用 Vue.set 或 vm.$set 方法
以修改数组某个元素为例
vm.items.splice(itemIndex, 1, newValue)
vm.$set(vm.items, itemIndex, newValue)
import Vue from 'vue'
Vue.set(items, itemIndex, newValue)
// object in array
Vue.set(object, 'propName', newValue)
修改数组长度(变小)
vm.items.splice(newLength);
Vue 不允许添加 root 级别的属性到实例上。但是当属性本身是一个对象时,可以在该对象上添加属性
vm.$set(vm.userProfile, 'age', 27);
vm.userProfile = Object.assign({}, vm.userProfile, {
age: '27',
favoriteColor: 'Vue Green',
});
双向绑定
常用于表单输入标签。本质上是语法糖,基于用户输入事件来更新数据。
v-model
<div>
<p>{{ message }}</p>
<input v-model="message">
</div>
自定义组件
Vue.component
方法可以自定义组件,组件是可复用的 Vue 实例, definition
基本上与 options
一致。
Vue.component(id, definition);
组件的数据
-
data
() => Object
- 组件内部、私有的数据 -
props
[propA, propB, ...]
||{ propA: { type: String, default: '' } }
- 组件外部传递过来、公开的数据 -
computed
{ dataA() {}, dataB() {} }
- 根据 data 或 props 动态计算出来的数据。
指令
v-model
, v-for
, v-if
, v-bind
, v-on
等都是内置指令,用户也可以自定义指令,主要用于底层的 DOM 操作。
Vue.directive(id, definition);
v-html: Raw HTML
<span v-html="rawHtml"></span>
<span>{{ plainText }}</span>
父子组件数据传递
父组件 -> 子组件:通过props
单向传递数据。父组件数据变化后子组件会自动刷新
子组件 -> 父组件:调用 events 手动修改父组件的数据
组件内部:$emit('event')
组件外部:v-on:event="method"
Vue.component('test-component', {
template: '#test-template',
props: ['value'],
methods: {
onInput: function (event) {
this.$emit('input', event.target.value)
}
}
})
Vue.component('show-component', {
template: '#show-template',
props: ['user'],
})
new Vue({
el: '#app',
data: {
user: 'John'
}
})
<template id='test-template'>
<input v-bind:value='value' v-on:input='onInput' type='text'/>
</template>
<template id='show-template'>
<div>{{ user }}</div>
</template>
<div id='app'>
<test-component v-model='user'></test-component>
<show-component v-bind:user='user'></show-component>
</div>
一些报错及原因
[Vue warn]: Property or method "addItem" is not defined on the instance but referenced during render.
一个常见原因为没在组件上定义好属性或方法;另一个原因是div#app
中包含了template
,template
的内容被 Vue 解析到 root 中,导致报错。
预处理器
.vue 单文件由vue-loader
预加载和处理。文件中的 HTML, JavaScript, CSS 都可以进行预处理。
Pug -> HTML
npm install -D pug pug-plain-loader
// webpack.config.js -> module.rules
{
test: /\.pug$/,
loader: 'pug-plain-loader'
}
<template lang="pug">
div
h1 Hello world!
</template>
SASS/LESS -> CSS
Coffee/TypeScript -> JavaScript
vue-cli
npm i -g @vue/cli
vue create <project-name>
cd <project-name>
npm start
在线交互
Try Vue :)
Input: {{ text }}// Init Vue with el, data and methods
new Vue({
el: '#app-demo',
data: {
text: 'hello'
},
methods: {
sayHello: function () {
console.log(this.text);
}
}
})