一、vue的介绍
1、MVVM和MVC区别
2、框架和库的区别
框架:
是一套完整的解决方案。
对项目的侵入性较大,项目如果需要更换框架,则需要重新架构整个项目,但是优点也很明显:功能完善,提供了一整套的解决方案。
库(插件):
知识提供某一个小功能。
对项目的侵入性较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求。
3、vue和react的相同点?
利用虚拟DOM实现快速渲染。
轻量级
响应式组件
支持服务器渲染
易于集成路由工具、打包工具以及章状态管理工具
4、什么是虚拟DOM?
传统的web开发是利用jQuery操作DOM,这是非常耗资源的。
我们可以在JS的内存里构建类似于DOM的对象,去拼装数据,拼装完成后,把数据整体解析,一次性插入html里去 ,这就形成了虚拟DOM。
vue1.0没有虚拟DOM,vue2.0改成了基于虚拟DOM。
二、Vue指令总结
1、v-if和v-show的区别
v-if:不显示时,第一次就直接不渲染;如果内容已经显示将其改为不显示,将内容直接从DOM中去除。只是渲染一次,用v-if。
v-show:不显示时,就会改为display:none,但是会渲染在DOM上。反复需要切换的内容,使用v-show。
2、v-once:一次性插入,不再修改
该指令后面不需要跟任何表达式(比如之前的v-for后面只是由跟表达式 的)
该指令表示元素和组件只渲染一次,不会随着数据的改变而改变。
3、v-html:
我们从服务器请求到的数据本身是一个HTML代码,如果我们直接通过{{}}来输出,会将HTML代码也一起输出。但是我们可能希望按照HTML格式进行解析,并显示对应内容。
可以使用v-html指令,该指令后面往往会跟上一个string类型
会将string的html解析出来并且进行渲染。
v-pre:
用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
比如下面的代码:
第一个h2元素中的内容会被编译解析出来对应的内容;
第二个h2元素中会直接显示{{message}}
4、v-cloak:
5、v-bind:6、v-on
这里用一个监听按钮的点击事件,来简单看看v-on的使用
v-on也有对应的语法糖:v-on:click可以写成@click
当通过methods中定义方法,以供@click调用时,需要注意参数问题:
情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
但是注意:如果方法本身中有一个参数,那么会默认将原生时间event参数传递进去。
情况二:如果需要同时传入某个参数,同时需要event时,可以通过¥event传入事件。
v-on修饰符:
在某些情况下,我们拿到event的目的可能是进行一些事件处理
VUE提供了修饰符来帮助我们方便的处理一些事件:
①、.stop:调用event.stopPropagation()
②、.prevent:调用event.preventDefault()
③、.{keyCode|keyAlias}:只当事件是从特定键触发时才触发回调
④、.native:监听组件根元素的原生事件。
⑤、.once只触发一次回调。
7、v-if、v-else、v-else-if
这三个指令与Javascript的条件语句if、else、else if类似。
v-if的原理:
v-if后面的条件为false时,对应的元素以及其子元素不会渲染。
也就是根本没有不会有对应的标签出现在DOM中。8、小案例,实现用户登录
9、v-for
①、v-for遍历数组写法:
②、v-for遍历对象写法:
10、数组中哪些方法是响应式的?
可变参数传多个值
11、编程范式的划分
编程范式:命令式编程/声明式编程
编程范式:面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)
12、Javascript高阶函数
现在有三个需求分别是:
取出所有小于100的数字;
将所有小于100的数字进行转化:“全部*2”;
将所有new2Nums数字相加,得到最终的结果。
下面分别使用filter/map/reduce三个高阶函数来实现这三个需求。
①、filter:filter中的回调函数必须返回一个布尔值。若返回true时,函数内部会自动将这次回调的n加入到新的数组中;若返回false时,函数内部会过滤掉这次的n
②、map:对数组中的值进行修改。
③、reduce:对数组中所有的内容进行汇总。
函数式编程写法:
箭头函数写法:
13、v-model的使用
Vue中使用v-model指令来实现表单元素和数据的双向绑定。
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
①、v-bind绑定一个value属性
②、v-on指令给当前元素绑定input事件
v-model结合radio
v-model结合checkbox
①、checkbox单选框:v-model绑定的是一个布尔值
②、checkbox多选框:v-model绑定的是一个数组
v-model结合select
和checkbox一样,select也分单选和多选两种情况。
单选:只能选中一个值。v-model绑定的是一个值。当我们选中option中的一个时,会将它对应的value赋值到mySelect中。
多选:可以选中多个值。v-model绑定的是一个数组。当选中多个值是,就会将选中的option对应的value添加到mySelects中。
input中的值绑定
我们前面的value中的值都是定义input的时候直接给定的,但是在真实开发中,这些input的值可能是从网络获取或定义在data中的,所以我们可以通过v-bind:value动态的给value绑定值。
v-model修饰符
①、lazy修饰符:默认情况下,v-model默认是在input事件中同步输入框的数据的。也就是说,一旦有数据发生改变时对应的data中的数据就会自动发生改变。lazy修饰符可以让数据在失去焦点或者回车时才会更新。
②、number修饰符:默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。number修饰符可以让在输入框中输入的内容自动转换成数字类型。
③、trim修饰符:如果输入的内容收尾有很多空格,通常我们希望将其去除。trim修饰符可以过滤内容左右两边的空格。
三、组件化开发
1、注册组件的基本步骤:
Vue.extend():创建组件构造器
通常在创建组件构造器时,传入template代表我们自定义组件的模板。该模板就是在使用到组件的地方,要显示HTML代码。事实上,这种写法在Vue2.x的文档中几乎已经看不到了,它会直接使用下面提到的语法糖。
Vue.componnet:注册组件
调用Vue.componnet()是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。所以需要传递两个参数:注册组件的标签名;组件构造器。
使用组件
组件必须挂在到某个Vue实例下,否则它不会生效。
2、全局组件和局部组件全局组件:当我们通过调用Vue.componnent()注册组件时,组件的注册是全局的,意味着可以在多个Vue实例下面使用。上面是全局组件的实例。
全剧组件的语法糖写法:
局部组件:如果我们注册的组件是挂载在某个实例中,那么就是一个局部组件。下面是局部组件的实例。
局部组件的语法糖写法:
3、父组件和子组件
组件和组件之间存在层级关系,而其中一种非常重要的关系就是父子组件的关系。
下面通过代码组成这种层级关系。
4、组件模板抽离写法
通过语法糖简化了Vue组件的注册过程,但是还有一个地方的写法比较麻烦,就是template模块的写法。
如果我们能将其中的HTML分离出来写,然后挂载到对应的组件上,必然结构会变得清晰。Vue提供两种方案来定义HTML模块的内容:
第一种:使用script标签
第二种:使用template标签
5、组件模板的分离写法
组件是一个单独功能模块的封装:这个模块有属于自己的HTML模板,也应该有属性自己的数据data。
那么组件中的数据是保存在哪里呢?顶层Vue实例中吗?答案不对,不能在Vue实例中访问,如果将所有的数据都放在Vue实例中,Vue实例就会变得非常臃肿,所以Vue组件应该有自己保存数据的地方。
组件自己的数据存放在哪里呢?
组件对象也有一个data属性(也可以有methods属性),只是这个data属性必须是一个函数,而且这个函数返回一个对象,对象内部保存着数据。
6、父子组件的通信*
子组件是不能引用父组件或Vue实例的数据的。但是在开发中,往往需要一些数据确实需要从上层传递到下层:比如在一个页面中,我们从服务器请求到了很多的数据,其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。整个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)。
如何进行父子组件间的通信呢?Vue官方提到通过props向子组件传递数据,通过事件向父组件发送消息。
①、父组件向子组件传递数据:props
在组件中使用选项props来声明需要偶从父级接收到的数据。props的值有两种方式:
方式一:字符串数组,数组中的字符串就是传递时的名称。
方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。当需要对props进行类型等验证时,就需要对象写法了。
验证都支持哪些数据类型呢?
当我们有自定义构造函数时,验证也支持自定义的类型。
②、子组件向父组件传递数据:
什么时候需要自定义事件呢?
当子组件需要想父组件传递数据时,就要用到自定义事件了。
我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。
自定义事件的流程:
在子组件中,通过$emit()来触发事件。
在父组件中,通过v-on来监听子组件事件。
示例一:两个按钮+1和-1,点击后修改counter。我们整个操作的过程是在子组件中完成的,但是之后的展示交给父组件,这样,我们就需要子组件中的counter,传给父组件的某个属性,比如total。
示例二:
③、父子组件的访问方式:$children
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
父组件访问子组件:使用$children或$refs.reference(引用)
$refs=>对象类型,默认是一个空的对象 ref=‘bbb’
子组件访问父组件:使用$parent
访问根组件:使用$root
四、组件化高级
1、slot插槽
在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。插槽的目的是让我们原来的设备具备更多的扩展性。组件的插槽也是为了让我们的组件更加具有扩展性。
如何去封装这类的组件呢?
它们有很多区别,但是也有很多共性。如果,我们每一个单独去封装一个组件,显然不合适,比如每个页面都有返回,这部分内容我们就要重复去封装。
如何封装合适呢?抽取共性,保留不同。
最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽。一旦预留好插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。
2、具名插槽的使用
3、编译作用域
父组件模板中的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子组件作用域内编译。
4、作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供。
五、模块化开发
多个JS文件会导致命名冲突,代码不可复用。采用匿名函数可解决命名冲突,但是代码不可复用。
我们可以使用将需要暴露到外面的变量,使用一个模块作为出口。下面是模块化最基础的封装。
1、常见的模块化规范:
CommonJS(node就是采用该规范)、AMD、CMD,也有ES6的Modules。
2、模块化有两个核心:导出和导入
下面是CommonJS的模块化:
3、import和export的使用
我们使用export指令导出了模块对外提供的接口,用import命令来加载对应的模块。
下面是几种导入导出方式。
export default
某些情况下,一个模块中包含某个功能,我们不希望给这个功能命名,而且让导入者可以自己命名,这时候可以采用export default。
需要注意的是export default在同一个模块中,不允许存在多个。
通过*key导入模块中所有的export变量,但是通常情况下我们需要给*起一个别名,方便后续的使用。