一、简单介绍
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
学习此框架你需要掌握关于 HTML、CSS 和 JavaScript 的中级知识。
同时还需要掌握 ES6 的语法知识。
二、简单体验
1. 在一个 HTML 文档中引入vue
方式一
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
方式二
我这里选择的是使用 <script></script>
标签直接引入的方式。
并且是把源码下载到本地。
因为是学习之用,所以选择开发版本

全部复制并保存到本地,名为: vue.js

三、挂载点、模板和实例
先看示例

1. 引入 Vue
<script src="../static/vue.js"></script>
2. Vue
实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var app = new Vue({
// 选项
})
当创建一个 Vue 实例时,你可以传入一个选项对象。
接下来,我们就来讨论一下如何使用这些选项来创建我们想要的行为。
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。
a. 选项
数据对象
在一个 Vue
实例中使用 data
指明了数据对象
var app = new Vue({
data: {
msg: 'hello vue!'
}
})
// 获取到实例中的属性值
app.msg
// 设置实例的属性值
app.msg = 'HELLO'
注意:
凡是在实例中数据对象中的属性都是响应式的,就是说实例中属性改变,会导致模板中的展示结果。否则不会导致模板的展示结果。
实例生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程,在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created
钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
不要在选项属性或回调上使用箭头函数,比如
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
。因为箭头函数是和父级上下文绑定在一起的,this
不会是如你所预期的 Vue 实例,经常导致Uncaught TypeError: Cannot read property of undefined
或Uncaught TypeError: this.myMethod is not a function
之类的错误。

3. 挂载点
<div id="app">
...
</div>
<script>
var app = new Vue({
el: "#app",
})
</script>
el
选项指明了 Vue
的实例作用于具体的那个 DOM 中,在数据变化时更新 DOM。
4. 模板
模板适用于在页面展示 Vue
数据的。
a. 模板可以存在于一个单独的挂载点之内
<div id="app">
<h1>{{ msg }}</h1>
</div>
b. 模板也可以存在于 Vue
的实例中
在 Vue
实例中使用 template
选项声明模板。
<div id="app">
<h1>{{ msg }}</h1>
</div>
<script >
// 创建一个 Vue 实例
var app = new Vue({
// 挂载点
el: '#app',
// 模板
template: '<h1>{{ msg }}</h1>',
// 声明数据
data: {
msg: 'hello vue!'
}
});
</script>
在一个挂载点中的所以元素都称为 Vue
的模板。
插值
下面在一个元素中直接使用 Vue
实例中的数据的形式: {{ msg }}
称为插值。
<h1>{{ msg }}</h1>
四、在Vue 中是如何绑定事件的
假设现在我需要做一个功能,就是在页面上点击一个按钮,之后使页面上的 喜欢我
都变成 不喜欢我
。
此时我们就需要使用 Vue
中一个特殊的东西,叫指令。
在 Vue
中指令有很多,可以实现各种功能,比如现在我们就需要用到的绑定事假的指令叫:v-on
。
实例如下
<div id="app">
<h1>{{ msg }}</h1>
<button v-on:click="handleChang">算一卦</button>
</div>
<script >
var app = new Vue({
el: '#app',
data: {
msg: '喜欢我'
},
methods: {
handleChang: function() {
this.msg = '不喜欢我'
},
}
});
</script>
在 Vue
中使用 v-on
这个指令来绑定一个事件到元素上。
事件触发的方法(函数),定义在 Vue
实例的 methods
属性中。
注意
v-on:click
一般都简写为:@click
五、元素属性的绑定和双向数据绑定
使用 v-bind
可以实现对元素中属性都绑定。
实例
<div id="app">
<h1 v-bind:title='titleText'>鼠标悬停到此处,就会显示出 title 属性的内容</h1>
</div>
<script >
var app = new Vue({
el: '#app',
data: {
titleText: '你得到了我'
}
});
</script>
注意:
v-bind:title
一般都简写成:title
使用 v-model
可以实现数据和页面的值的双向绑定。
一般情况下,都是页面上显示的结果是和数据同步的,改变数据的值,页面会同时发生改变。
现在 Vue
允许修改页面上的值,会同步到数据上。这样的话, input
输入框的值,我们就可以使用数据来接收到了。
实例
<div id="app">
姓名:
<input v-model='inputName'>
<div>{{ inputName }}</div>
</div>
<script >
var app = new Vue({
el: '#app',
data: {
inputName: ''
}
});
</script>

