19-5-25 js(4) vue

官方文档比较乱。写的时候稍微整理了整理,但是内容不全。

Vue 基础

参考资料 Vue官方文档

runoob

基础

最简单的方法是直接引用就行,

1
2
3
4
5
6
7
8
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
{{ message }}
</div>

需要注意的是js内容无法通过直接使用外部引用来完成

1
2
3
4
5
6
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})

运行之后,可以在控制台里面对app.message进行修改

v-model 还可以双向绑定修改input框中的内容,p中内容也会改变

1
2
3
4
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
1
2
3
4
5
6
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})

实例

Vue的属性与用户定义的内容是分开来的

1
2
3
4
5
6
7
8
9
10
11
12
13
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})

vue实例被创建的时候带有生命周期,可以用created来执行一个实例被创建后的函数

1
2
3
4
5
6
7
8
9
10
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"

样例

常用数据绑定形式就是双大括号,但是这种只是讲文本插入,如果要使用html就需要使用v-html

1
2
3
<span>Message: {{ msg }}</span>
<span v-once> vonce使得此处内容插入后不能被修改:{{msg}}</span>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

模板支持单个的js表达式

1
2
{{ number + 1 }}

在2.6版本中,可以用方括号括起来的一个js表达式作为一个指令的参数

1
2
3
4
<a v-bind:[attributeName]="url"> ... </a>

<a v-on:[eventName]="doSomething"> ... </a>

v-bind和v-on都可以缩写

1
2
3
4
5
6
7
8
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>

计算属性 computed

可以在vue的实例里创建computed的属性。尽量不使用箭头函数,有时候会导致this指向错误。

1
2
3
4
5
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})

侦听属性 watch

有些数据会随着其他数据变化而变化,因此容易滥用watch,建议使用计算属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<div id="demo">{{ fullName }}</div>

var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})

计算属性的setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}

这样子就能对fullname进行修改

class与style绑定

1
2
3
4
5
6
7
8
9
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

data: {
isActive: true,
hasError: false
}

写成计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div v-bind:class="classObject"></div>


data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}

也可以应用成一个数组

1
<div v-bind:class="[activeClass, errorClass]"></div>
1
2
3
4
data: {
activeClass: 'active',
errorClass: 'text-danger'
}

用在组件上

1
2
3
4
5
<my-component class="baz boo"></my-component>
<!-- 渲染结果-->
<p class="foo bar baz boo">Hi</p>
<!-- bind一样适用-->
<my-component v-bind:class="{ active: isActive }"></my-component>

这些组件需要放在vue创建的内容下

1
2
3
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})

用在style上

1
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
1
2
3
4
data: {
activeColor: 'red',
fontSize: 30
}

当然 直接绑定对象更好

1
<div v-bind:style="styleObject"></div>
1
2
3
4
5
6
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}

条件渲染 if

有v-if跟v-else

1
2
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

v-show差不多 区别在渲染时候的不同

列表 for

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>

var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})

监听 on

除了监听点击,还能监听键盘内容

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>

new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})

组件化 component

vue可以通过小的组件来实现大的应用,组件非常类似于自定义元素。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:message="parentMsg"></child>
</div>
</div>

<script>
// 注册
Vue.component('child', {
// 声明 props
props: ['message'],
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
el: '#app',
data: {
parentMsg: '父组件内容'
}
})
</script>
1
2
3
4
5
6
7
8
9
10
<div id="app-7">
<ol>
<!--现在我们为每个 todo-item 提供 todo 对象todo 对象是变量,即其内容可以是动态的。我们也需要为每个组件提供一个“key”,稍后再作详细解释。-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//todo-item是名字
//props 是传递
//template 是内容样式
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})

var app7 = new Vue({
el: '#app-7',
data: {
groceryList: [
{ id: 0, text: '蔬菜' },
{ id: 1, text: '奶酪' },
{ id: 2, text: '随便其它什么人吃的东西' }
]
}
})