Vue有两个不同的版本,分别是Vue完整版
vue.js和Vue非完整版vue.runtime.js:
1. Vue完整版
-
文件名:vue.js
-
优点:含有编译器compiler,可以将视图直接写入html
-
缺点:文件体积较大,用户要下载很大的文件,体检较差
2. Vue非完整版
-
文件名:vue.runtime.js
-
优点:文件体积小,用户加载很快,体验较好
-
缺点:没有编译器,无法将html编译成视图,开发时需要将视图写到render函数里,对开发者来说不直观
3. Vue两个版本的详细介绍:
3.1 完整版Vue实例创建过程(从HTML得到视图):
-
完整版的实现思路为:通过编译器compiler把含有占位符
'html {{n}}'或条件循环'v-if','v-for'或@click='add'转化为'html 0'真实的DOM节点,这样的话,在执行this.n += 1的时候,vue就知道要改的是n,不用再去编译,直接就改DOM节点,分析得到'html 1' -
支持在index.html中写标签,或在main.js中写template,都可以用得到视图:
template: `
<div>Hello</div>
`
- 引入vue.js或vue.min.js的方法有两种:
- boot cdn 复制链接 放在index.html的script标签里
- import 引入
import Vue from 'vue'、import App from './App.vue'
console.log(window.Vue)
Vue.config.productionTip = false
new Vue({
el:'#app',
template:` //一种方法是直接在main.js中写
<div>{{n}}</div>
`
data:{
n:0
}
})
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
{{n}} //另一种方法是在index.html中写标签
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.4/vue.js"></script> //引入Vue.js
<!-- built files will be auto injected -->
</body>
</html>
[Vue warn]:You are using the runtime-only build of Vue where the template compiler is not available.
3.2 非完整版Vue实例创建过程():
- 不支持在main.js里面写template,视图写在render函数里创建标签,接收到vue传给render的参数h,实质就是createElement,用h可以创建:
非完整版Vue原理,代码演进过程:
- 第一步
new Vue({
el:'#app', //引用的是页面index.html中<div id="app"></div>的'app'
render(creatElement){
const h =creatElement
return creatElement('div', [this.n, creatElement('button'),'+1'])
},
data:{
n:0
}
})
- 第二步,用
h代替creatElement
new Vue({
el:'#app',
render(h){
return h('div', [this.n, h('button'), '+1'])
}
})
- 第三步,添加
button监听事件
new Vue({
el:'#app',
render(h){
return h('div', [this.n, h('button',{on:{click:this.add}}),'+1'])
}
})
- 非完整版的Vue本身没有编译器compiler,而是结合webpack的vue-loader把
<div>{{n}} <botton>转化为h('div',this.n)
console.log(window.Vue)
Vue.config.productionTip = false
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;
}
}
});
4. Vue单文件组件:
- 非完整版的Vue本身没有
编译器compiler,而是结合webpack的vue-loader把<div>{{n}} <botton>转化为h('div',this.n),也可以说通过vue-loader可以把demo.vue变成一个对象。 - Vue单文件组件中的
index.html,存在一个问题:因为div内容是空的,所以会存在用户交互不友好的情况,称为SEO不友好,搜索引擎优化
<template> //视图
<div class="red">
{{n}}
<button @click="add">+1</button>
</div>
</template>
<script> //视图之外的其他选项
export default{
data(){
return {
n:0
}
},
methods:{
add(){
this.n += 1
}
}
};
</script>
<style scoped> //css样式
.red{
color:red;
}
</style>
import Demo from './Demo.vue' //引入当前目录下的Demo.vue文件
new Vue({
el:'#app',
render(h){
return h(Demo)
},
});
- 以上代码通过打log可以得知,通过
vue-loader的转化,结果得到的Demo其实就是一个对象:
render里面就是把Demo.vue的html翻译成如下代码:
render(h){
h('div')
}
对比就可以知道是做了这样的事: