前言

对不起,我学习晚了。

前端迭代真是太快了,我所掌握的前端知识还停留在 jQuery 时期,这不正好就需要恶补一下前端新知识了,选择太多了,我决定直接从 vue 入手,把 Nodejs、HTML5、CSS3、ES6 都能带入进来学习,触类旁通。话不多说,正式进入 vue 学习入门第一课。

vue 入门

页面源码直接在线打开:《vue框架学习入门demo》

1. 声明式渲染

1
2
3
4
5
6
7
8
9
10
<h3>入门</h3>
<div id="app">{{message}}</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: "Hello Vue!",
},
});
</script>

这是官方文档给出的第一个例子,看起来很简单吧,我们可以从这个例子发散一下思维,如果是 jQuery 怎么写呢。

1
2
3
4
5
<div id="jq_app"></div>
<script>
var jqApp = { message: "Hello jQuery!" };
jQuery("#jq_app").text(jqApp.message);
</script>

看起来渲染效果是一样的,但是 vue 版的渲染会随着 app.message 值的改变而自动更改渲染值,jQuery 的这个渲染不会随着 jqApp.message 值的改变而更改渲染值,除非写出更复杂的代码才能达到同样效果。

有什么好处呢,好处就是如果我从接口请求了数据渲染这个值,当重新请求数据需要重新渲染时,vue 版只需要执行 app.message=”new value” 即可,不必去操作 DOM 修改值,Vue 会自动重新渲染。

单个值可能看不出优势,如果是下面这样的一整块需要渲染,那么就体现出优势了。

1
2
3
4
5
<div id="article">
<h1 class="title">{{title}}</h1>
<div><span class="author">{{author}}</span><span class="pub_time">{{publish_at}}</span></div>
<div class="content">{{content}}</div>
</div>

jQuery 来写上面这段渲染会很复杂,Vue 只需要维护几个字段就好了。

2. 绑定元素 attribute

1
2
3
4
5
6
7
8
9
10
11
<div id="app_2">
<span v-bind:title="message"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span>
</div>
<script>
var app2 = new Vue({
el: "#app_2",
data: {
message: "页面加载于 " + new Date().toLocaleString(),
},
});
</script>

这个例子学到了 v-bind:xxx=”yyy” 这种语法,我把例子稍微延伸一下,应该也是可以运行吧。

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app_2">
<span v-bind:title="message" v-bind:style="styleInfo"> 鼠标悬停几秒钟查看此处动态绑定的提示信息! </span>
</div>
<script>
var app2 = new Vue({
el: "#app_2",
data: {
message: "页面加载于 " + new Date().toLocaleString(),
styleInfo: "color:red;",
},
});
</script>

内联样式属性 style 也可以绑定成功,说明理解得不错。

3. 条件

1
2
3
4
5
6
7
8
9
10
11
<div id="app_3">
<p v-if="seen">现在你看到我了</p>
</div>
<script>
var app3 = new Vue({
el: "#app_3",
data: {
seen: true,
},
});
</script>

上面是官方的例子,我在此基础上加了个切换按钮,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app_3">
<p><input type="button" class="button" value="显示/隐藏" /></p>
<p v-if="seen">现在你看到我了</p>
</div>
<script>
var app3 = new Vue({
el: "#app_3",
data: {
seen: true,
},
});

var ele3 = document.querySelector("#app_3");
var btn3 = ele3.getElementsByClassName("button");
btn3[0].addEventListener("click", function () {
if (app3.seen) {
app3.seen = false;
} else {
app3.seen = true;
}
});
</script>

这个绑定事件是我在不了解 Vue 绑定事件怎么用的情况下,用原生 js 写的,Vue 里面有更好的封装,下面会有例子。

jQuery 版估计得这么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="jq_app_3">
<p><input type="button" class="button" value="显示/隐藏(jq)" /></p>
<p class="seen-con">现在你看到我了</p>
</div>
<script>
var jqApp3 = { seen: true };
jQuery("#jq_app_3 > p > input[type=button]").on("click", function () {
if (jqApp3.seen) {
jQuery("#jq_app_3 .seen-con").hide();
jqApp3.seen = false;
} else {
jQuery("#jq_app_3 .seen-con").show();
jqApp3.seen = true;
}
});
</script>

