vue的引用
通过script标签的方式进行引用。
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
组件
vue
的核心功能之一就是组件
组件基本分类
- 根组件
- 可复用的功能组件
根组件的创建
通过 vue
提供的构造函数可以实例化出来一个跟组件实例对象
let app = new Vue(options);
应用最顶层的组件,一般情况下,一个独立的应用有且只有一个根组件(节点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue.js"></script>
</head>
<body>
<!-- VUE的入口 -->
<div id="app"></div>
<script>
// 创建一个根组件
let app = new Vue({
// 定义一个模板
template: '<div>xiaokang.me</div>'
})
// 将模板添加到#app这个元素中
app.$mount('#app')
</script>
</body>
</html>
上面发生了什么?
其实通过实例化Vue对象,传入配置字段
template
相当于定义了一个模板,通过Vue对象提供的$mount
方法,将其添加到指定的标签元素中。类似于createElement
与appendChild
的概念。
可复用的功能组件
通过 Vue
提供的静态方法 component
窗口可复用的功能组件
let component1 = Vue.component(options)
组件配置选项:https://cn.vuejs.org/v2/api/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- VUE的入口 -->
<div id="app"></div>
<script src="./js/vue.js"></script>
<script>
// 定义一个可以复用的组件
Vue.component('tab', {
template: `<div>这是一个tab选项卡</div>`
})
// 创建一个根组件
let app = new Vue({
// 定义一个模板
template: `
<div>
<p>xiaokang.me</p>
<tab />
<br />
</div>
`
})
app.$mount('#app')
</script>
</body>
</html>
el选项
如果提供了 el,且又没有提供template,那么会自动把el的innerHTML作为template。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- VUE的入口 -->
<div id="app">
<h1>xiaokang.me</h1>
<tab>
</div>
<script src="./js/vue.js"></script>
<script>
// 定义一个可以复用的组件
Vue.component('tab', {
template: `<div>这是一个tab选项卡</div>`
})
// 创建一个根组件
let app = new Vue({
el: '#app'
})
</script>
</body>
</html>
data与更新
使用 vue 的原因,在于数据,页面会根据不同的数据显示不同的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- VUE的入口 -->
<!-- vue中的花括号内可填入的内容
* 表达式:可以通过运算(执行)得到结果(数据)的公式
* - 变量
* - 函数调用
* - 数学运算
*
* 语句:if,else,while,for....
*
* 数据来源于组件内部,比如 data 中的数据
* 解析过程中,会自动绑定组件实例中的数据
-->
<div id="app">
<h1>xiaokang.me</h1>
<h2>name:{{name}}</h2>
<tab>
</div>
<script src="./js/vue.js"></script>
<script>
// 定义一个可以复用的组件
Vue.component('tab', {
template: `<div>这是一个tab选项卡</div>`
})
// 创建一个根组件
let app = new Vue({
el: '#app',
// 用来挂载组件所需要渲染的数据
data: {
name: 'Xioakang',
age: 18
}
})
</script>
</body>
</html>
将数据传入到Vue对象选项中的data
字段,在模板里只需要通过{{}}
即可调用到该属性,例如{{name}}
表示调用data.name
,其数据来源于data中的数据,所以不需要写data.name
。
Vue会把
data
传入的属性挂载到Vue对象中,因此属性命名时不可以与原有属性冲突。
关于数据的更新,只需要改动属性即可。如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDGUIWhc-1604307226840)(https://files.alexhchu.com/2020/09/25/c32eb08ffe3c9.gif)]
拦截数据
简单来说,就是数据修改时拦截数据,这样就实现了只关注数据的修改,而不关心渲染。
在 vue3 之前,数据的监听是通过
Object.defineProperty
方法来实现的,但是该方法只能监听拦截单个数据,对于对象新增属性无法监听拦截。所以,对于数据对象中新增的属性,我们需要调用 vue 提供的方法来进行处理
对vue的模拟如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let obj1 = {
x: 1,
y: 2
}
function render() {
console.log('渲染了!');
}
let obj2 = Object.assign({}, obj1)
// 当每次修改x属性时,调用render函数进行渲染。
Object.defineProperty(obj1, 'x', {
set(newVal) {
// 如果使用obj1会导致循环递归的问题,因此使用另一个变量
obj2.x = newVal
render()
},
get() {
return obj2.x
}
})
obj1.x = 2
console.log(obj1.x);
</script>
</body>
</html>
通过 Object.defineProperty
监听拦截中存在一些问题
- 属性新增属性
- 数组方法:push、pop、shift、unshift、splice、sort、reverse
- 数组新增值:[]
- 数组 length 属性
以上的操作中并不会触发监听拦截
vue
对数组中的push
、pop
等方法进行重新包装,所以在vue
中调用这些方法,可以对数组的修改进行监听拦截https://cn.vuejs.org/v2/guide/list.html#%E5%8F%98%E5%BC%82%E6%96%B9%E6%B3%95-mutation-method
为了解决上述问题,vue2提供了set方法,其原理如下:
function set(key, value) {
Object.defineProperty(obj1, key, {
set(newVal) {
value = newVal;
render();
},
get() {
return value;
}
})
}
此时通过调用set方法即可对新属性进行拦截。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t2Ysq6cB-1604307226841)(https://files.alexhchu.com/2020/09/27/c767424bc2d2c.gif)]
在vue中有两种方式调用set方法:
Vue.set(app.user, 'age', 19)
// 或下面的方法(app为Vue的实例对象)
app.$set(app.user, 'age', 19)