1 Vue的两个版本
完整版:编译器compiler+运行时runtime。CDN引入所对应的文件名为vue.js或vue.min.js(生产版)。
- 编译器:将template里的html编译成JS代码
- 运行时:创建vue实例,render,虚拟dom
1.1 完整版 vue.js、vue.min.js
需要有编译模板、编译器,CDN引入
index.html
<body>
<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script>
</body>
main.js
new Vue({
el:'#app', //挂载到id为app的容器上
template: '<div>{{ n }}</div>', //模板:将 <div id="app"></div>替换为<div>0</div>
data:{
n:0
}
})
data 不仅可以是对象,还可以是函数
data(){
return {
n:0
}
}
1.2 运行时版(非完整版)vue.runtime.js
只包含运行时的版本,没有编译器,CDN引入所对应的文件名为vue.runtime.js或vue.runtime.min.js。
index.html
<div id="app">
{{n}}
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.runtime.js"></script>
main.js:用JS构建视图
new Vue({
el:'#app',
render(h){ //render里的h函数创建html节点
return h('div',this.n)
},
data(){
return {
n:0
}
}
})
建议:优先使用非完整版:没有编译器,代码体积小,用户体验好。
1.3 单文件组件 demo
由于h函数比较复杂,可以先使用Vue-loader将demo.vue文件编译成JS(把vue文件里的html转换成h函数),然后使用运行时版
新建demo.vue
<template> <!--写视图-->
<div class='red'>
{{n}}
<button @click="add">+1</button>
</div>
</template>
<script> //视图之外的其他选项
export default {
data() { //data只能是以函数形式存在
return {
n:0
}
},
methods:{
add(){
this.n=this.n+1
}
}
}
</script>
<style scoped> /* css */
.red {
color:red;
}
</style>
在main.js里
import demo from './demo.vue' //引入该单文件组件
//console.log(demo) //获取到的demo是个对象
new Vue({
el:"#app",
render(h){
return h(demo)
}
})
问题:在index.html里,SEO(搜索引擎优化)不友好
<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.runtime.js"></script>
原因:只用JS来创建div,而不是在index.html里写好
解决办法:在Index.html里写好title description keyword h1标签,不用js写这些
1.4 两个版本区别
| Vue完整版(vue.js) | Vue运行时版(vue.runtime.js) | |
|---|---|---|
| 特点 | 有compiler | 没有compiler |
| 视图 | 写在HTML里,或者写在template里 | 写在render函数里,用h创建标签 |
| cdn引入 | vue.js | vue.runtime.js |
| webpack引入 | 需要配置alias | 默认使用 |
| vue@cli引入 | 需要额外配置 | 默认使用 |
2 template
2.1 创建一个demo.vue文件,template标签
<template>
<div id="app">
{{n}}
<button @click="add">+1</button>
</div>
</template> `
<script>...</script>
<style scoped>...</style>
2.2 js中的Vue构造函数里的template选项
new Vue({
el:'#app',
data:{
n:0
},
template :`
<div id="app">
{{n}}
<button @click="add">+1</button>
</div>`
})
3 render
(1)不完整版的JS中,用于构建视图
new Vue({
el:'#app',
data:{
n:0
},
render(h){
return h('div', this.n)
}
})
(2)使用vue-loader+不完整版,
import demo from "./demo.vue"
new Vue({
el: "#app",
render(h) {
return h(demo)
}
})
4 data
data 选项是一个函数,return 回一个对象。返回对象的属性在 template 里的{{ }}和组件属性绑定<son :Count="count" />时可以直接使用,如果没有初始值的属性用 null 或者 undefined 占位。
data() {
return {
count: 0,
name: null
}
}
注意:
- 实例创建后再添加的property,就不是响应式数据了。
- Vue2 的 data 可以是对象,但 Vue3 的data只能是函数,否则会报错。
- Vue2 中 组件中的 data 必须使⽤函数,否则组件复用后 data 对象会共用同一个内存地址,共用数据造成数据污染。
5 computed 与 watch
computed
- computed是计算属性,是用来计算出一个值的,如果数据a依赖数据b,则数据a可以设计成computed。
- computed里定义的函数有返回值,调用函数时不用加
(),当成属性用; - 根据依赖自动缓存:依赖不变,computed值直接使用缓存之,不会重新计算
- 注意methods和computed里面的方法不要使用箭头函数,否则this就不是vm对象了 计算属性count会依赖data中的属性books,books发生改变自动触发count的变化
<template>
<div>
<p>{{name}} published {{count}} books:</p>
<button @click="add">Add book</button>
</div>
</template>
<script>
export default {
data() {
return {
name: 'lucy',
books: ['book1']
}
},
methods: {
add() {
this.books.push('book')
}
},
computed: {
count() {
return this.books.length
}
}
}
</script>
watch
- watch是监听。使用场景:1.当需要根据data中某个property的变化做出反应,但不⼀定需要拿到结果时。2.异步操作。3.需要使用旧值时。
const vm = Vue.createApp({
data() {
return {
name: 'lucy'
}
},
watch: {
name(newname, oldname) {
console.log(oldname + '->' + newname)
}
}
}).mount('#app')