4. 循环

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app_4">
<ol>
<li v-for="todo in todos">{{todo.text}}</li>
</ol>
</div>
<script>
var app4 = new Vue({
el: "#app_4",
data: {
todos: [{ text: "学习JavaScript" }, { text: "学习Vue" }, { text: "整个牛项目" }],
},
});
</script>

上面是官方的例子,我在此基础上加了个数据新增功能,代码如下。

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
<div id="app_4">
<p><input type="text" class="text" /><input type="button" class="button" value="增加" /></p>
<ol>
<li v-for="todo in todos">{{todo.text}}</li>
</ol>
</div>
<script>
var app4 = new Vue({
el: "#app_4",
data: {
todos: [{ text: "学习JavaScript" }, { text: "学习Vue" }, { text: "整个牛项目" }],
},
});

var ele4 = document.querySelector("#app_4");
var btn4 = ele4.getElementsByClassName("button");
var txt4 = ele4.getElementsByClassName("text");

btn4[0].addEventListener("click", function () {
let con = txt4[0].value;
if (con) {
app4.todos.push({ text: con });
txt4[0].value = ""; // 清空文本框的值
txt4[0].focus(); // 文本框继续获得输入焦点
}
});
</script>

这样就可以给这个列表添加项目了,比官方例子生动多了嘛。

至于 jQuery 版实现,算了,我不想写了…(PS:源码在 demo 里)

5. 绑定事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app_5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反转消息</button>
</div>
<script>
var app5 = new Vue({
el: "#app_5",
data: {
message: "hello Vue.js!",
},
methods: {
reverseMessage: function () {
this.message = this.message.split("").reverse().join("");
},
},
});
</script>

原来 Vue 绑定事件的语法是: v-on:event=”eventMethod” ,确实封装得挺好的哈。

6. 表单双向绑定

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app_6">
<p>{{ message }}</p>
<input v-model="message" class="text" />
</div>
<script>
var app6 = new Vue({
el: "#app_6",
data: {
message: "Hello Vue",
},
});
</script>

双向绑定也很简洁嘛,总算不用写 jQuery 那种事件监听了。

7. 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app_7">
<ol>
<todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"></todo-item>
</ol>
</div>
<script>
// 在Vue中注册组件
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: "牛肉" },
],
},
});
</script>

唔,组件的例子,初次看还听复杂的,看懂以后稍微联想一下,就想到了这个就是模版渲染了,为了保持 HTML 兼容性,自定义了 HTML 标签嘛。看懂就好,先不深究,在实际开发中再去一一应证。

8. 侦听器

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<div id="watch-example">
<p>问一个是或否(yes/no)的问题: <input v-model="question" /></p>
<p>{{ answer }}</p>
</div>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
el: "#watch-example",
data: {
question: "",
answer: "请先输入问题!",
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = "正在输入中...";
this.debouncedGetAnswer();
},
},
// Vue实例初始化以后会执行这个函数
// _.debounce()是lodash库提供的延迟执行函数
created: function () {
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500);
},
methods: {
getAnswer: function () {
if (this.question.indexOf("?") === -1) {
this.answer = "问题要以问号结尾嘛 :-)";
return;
}
this.answer = "思考一下...";
var vm = this;
axios
.get("https://yesno.wtf/api")
.then(function (response) {
vm.answer = _.capitalize(response.data.answer);
})
.catch(function (error) {
vm.answer = "Error! Could not reach the API. " + error;
});
},
},
});
</script>

Vue 生命周期图示见官网图片点这里

Lodash 库的功能嘛,大概就是一些实用函数封装,不需要立马学习,使用时去 Lodash 官网 查一下,有时间也可以把其中的函数都看一遍,留个印象。

Axios 库就是一个 Ajax 库了,和 jQuery 里的 jQuery.ajax() 类似,也算工具库,有时间可以看看封装了哪些东西。

总结

至此,对 Vue 有了初步了解,学到了几个 Vue 的语法。

v-bind:xxx=”yyy” 绑定元素 attribute
v-if=”xxx” 条件语句
v-for=”item in list” 循环语句
v-on:xxx=”yyy” 绑定事件
v-model=”xxx” 表单元素双向绑定语法

这几种是模版引擎里常用的语法,Vue 实现得都很优雅,甚是喜欢。

–End–