Vue 1.0是MVVM框架,但是2.0就是MV*框架了
一. 使用vue搭建项目
方法1. 使用 @vue/cli
安装
(此时先不建目录,先在vscode终端)
yarn global add @vue/cli
创建项目
可以在终端先进入项目的目录:cd /d/jirengu/
vue create vue-demo-1
之后会选择默认配置还是自己手动配置,我们本节课学习时手动配置:
如果创建成功,会提示你输入:
$ cd vue-demo-1
$ npm run serve // 也可以用 yarn serve
会开启一个webpack-dev-server,方便实时预览
vscode打开项目
终端输入: start . 会自动打开这个目录,然后手动把目录拖进vscode
yarn serve开启服务器,看到如下就说明我们的第一个vue项目创建成功。
方法2.
从零搭建vue项目,但是不推荐新手
二. 了解Vue实例
使用Vue实例有两种方法,这与vue的两种版本有关。完整版(vue.js)和不完整版(vue.runtime.js):各自都有一个min.js,是生产环境的版本,删掉了注释,压缩变量等,使体积更小。
方法1. 从HTML获取视图(完整版vue)
在index.html里通过script标签引入cdn里的完整版vue.js
<div id="app">
{{n}}
</div>
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
这时我们就得到了一个vue全局变量,在main.js里console.log(window.Vue)可以打印出Vue的初始化,是一个函数。
new Vue({
el: "#app", //对这个div进行MVC封装
data: {
n: 0,
},
});
这时页面中的占位符就变成了0.
可以看出,完整版的功能在于: MVC的视图没有写在JS里,直接写在了body里,可以在页面里把n变成0
方法2. JS构建视图(不完整版vue)
如果使用不完整版的vue,在index.html里:
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js"></script>
其他还是相同的操作,发现页面里没有0.
因为不完整版的vue,不支持从HTML里获取视图。那如果我自己写呢?
//index.html
<div id="app"></div>
//main.js
new Vue({
el: "#app", //对这个div进行MVC封装
template: `<div>{{n}}</div>`, //自己写一段html字符串
data: {
n: 0,
},
});
发现还是不行。同样的写法如果使用完整版,就好用了。
说明,只要是从html里产生视图,把html变成页面中的东西,不完整版就不支持;完整版就支持。
总结
但是不完整版不认识template,要传一个render函数,参数h是vue传给它的
new Vue({
el: "#app",
render(h) {
return h("div", this.n);
},
data: {
n: 0,
},
});
h就相当于createElement,必须通过createElement的方式把所有元素构造出来。
再加一个按钮,并且绑定事件:
new Vue({
el: "#app",
render(h) {
return h("div", [this.n, h("button", { on: { click: this.add } }, "+1")]);
},
data: {
n: 0,
},
methods: {
add() {
this.n += 1;
},
},
});
原理:
完整版的思路是:
前提:我们有一段html字符串,这里边可能还会有{{n}},@click,vue-if之类复杂的代码,我们想把他们变成真正的html和数字。
做法:如果直接替换,有很多问题。所以vue写了一个编译器(compiler),这个编译器可以把html字符串变成DOM节点。但是编译器的缺点是很复杂,所以占用体积很大。
所以有了不完整版:
不完整版是没有编译器的,所以体积小了很多。但是没有编译器,就不能把html字符串变成DOM节点。
还好我们可以使用webpack,有一个vue-loader,可以在build的时候把字符串html预编译成h(),而不完整版正好支持h()语法。
所以我们写代码的时候可以按照完整版来写,用户也可以下载体积小的不完整版,中间由webpack的vue-loader进行转换。转换后已经不是html字符串了。所以其实在打包好之后是不需要编译器的,可以使用不完整版。
方法三. 使用vue-loader(vue单文件组件)
新建一个Demo.vue
//视图
<template>
<div class="red">
{{n}}
<button @click="add">+1</button>
</div>
</template>
//除视图外的其他选项
<script>
export default {
data() { //使用vue-loader,data必须是函数
return { n: 0 };
},
methods: {
add() {
this.n += 1;
}
}
};
</script>
//样式
<style scoped>
.red {
color: red;
}
</style>
.vue文件里有三个内容,template,script.style。
在main.js里导入vue模块:
import Demo from "./Demo.vue";
console.log(Demo);
console.log(Demo.render.toString());
new Vue({
el: "#app", //对这个div进行MVC封装
render(h) {
return h(Demo);
},
});
在index.html里引入不完整版的vue,所以可以在js里使用全局变量
效果:
所以我们写的vue文件经过vue-loader变成了一个对象,它有一个render方法,可以自动的把我们写的template翻译成h()构建方法,所以我们即使没写render函数,也可以。
但是用vue-loader有一个缺点,视图都在.vue文件里,HTML就只有一个空的div,导致SEO不友好。
SEO
SEO是搜索引擎优化,把网站的关键词优化到搜索引擎前排的位置。
当我们在百度搜索xiedaimala.com时,我们看到的页面是JS渲染的结果。可以认为搜素引擎就是不停的curl,百度服务器会不停的curl 这个xiedaimala.com,拿到这个网站的主要内容,比如看到title,就知道了这个网站的标题是什么。搜索引擎会根据curl到的结果猜测页面的内容。把这些结果放到数据库里,如果有人搜索相关内容,就会展示出这个网站。
所以用vue-loader创建vue实例时,HTML里就只有一个空的div,最终展示的内容都是用JS创建的,那么curl就很瞎,得不到这个页面的主要内容,因为你啥都没写(除了有个title)。
那应该怎么办呢?
给curl一点内容就好了。把title,keyword,description,h1,a写好。这样curl就能得到基本信息了,SEO就可以正常工作。
在我们的例子中,可以在HTML的div里写h1标签,a标签等,最终页面的效果还是一样的,因为vue会把原来的节点替换掉。写这些只是为了SEO。
keyword,description都是head里的meta标签的选项,以淘宝为例:
三.深入理解vue两种版本的区别
当我们通过@vue/cli创建项目时,就已经引入了vue,默认是不完整版的。所以我们才可以在main.js里通过import Vue from "vue"使用Vue。然后new Vue
也可以通过bootcdn,在body的script标签里引入。这种情况不需要import,可以直接使用Vue。
webpack引入比较复杂
最好的选择:使用不完整版的vue,然后配合vue-loader和vue文件