let app = new Vue({
el: '#app',
template: `<div>Hello!</div>`
})
- 挂载点不能是html、body元素
- 每一个组件有且只能有一个顶级元素
- 如果一个组件没有template、render,那么el(挂载点)的outerHTML就作为模板
渲染优先级render优先级高于其他视图处理
指令
表达式的值除了可以出现内容中,也可以使用在其他位置,比如:属性。但是不能使用{{}} 语法,而是需要 指令
。
在 vue
中,指令是一个带有 v-
前缀的属性,与普通属性不一样的地方在于,指令的值是引号括起来的 表达式
,不同的指令有不同的作用, vue
内置了一些常用的指令,后期还可以自定义属于自己的指令
- 内容输出
通过
{{}}
我们可以很方便在模板中输出数据,但是这种方式会有一个问题,当页面加载渲染比较慢的时候,页面中会出现{{}}
,vue
提供了几个指令来解决这个问题。
指令中的表达式不需要{{}}
v-text
<p v-text="title"></p>
弊端: v-text 会填充整个innerHTML
v-cloak
<p v-cloak>{{title}}</p>
需要配合css
进行处理
<style>
[v-cloak] {
display: none;
}
</style>
v-html
...
- 循环
- 逻辑
- 属性绑定
- 事件
- 其他
单项数据流(简称为:
)
在上面的案例中可以看到当数据更新的时候页面视图就会更新,但是页面视图中绑定的元素更新的时候,对应数据是不会更新的
<input type="text" :value="title" />
通过 {{}}
、v-bind
等, 语法,可以把数据实例中的数据显示在视图中
当实例中的数据发生变化的时候,海会自动去更新视图(数据流, 数据 --> 视图)
视图发生了变化,数据不会变
{{}}
、v-bind
等 都是单向绑定,但是 可以通过事件监听方式去修改数据。
双向数据流(v-model)
在 vue
可以通过 v-model
实现数据的双向绑定,但 不是所有的元素都能够使用v-model,表单元素 + 自定义组件这类可以使用 v-model
<input type="text" v-model="title" />
在vue 中,还有一种
组件中的数据(状态-data)
data 中的数据会被遍历挂载到实例对象上,所以 data 中的数据命名要注意,不要和实例本身的一些属性方法重名。
_
和 $
开头的属性 都是vue实例内置的属性和方法
_
: 内置私有属性和方法,内部使用,不建议外部调用
$
: 内置属性和方法,可以在外部调用
<div id="app">
<div>n: {{n}}</div>
</div>
let app = new Vue({
el: '#app',
data: {
n: 1
}
})
// 或者
console.log(app.$data);
console.log(app.n);
检测变化的注意事项
不要通过 .
的方式给 data 中的对象增加新的属性,因为不能通过 vue 进行defineProperty 处理。
Vue 把内部对 data 进行了 拦截处理 api 提供出来了,如下:
Vue. set(app.user, 'genter', '男')
实例.$set
是 Vue.set 的别名
app.$set(app.user, 'genter', '男')
;
在vue3
之前,数据的监听是通过 Object.defineProperty
的方法来实现的,但是该方法只能监听拦截单个数据,对于对象新增属性无法监听拦截。所以,对于数据对象中新增的属性,我们需要调用 vue
提供的方法进行处理。
扩展
通过 Object.defineProperty
监听拦截中存在一些问题
- 属性新增属性
- 数组方法: push、pop、 shift、unshift、splice、sort、reverse
- 数组新增值: []
- 数组 length 属性
以上的操作中并不会触发监听拦截
可复用的功能组件
通过Vue提供的静态方法 component窗口可复用的功能组件
// 使用
<my-component></my-component>
// 注册
Vue.component('MyComponent', {
template: `<div>MyComponent!</div>`
});
let app = new Vue({
el: '#app'
})
computed(计算属性)
- 该属性是通过计算得到的(get,set逻辑)
- 当计算属性依赖的数据发生了变化,计算属性就会重新计算值
computed: {
showUsers: {
get() {
if(this.gender === '') {
return this.users;
} else {
return this.users.filter(user => user.gender === this.gender);
}
}
}
}
- 当一个计算属性只有get的时候,可以直接写成一个函数
computed: {
showUsers: {
if(this.gender === '') {
return this.users;
} else {
return this.users.filter(user => user.gender === this.gender);
}
}
}
<input type="check box" v-model="checkedAll" /> 全选
computed: {
checkedAll: {
get() {
return this.users.every(user => user.checked)
}
set(newVal) {
// 不用再次赋值,因为v-model已经做了赋值操作,如果赋值则会造成死循环
// this.checkedAll = newVal;
}
}
}
- 计算属性的值可以进行缓存,如果依赖的其他响应式数据没有发生变化,但多次访问该计算属性,得到结果是最近一次变化产生的值(相对于调用方法得到结果在某些时候性能要好一些)
- 不支持异步
watch
- 支持异步
watch: {
async keyWord() {
let users = await getUsers(this.keyWord)
this.
}
}
- 多层监听
对于多层数据监听,可以使用字符串 + 点语法
watch: {
'a, b, c': function() {
// ....
}
}
- 深度监听
默认情况下,·watch·只对当前指定的值进行一层监听,如果需要对对象进行深度监听,则需要设置deep: true,handler() 需要做的处理
watch: {
a: {
handler() {
console.log('a deep')
},
deep: true
}
}