六、计算属性和侦听器
1. 计算属性
当我们使用 Vue
时,在模板中展示数据的时候其实可以放入更多的逻辑。比如下面这样:
<div id="app">{{ msg.replace('h', 'y') }}</div>
<script>
var app = new Vue({
el: "#app",
data: {
msg: 'hello'
}
})
</script>
可以看到上面只是做了个替换而已,但是足矣说明可以在模板中写一些逻辑了。
但是这样下去,随着业务方复杂性,元素中展示的数据需要更多的逻辑去实现,整模板部分会看起来很臃肿杂乱,且难以维护。
所以, Vue
在其实例中设计了一个计算属性,这个计算属性可以写成一个方法(函数),在这个方法中去编写逻辑。
应该任何复杂的逻辑放到这个计算属性中。
究竟如何使用呢? 看下面的例子。
<div id="app">
<p>{{ msg }}</p>
<p>替换后的数据: {{ replaceMsg }}<p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
msg: 'hello'
},
computed: {
replaceMsg: function(){
return this.msg.replace('h', 'y')
}
}
})
</script>
在 Vue
中使用 computed
属性定义计算属性。
可能你已经看出来到了,其实这些逻辑可以在 methods
中使用一个方法实现。
但是这样一来,每次渲染页面中的这个数据时,对应的方法就需要执行。
而这里我们学到的计算属性是有缓存特性的。
就是第一次调用计算属性对应的方法,只要依赖的源数据不改变,之后就不会重复调用此方法。
另一个例子
<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Shark',
lastName: 'Yun'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
七、 模板语法
1. v-text
和 v-html
v-text
是把数据作为文本渲染的页面,不解析数据中的标签。
双大括号和 v-text
都会将数据解释为普通文本,而非 HTML 代码。
为了输出真正的 HTML,你需要使用 v-html
指令:
<div id="demo">
<div>双大括号语法:<span>{{ rawHtml }}</span></div>
<div>v-text 语法:<span v-text="rawHtml"></span></div>
<div>v-html 语法:<span v-html="rawHtml"></span></div>
</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
rawHtml: '<h1>SharkYun</h1>'
},
})
</script>
v-html
是会同时解析数据中出现的标签。
2. v-if
v-if
指令将根据表达式 result
的值的真假来插入/移除 <p> 元素。
在 JavaScript
中有如下真值的实例:
if (true)
if ({})
if ([])
if (42)
if ("foo")
if (new Date())
if (-42)
if (3.14)
if (-3.14)
<div id="demo">
<div v-if="seen"><img :src="imgSrc"></img></div>
<button @click="handelClick">召之即来挥之即去</button>
</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
imgSrc: "./松鼠.jpg",
seen: true
},
methods: {
handelClick: function () {
this.seen = !this.seen
}
}
})
</script>
3. v-show
v-show
指令是根据表达式 seen
的真假,来通过给元素添加/去除 dispaly: none
的样式控制元素都显示/隐藏。
<div id="demo">
<div v-show="seen"><img :src="imgSrc"></img></div>
<button @click="handelClick">召之即来挥之即去</button>
</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
imgSrc: "./松鼠.jpg",
seen: true
},
methods: {
handelClick: function () {
this.seen = !this.seen
}
}
})
</script>
4. v-for
v-for
把一个数组对应为一组元素。
v-for
指令需要使用 item in items
形式的特殊语法,items
是源数据数组并且 item
是数组元素迭代的别名。
循环列表
<div id="app">
<ul>
<li v-for="(num, index) in numbers" :key='index'>
索引号是:{{index}} 值是:{{ num }}
</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
numbers: ['one', 'two', 'three']
}
})
</script>
也可以用 of 替代 in 作为分隔符,因为它是最接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
循环对象
<div id="app">
<ul>
<li v-for="(val) of info" :key='index'>
索引号是:{{index}} 值是:{{ val }}
</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
info: {
name: 'shark',
age: 18
}
}
})
</script>
也可以添加第二个参数,同时遍历 key
和 value
。
<div id="app">
<ul>
<li v-for="(key, val) of info" :key='index'>
索引号是:{{index}} 键是: {{ key }}值是:{{ val }}
</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
info: {
name: 'shark',
age: 18
}
}
})
</script>
一起循环
<div id="app">
<ol>
<li v-for="todo in todos">
{{todo.title }} {{ todo.text }}
</li>
</ol>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
todos: [
{ title: '学习', text: 'JavaScript' },
{ title: '学习', text: 'Vue' },
{ title: '学习', text: 'Django' },
{ title: '整个', text: '牛🐮项目'}
]
}
})
</script>
八、class
和 style
的绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。
它们都是属性,可以用 v-bind 处理。
只需要通过表达式计算出字符串结果即可。表达式结果的类型除了字符串之外,还可以是对象或数组。
1. 绑定 HTML Class
a. 对象的语法
我们可以传给 v-bind:class 一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }"></div>
上面的语法表示 active
这个 class 存在与否将取决于数据属性 isActive
的值是否为真。
也可以于原来的 class
共存,并且同时添加多个 class
。
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
假如实例中的 data
如下:
data: {
isActive: true,
hasError: false
}
渲染后的结果:
<div class="static active"></div>
当 isActive
或者 hasError
变化时,class
列表将相应地更新。
当然,class
的对象没必要放在模板中,应该放在实例的 data
中。
<div id="app">
<div class="static" :class='classObject'></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
classObject: {
active: true,
'text-danger': false
}
}
})
</script>
其实更多的是绑定一个返回对象的计算属性。这是一个常用且强大的模式:
<div :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'
}
}
}
b. 列表的语法
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染为
<div class="active text-danger"></div>
如果你也想根据条件切换列表中的 class,可以用三元表达式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
假如有多个条件,在数组语法中也可以使用对象语法:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
2. 绑定 HTMl Style
a. 对象的语法
v-bind:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
直接绑定到一个样式对象通常更好,这会让模板更清晰:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
同样的,对象语法常常结合返回对象的计算属性使用。
b. 数组的语法
v-bind:style
的数组语法可以将多个样式对象应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>
c. 自动添加前缀
当 v-bind:style
使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform
,Vue.js 会自动侦测并添加相应的前缀。
d. 多重值
从 2.3.0 起你可以为 style
绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。
在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex
。
九、组件基础
1. 什么是组件
组件就是在网页上的某一部分,随着在一个页面中的功能越来越多,我们把页面拆分成多个部分,每一部分都是一个组件。这样维护起来就比较容易了。
2. 创建组件
使用 Vue 的 component
可以创建一个组件,这样创建的组件称为全局组件。
一个组件的示例:
Vue.component('show-data', {
data: function () {
return {
count: 0
}
},
template: '<div>{{ count }}</div>',
})
var app = new Vue({
el: "#app"
})
上面定义了一个组件,名字叫做 show-data
组件中的 data
的值不能是一个对象,必须是一个函数。
3. 使用组件
组件定义好后,就可以在页面上使用了。
使用方法是在页面上利用自定义元素的形式:
<div id="app">
<show-data></show-data>
</div>
4. 组件与实例之间的关系
组件本质上是 Vue 的实例,且带有一个名字。
所以它可以接收 new Vue
相同的选项。
例如 data
、computed
、methods
。
但是,组件中是没有 el
选项的, el
只有 Vue
的根实例才会有。
下面的示例是接上例,并且给其添加一个点击实例,当每次点击页面上的数字的时候,数字加一。
<div id="app">
<show-data></show-data>
</div>
<script>
Vue.component('show-data', {
data: function () {
return {
count: 0
}
},
template: '<div @click="handleCount">{{ count }}</div>',
methods: {
handleCount: function () {
this.count++
}
}
})
var app = new Vue({
el: "#app"
})
</script>
从上例中,可以看出,在一个组件中可以想使用 Vue 的实例一样,添加一些属性,这样证明了一个组件就是一个 Vue 的实例,所以页面中都是由 Vue 无数个实例组合成的。
5. 可复用的组件
之前说过,每个组件就是一个 Vue 的实例。
其实,不但是这样,组件还是可复用的。
接下来,我们还是在上个示例的基础上稍作修改, 在 HTML 代码中多写几个组件。
<div id="app">
<div>第一个<show-data></show-data></div>
<div>第二个<show-data></show-data></div>
<div>第三个<show-data></show-data></div>
</div>
<script>
Vue.component('show-data', {
data: function () {
return {
count: 0
}
},
template: '<div @click="handleCount">{{ count }}</div>',
methods: {
handleCount: function () {
this.count++
}
}
})
var app = new Vue({
el: "#app"
})
</script>
注意:
每个组件都会各自独立维护它的count
。因为我们在 HTML 文档中每用一次组件,就会有一个它的新实例被创建。
网友评论