1. 学习前提条件
- html标签语法
- js基础知识
- es6常用语法
2. vue是什么
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。(从官网摘抄)
vue是当今世界三大前端主流框架之一,其余两个是angualr和react。vue脱胎于angular,使用MVVM的设计思想实现双向数据绑定,以其简单易用能够快速上手而被开发人员广泛使用。VUE使开发人员专注于页面逻辑的开发而免去频繁操作dom的繁琐操作。
3. 学习环境搭建
vue官网上用例是直接使用node进行安装,但是这对于入门小白来说有一定的门槛(比如我),一开始接触就遇到node、npm命令等等实在是不明所以,总觉得隔了一层东西。
所以现阶段我们先不安装vue脚手架和nodejs等,只在我们的代码种引入vue的js文件就可开始学习。引入js学习可以更好的帮助我们理解vue的底层原理,为以后学习使用vue进行组件化开发、node进行开发打好基础。
node等以后我们学到了一些企业级开发方式的时候再去安装也不迟。
3.1 引入方法
- 下载vue.js。https://unpkg.com/vue@3.3.4/dist/vue.global.js
- 创建一个html文件并引入刚才下载的js文件
- 打印Vue
示例
<html>
<header>
</header>
<body></body>
<script src="./js/vue.global.js"></script>
<script>
console.log('hello vue', Vue);
</script>
</html>
4. vue实例创建和使用
我们想要使用Vue第一步就是创建一个Vue实例。然后通过实例去挂载我们页面上的元素,挂载之后页面元素就会被Vue接管,Vue的相关特性、api等才会应用在元素上。
示例:
<html>
<header>
</header>
<body>
<p>{{ name }}</p>
<div id="root">
<p>{{ name }}</p>
</div>
</body>
<script src="./js/vue.global.js"></script>
<script>
let vue = Vue.createApp({
data() {
return {
name: "码小飞飞飞"
}
}
});
vue.mount('#root')
</script>
</html>
运行效果:
- 在本例中,我们创建了一个叫vue的app实例,然后使用实例的mount方法将其挂载到页面元素'#root'(使用了id选择器,实际我们也可以使用其他元素选择器进行挂载)上。在实例中我们创建了date方法,方法返回了一个数据对象,数据对象中包含一个name属性。
- 在页面上,我们在#root元素内创建了一个p标签,标签内使用了{{}}模板绑定语法绑定了name属性。当vue调用mount方法后,Vue框架会将data里的name渲染到页面模板的{{}}中。
- 在未被挂载的元素中,即我们在'#root'元素外声明的模板绑定语法就会被当作一个普通的p标签渲染出来,其内部的name并不会被vue解析
注意:在上述例子中我们只创建了一个app实例。其实vue是可以在页面上创建多个app实例的,且app实例与页面元素的对应关系只可是一对一,如果是多对一的情况则vue只会将第一个调用mount方法的实例绑定到元素上,其他实例即使绑定也不会生效。
5. 模板语法、插值表达式
模板语法就是将我们在app实例内声明的属性给渲染到页面声明的模板里。其特点就是使用双花括号{{}},内部包含一个能够返回值的js表达式,表达式是指能够产生明确值的js语句。在上面的例子中我们已经简单使用了模板语法,将data方法中返回的name属性渲染到了页面的双花括号内。
要区分js表达式和js语句,js表达式是能返回明确值的,js语句不一定能返回明确值比如if、for等条件控制语句
模板语法内可写入以下内容
- 普通属性
<p>{{ name }}</p>
- 表达式
<p>{{ firstName + " " + lastName }}</p>
<p>{{ isAuthor ? '是作者本人' : '是其他人' }}</p>
- 方法返回值
<p>{{ getFullName() }}</p>
6. 数据绑定(指令语法)
模板语法可以让我们将数据绑定到页面内容上,但是不能将数据绑定到页面元素的属性上。如果我们需要将表达式、变量绑定到页面元素的属性上,需要使用指令v-bind来实现
示例:
<html>
<header>
</header>
<body>
<div id="root">
<p v-bind:id="uid">{{ name }}</p>
<p :id="uid">{{ name }}</p>
<p id="{{ uid }}">{{ name }}</p>
</div>
</body>
<script src="./js/vue.global.js"></script>
<script>
let vue = Vue.createApp({
data() {
return {
uid: '1',
name: "码小飞飞飞"
}
}
});
vue.mount('#root')
</script>
</html>
我们使用v-bind:+要绑定的属性名就可以将在app中声明的变量绑定到指定的属性上,我们可以使用这个指令绑定一切属性比如表单标签的value属性、name属性、innerHtml等。v-bind:的有简写语法,可以直接写:+属性名,运行效果是一样的。
v-bind是vue的指令之一,用来进行标签的属性绑定,vue还提供了很多功能强大的标签来操作页面元素,我们以后会慢慢接触到。
v-bind同模板绑定一样,也可以在其内部绑定属性、表达式、函数返回值,在此不再举例,感兴趣可以自己试一试
7. 双向数据绑定(MVVM)
我们使用模板语法或者绑定标签只能将数据进行单向传递,即从定义的数据模型传递到页面模板上,反过来是无效的。比如我们在一个表单元素input中输入一段话是无法反写到属性中的。
比如下面这个例子
<html>
<header>
</header>
<body>
<div id="root">
<p :id="uid">{{ name }}</p>
<input id="name" type="text" :value="name">
</div>
</body>
<script src="./js/vue.global.js"></script>
<script>
let vue = Vue.createApp({
data() {
return {
uid: '1',
name: "码小飞飞飞"
}
}
});
vue.mount('#root')
</script>
</html>
在页面渲染完毕后,我们可以看到p标签和input表单内都显示了"码小飞飞飞飞",并且input标签使用了v-bind绑定了name值和value属性。但是当我们在input标签中敲入其他值后,p标签内的数据并没有发生变化。此时我们可以证明v-bind绑定的属性只是单项的从属性传导到了页面,而页面上的变化是无法传递回属性值的,即数据是单项绑定。
为了解决表单数据的双向数据绑定问题,即让页面上的修改能映射回属性上,vue为我们提供了新的指令v-model,用法为v-model="要绑定的js属性值"。
示例:
我们将上面的例子修改以下即可
<html>
<header>
</header>
<body>
<div id="root">
<p :id="uid">{{ name }}</p>
<input id="name" type="text" v-model="name">
</div>
</body>
<script src="./js/vue.global.js"></script>
<script>
let vue = Vue.createApp({
data() {
return {
uid: '1',
name: "码小飞飞飞"
}
}
});
vue.mount('#root')
</script>
</html>
此时我们再向input框中敲入值后,敲入的值会回显到p标签内。可以证明,我们的数据不仅从属性传导到了页面,还能通过修改页面上的值将数据传导回属性上。
v-model中只能写属性值,而不能写表达式和函数返回值了。原因也很简单,我们使用v-model是想将表单元素中的value与js属性进行绑定,实现双向的数据绑定。而当我们内部填写了表达式或函数以后,vue就无法判断我们具体是想将页面的变化传递回哪个属性上了,因为表达式或函数可以写的很复杂。
这就体现了vue的设计思维,使用了MVVM的思想,即M(model)模型、V(view)视图、VM(view model)视图模型
- model代表了我们的数据源,是一个数据模型,比如我们从服务器中获取到的商品信息(名称、价格、库存等)
- view代表了我们的展示页面,即一段html+css的综合代码,负责展示model中的数据
- view model负责将model和view连接起来,是他们两个沟通的桥梁。当model中的值发生变化时,负责通知给view更新页面。当view中用用户进行操作影响了model中的值时,负责将变化的值传递回model属性
8. 数据绑定原理
数据绑定的原理在Vue2.X时使用的时ES6的对象操作API Object.defineProperty()方法,在Vue3.X使用了ES6新特性Proxy代理对象来实现的。两种方式的核心原理其实都是数据代理(将两个不同对象的某个属性做映射,当一个对象的属性变化是可以使另一个对象的属性也变化),即将页面dom元素的输入给通过数据代理的方式绑定到js属性上,当js属性变化时通过代理监听得到变化值,然后将变化的值渲染到页面dom元素里。
下面我们简单示例一下两种数据代理方式
<html>
<header>
</header>
<body>
</body>
<script>
let customName = '页面上的name';
let obj = {
id: '1',
name: '码小飞飞飞飞'
}
//将obj的name属性和customName进行了绑定,当customName变化时,obj.name也会发生变化,反之也是。
Object.defineProperties(obj, {
'name': {
get() {
console.log('get方法被调用');
return customName;
},
set(value) {
console.log('set方法被调用');
customName = value;
}
}
})
let name = obj.name;
obj.name = '123';
console.log(obj);
let obj2 = {
id: '2',
name: '码小飞飞飞飞2'
}
//创建代理对象,代理obj对象的赋值和取值方法,当代理对象变化时,原对象的属性也会发生变化,反之也是。
let proxyObj = new Proxy(obj2, {
get: function (target, attr, receiver) {
console.log('proxy get方法被调用');
return target[attr];
},
set : function(target, attr, value){
console.log('proxy set方法被调用');
target[attr] = value;
}
});
let pName = proxyObj.name
proxyObj.name = '456';
console.log(proxyObj);
</script>
</html>
Vue就是通过上述方式实现了页面dom元素与我们的js属性实现了双向数据绑定。当然单向绑定也是这样实现的,我们根据需求只实现set或get的一边就可以了。
本人也是刚入门前端,文中有不正确的地方还请在评论区指正,我会及时改正,万分感谢。