2、组件化开发
前言
- 基础篇链接:https://www.cnblogs.com/xiegongzi/p/15782921.html
2.1、认识组件概念
- 对于学Java的人来说的话,这个词所要表达的意思再熟悉不过了,所谓组件就是:面向对象中的抽象、封装思想,而所谓的组件化就是:把功能用多组件的方式搭配起来编写( 有一个根组件,旗下有N多微型组件 ,粗暴理解就是:SpringCloud中的main()方法可以搭配很多不同功能的注解,main()方法就是根组件,不同功能的注解就是微型组件 ),而这些功能组成的应用程序就是一个组件化应用,因此:这样做之后,好处就是利于维护和提高代码的复用性了
- 但是对于前端的人来说,这个东西就需要特别解释一下:直接下定义就是 实现应用中局部功能代码和资源的集合
- 至于为什么要学组件化开发?
- 一是因为做的应用页面都是很复杂的,如果使用传统的CSS+HTML+JS,那么就会出现很多的js文件,不利于维护和 编写很费力的
- 二是因为组件化开发可以极好的复用代码、简化项目代码、所以也就提高了运行效率
同时组件又有单文件组件( 真实开发玩的 ) 和 非单文件组件
- 单文件组件:就是指只有一个组件组成( 即:是一个.vue的文件 )
- 非单文件组件:就是有N多个组件组成
2.2、非单文件组件
2.2.1、使用组件
玩一下组件
组件小结
- Vue中使用组件的三板斧
- 1、创建组件
- 2、注册组件
- 3、使用组件( 写组件标签即可 )
- 如何定义一个组件?
- 使用Vue.extend( { options } )创建,其中options 和 new Vue( { options } )时传入的哪些option“几乎一样”,区别就是:
- 1、el不要写 ——— 因为最终所有的组件都要经过一个vm的管理( 根组件 ),由vm中的el决定服务哪个容器
- 2、data必须写成函数式 ———— 因为可以避免组件被复用时,数据存在引用关系
- 另外:template选项可以配置组件结构
- 使用Vue.extend( { options } )创建,其中options 和 new Vue( { options } )时传入的哪些option“几乎一样”,区别就是:
- 如何注册组件?
- 1、局部注册: 靠new Vue的时候传入components选项
- 2、全局注册:靠Vue。component( '组件名' , 组件 )
- 真实开发中一般都是玩的局部组件,局部变全局一般都是一样的套路,去掉s,然后使用Vue来调,最后加入相应的名字和配置即可
- 最后编写组件标签即可使用,如:
2.2.2、使用组件的注意点
1、创建组件时的简写问题
-
// 1、创建局部组件( 完整写法 ) const person = Vue.extend({ template: `
{{name}}
{{age}}
{{name}}
{{age}}
-
上面两种都可以
2、组件名的问题
- (1)、组件名为一个单词时
- (2)、组件名为多个单词组成时
- 全部用小写 / 使用 - 进行分割都没问题( 此种分割需要注意在注册时的方式,加单引号 )
- 还有一种就是上图中的效果:大驼峰命名
- (3)、注意组件名别和HTML中的原生标签名一致,会冲突报错,HTML的限制就是上图中看源码中的哪些( 别想着它是小写,你搞大写,也是不行的^ _ ^ ),如果非要用HTML标签名,让人见名知意,那就在原生HTML标签名前加一些特定的词,如:user-input这种【 一般加的前缀都是功能点名称 】,记得千万别用:input、h2....此类名字来命名组件名
3、关于组件在使用时的注意项
2.2.2.1、使用组件注意点总结
- 1、关于组件名
- 2、关于组件标签( 使用组件 )
- (1)、使用开放标签也行,如:
- (2)、使用自闭合标签也行,如:
- 但是:此种方式目前有坑,会出现后续组件不能渲染的问题,所以需要等到后续使用脚手架时才可以
- (1)、使用开放标签也行,如:
- 3、创建组件的简写形式
- const person = Vue.extend( { 配置选项 } ) 可以简写为 const person = { 配置选项 }
2.2.3、组件的嵌套 / 子父组件
- 很有用啊,真实开发玩的是单文件组件,逃不开这个点的,而且还会有子父组件通信和兄弟组件通信
组件嵌套
另一种嵌套:开发中玩的,我的快捷模板给那个div容器起的id值为app,是有用的
2.2.4、认识VueComponent()函数
1、来看一下组件到底是谁?
-
既然知道了组件真身是VueComponent(),那么先去源码中看一下它,从而获取到一些对自己有用、能明白的信息
-
源码提取出来就是下面的样子
-
var Sub = function VueComponent (options) { this._init(options); }; return Sub };
-
-
经过前面的分析和查看源码得出两个结论:
- 1、所有的组件指的都是VueComponent()
- 2、每一个组件都调用了VueComponent(),但是:它们都不一样( 源码中有嘛,每次都是创建了一个全新的sub,sub就是VueComponent(),最后把这个sub返回去了,验证一下嘛
- 但是:这里有一个有意思的东西,不了解原因的人很容易弄错,也是第一条说的组件就是指VueComponent(),从而会出现不了解的人认为:每个组件都是调了同一个VueComponent(),来看一下
VueComponent()小结
-
组件本质是一个名为VueComponent()的构造函数,且不是程序员自己定义的,是Vue.extend()生成的
-
我们只需要写组件标签(
或
) ,Vue解析组件标签时会帮我们创建组件的实例对象,即:Vue帮我们执行了new VueComponent( { options配置选项 } )- 注意点:每次调用Vue.extend(),返回的都是一个全新的VueComponent
-
关于this的指向问题
- (1)、在组件配置中:
- data函数、methods函数、watch中的函数、computed中的函数,它们的this均是【VueComponent实例对象】
- (2)、在new Vue()配置中:
- data函数、methods函数、watch中的函数、computed中的函数,它们的this均是【vue实例对象,即:前面玩的vm 】
- (1)、在组件配置中:
-
VueComponent实例对象,简称:vc( 或:组件实例对象 )
-
Vue实例对象,简称:vm
-
但是:vm和vc也有一个坑
-
观察结构会发现:vm和vc如出一辙,什么数据代理、数据监测等等,vm有的,vc都有,所以vm中的配置项在vc中都可以配置,但是:vm和vc不能画等号,它们两个不一样
- vm是Vue实例对象,vc是组件实例对象
- vm中可以使用el选项,而vc中不可以( 只要用el就报错 )
- 在vm中,data可以用函数式和对象式,但是在vc中data只能用函数式
- vm是大哥,vc是小弟,vc是vm的组件( 或者说:算上app,那么vc就是vm的后代 )
- vm和vc之间很多东西只是复用了而已- ( 这里说的复用,里面有大门道,vm和vc之间是有关系的,这里需要原型对象知识 —— 就一句话:函数肯定有prototype( 显示原型属性 ),而实例( 如:const person = vue.extend()中的person )肯定有 _ _proto _ _ ( 隐式原型属性 ),而这二者指向的是同一个对象:即,该实例的原型对象,而vc和vm之间就是通过这二者关联起来的
-
vm和vc之间的内置关系是:VueComponent.prototype._ _proto _ _ === Vue.prototype【这句话的验证自行在控制台输出查看,答案是:true】
以上的内容就属于非单文件组件相关的,接下来就看单文件组件,也是开发中会做的事情
2.3、单文件组件
- 就是只有一个文件嘛,xxxx.vue
- 而xxxx就是前面说过的组件命名
- 单个单词:全小写、首字母大写
- 多个单词:用 - 进行分割、大驼峰命名
- 而开发中最常用的就是:首字母大写和大驼峰命名
2.3.1、疏通单文件组件的编写流程
- 前提:如果自己的编辑器是vscode,那么就给编辑器安装vetur插件,然后重启vscode,这个插件就是为了能够识别xxxx.vue文件的;如果自己是用的IDEA编辑器来写的vue,那么安装了vue.js插件之后,不用安装其他的插件都可以的
2.3.1.1、创建xxxx.vue文件
- 这个创建的就是单文件组件,前面玩非单文件组件,不是有三板斧吗,对照来看
- 创建了xxx.vue之后,是一个空文件,里面要写的东西就三样(模板template、交互script、样式style ),里面内容也对照非单文件组件来看
{{name}}
2.3.1.2、注册组件到app中
- 前面玩过,vm管app,app管其他的小弟,所以需要一个app组件,创建一个app.vue
2.3.1.3、将app和vm绑定起来
- 新建一个main.js文件,创建这个文件的目的:一是让app和vm绑定,二是浏览器并不能识别.vue文件,所以根本展示不了,因此:需要将.vue文件转成js文件,这样浏览器就能解析了【 当然:解析的门道没这么简单啊 】
// 1、引入app组件
import App from "./2App.vue"
// 2、把app组件和vm进行绑定
new Vue({
// 这里面和以前一样写法,当然:这里的el值绑定的是容器id,怕误会改成root也行
el: '#App',
components: {App}
})
2.3.1.4、创建容器
- 前面app组件和vm绑定了,但是vm中指定的el值,它绑定的容器还没有啊,因此:创建index.html
创建el容器
- 而整个流程按照解析的逻辑来看就是如下流程
当然:以上的东西弄完之后,还启动不了,一启动就会报错
2.3.2、认识脚手架 vue cli
2.3.2.1、使用nodejs配置脚手架
- 前提:保证自己的电脑有nodejs,玩后端的人要是不了解nodejs的话,就把它理解为服务器,低配版的tomcat,
- nodejs的配置很简单,官网进行下载、一直next
- 有个注意点:选择安装目录时,别把nodejs安装到系统C盘了,不然很大可能出现权限不足,无法操作的问题,特别是:如果自己的电脑没升级,还是家庭版的而不是专业版的,这种问题更常见
- 出现这种问题就需要切换到管理员身份运行cmd才可以进行安装vue-cli了,甚至有时会奇葩点:需要在管理员身份下运行npm clean cache –force
- 然后再进入到C盘的用户目录下的appdata/roaming下把一个叫做npm-cache的缓存文件删了,最后再用管理员身份运行npm clean cache –force清除缓存【 当然:npm clean cache –force不是绝对好用,还得看自己的另外配置 不多延伸了 】,经过上面的操作,把自己整疯了之后才可以安装vue cli脚手架
- 有个注意点:选择安装目录时,别把nodejs安装到系统C盘了,不然很大可能出现权限不足,无法操作的问题,特别是:如果自己的电脑没升级,还是家庭版的而不是专业版的,这种问题更常见
-
LTS就是稳定版,而CURRENT就是更新版( 新特性就丢在这里面的,可能会出现bug,所以不推荐下载 )
-
-
其中下载msi和zip都可以,区别就是msi是直接帮你把环境变量配好了的,当然:也有其他的区别,而zip就是解压之后,自己进到目录下复制路径,然后配置在“系统环境变量”的path目录中即可,这些操作玩java的第一天就弄了jdk的环境变量,所以再熟悉不过了,而如果是前端人员,nodejs早学了,所以可以下滑到到后面全局安装vue cli那里,安装成功之后是如下效果
-
查看一下是否成功?
-
进入dos窗口( win+r,输入cmd回车 )
-
表明成功
-
但是:现在npm的配置和缓存文件都在C盘用户目录/appdata/roaming/npm 和 appdata/local/npm-cache中的
-
因此:我们需要去改动这两个地方( 知道了这两个目录,不用改也可以,后面什么事都可以不做的,对后续的操作也没影响 ,嫌找东西时麻烦就可以改 )
-
1、在安装的nodejs中新建node_global和node_cache两个文件夹( 前为全局配置路径,后为npm缓存路径 )
-
2、执行如下命令( 路径记得复制成自己的 ),另外记得用管理员权限打开命令行窗口
-
进行设置 C:\WINDOWS\system32>npm config set prefix "D:\install\Nodejs\node_global" C:\WINDOWS\system32>npm config set cache "D:\install\Nodejs\node_cache" 检查是否成功 C:\WINDOWS\system32>npm config get prefix D:\install\Nodejs\node_global C:\WINDOWS\system32>npm config get cache D:\install\Nodejs\node_cache
-
可见成功修改,但是:还需要做最后一步,去改环境变量( 使用msi安装是默认配好了的,但现在我们改动了配置,需要去重新弄一下 )
-
-
3、修改环境变量( 后端人员再熟悉不过,如果前端人员不明白的,直接计算机右键,选择属性,选择高级系统设置,选择环境变量就可以了【家庭版和专业版、win10和win7不一样,自行查找】 )
- 最后一路点OK即可,测试是否成功,可以选择安装一个vue包来测试
- 此时可能出现报一堆的ERROR,最后一行的大概意思就是让使用 root/ admin...用户( 也就是让用管理员运行dos窗口,再执行命令 )
报一堆ERROR错误的解决办法:本质是你安装时弄错了,文件权限不够 / 另外一种也是最常见的一种,就是明明都是正规步骤,但是就是不行,这是因为你自己本身登录的电脑用户权限不够【 自己买电脑之后,创建登录用户时操作有问题 】
-
想解决,此时:做一个操作即可,回到nodejs安装的根目录
-
右键选择属性、安全、高级
-
当然:要是自己的电脑在这个安全界面中,直接编辑权限,然后把“写入权限”√上是可以的,那就直接√上【 我说的是勾上时,不报错、直接出现一个加载过程 / 无任何报错提示的那种 ,若选择勾上、确认时系统有一个什么鬼提示来着,忘球了,反正有个提示就是不允许操作 】,要是不行就接着往后看
-
- 没有用户,点击添加之后,选择主体、在检索名称前面的框中:输入你当前登录用户名、检索即可有结果、最后确认是自己就可以了,这种情会直接看到权限选择,直接选完全控制 / 除这个以外的全勾上即可
-
确认之后,再使用npm install -g xxx就发现可以了
-
安装之后,在刚刚新建的node_global和node_cache中是有东西的
-
如果想要把全局配置恢复为初始化配置的话,也很简单,系统C盘用户目录/.npmrc的文件,删了就可以了
-
-
-
- 配置成功了nodejs之后,就可以使用npm指令了
- 但是:npm是国外的,我们拉取东西时就犹如隔了一道墙,很慢,因此:拉取淘宝的镜像,从而使用cnpm来代替npm指令,拉取淘宝镜像链接:
npm install -g cnpm --registry=https://registry.npm.taobao.org
或npm config set registry http://registry.npm.taobao.org
这两个都可以,如果因为自己电脑原因出现卡顿,进度条走得很慢、或不走了,那直接敲一下回车就可以了( 但:不是绝对好使,可能在你那边就不得吃 )
- 1、全局安装@vue/cli,指令:npm install -g @vue/cli
- npm 是nodejs的指令 拉取了淘宝镜像之后,就可以使用cnpm代替了
- install 就是安装的意思
- -g 是全局安装
- @vue/cli 是安装的东西
- 有个注意点:要是有人知道可以使用npm install -g vue-cli这样安装脚手架的话,可以用,没错的,但是:目前别这么安装( 它安装的脚手架是旧版本的,用这种方式安装的不能保证vue( 目前版本是1 — 3 )和vue-cli( 目前版本是1 — 4 )的版本很适合,所以后续使用一些命令时可能会出现版本不足的问题,让把版本升级,而使用@vue/cli安装的是最新版本
- 对于后端人员来说,这些指令太简单了,所以后续不说明了,下图是我重新安装了一次的结果
- 2、创建一个文件夹,并进入目录中,使用指令:vue create xxxx
2.3.2.2、分析cli构建的项目
- 使用vscode打开刚刚编译的项目【 ps:有些人是个人才,打开还整半天,1文件夹右键有一个open with code / 使用code打开,图标就是vscode的,没有的话,是安装vscode时,有一个界面是open with xxxx 的两个选择框没选,卸载、重装把那两个√打上就可以了 】
1、packpage-lock.json
2、package.json
- 以上就是基础的东西,接下来就对照前面手写的单文件组件思路来分析接下来的东西,那时说过:main.js是入口,所以cli脚手架程序就从main.js入手( 在cli中为什么它是入口?脚手架底层做的处理 )
- 1、main.js
- 2、引入了App.vue组件,那就接着分析App.vue组件
- 3、上面引入了helloword组件,而那里面就是一堆正常的组件写法
- 4、分析的差不多了,但是:还少了一个重要的东西,容器在哪里?
- 经过前面的分析之后,再结合上次写的单文件组件,就知道对应的东西写在哪里了
- 顺便说一下:vscode中启动vue程序,按ctrl + 飘字符( esc下面、tab上面的那个按键 )唤出控制台,后面的就知道怎么做了 做了修改之后,按ctril+s保存时会自动重新编译 )
2.3.2.3、认识render()函数
- 把前面编译好的例子改一下( 我的是把前面疏通流程的代码拷贝进来的 )
- 原因就是:代码中的一句话
- 那就去看一下vue到底有哪些版本?按住ctrl+鼠标点引入的vue哪里,点vue就进去了
-
点开它的包说明:就发现引入的是dist/vue.runtime.esm.js
-
随便选择一个右键在资源管理器中显示,就可以看到文件大小( 可以和vue.js对比,就少了100kb左右而已,少的就是模板解析器,但是:少的这部分用处很大 )
-
vue为什么要搞出这么多版本?
- 这是因为vue其实就是将webpack进行了封装,然后添加了一些技术,从而搞出来的,所以webpack在进行打包时会将.vue转成.js从而实现渲染( 后端人员不懂webpack的,就粗暴的把它当做是maven中的install打包,当然:compile编译等等这些指令功能也在vue中有相同的效果的实现机制 )
- 而程序编写完了之后,webpack本身就支持将.vue转成.js,那使用webpack打包时,模板解析器就不应该出现了( 模板解析器就是编写时解析而已 ),所以真实打包时如果还要有模板解析器就出现一个骚气的事情,举个例子:去做某事
- 回到前面报的错,怎么解决?控制台已经把答案给的很明确了
- 1、使用包含模板解析器的vue就可以了
- 2、使用render()函数实现模板解析器的效果
- 2、使用render()函数来实现解析template的功能
2.3.2.4、关闭语法检测
- 官网中有,改cli的全局配置也是一样的套路
- 官网里面就是说新建一个vue.config.js的文件,这个文件必须和package.json是同级目录,然后要配置东西时,找对应的配置项,然后复制粘贴对应的内容( 或改动一点自己要的配置项即可 )
- 经过上面的操作之后,就算定义一个变量,然后后面一直没用这个变量也不会导致项目启动不了了,否则:使用npm run serve时,就会报错,导致启动不了
- 而创建这个vue.config.js文件能够修改cli的配置是因为:cli是在webpack的基础上做出来的,而webpack是在nodejs的基础上整出来的,因此:程序最后是将自己写的vue.config.js去和webpack中的进行了合并,从而就成功了
- 另外:注意点
2.3.3、认识ref属性
- 这个属性是用来给“元素”或“子组件“注册引用信息( 也就是id属性的替代者 ),这个小东西很重要,关系到后续组件与组件之间的通信
我重新复制了一份src文件夹,用的时候把名字改回来就可以了( 需要哪一个就把哪一个改为src,然后执行npm run serve
就行了 )
运行效果如下:
现在有一个需求:获取下图中的DOM结构
- 使用传统js来操作的话,就是
document.getElementById
进行获取,但是:Vue中提供得有ref属性来进行操作:ref属性用来给“元素”或“子组件“注册引用信息( 也就是id属性的替代者 ),所以来见识第一个“元素”注册引用信息( 在HTML元素中这个ref属性就和id属性是一样的效果 ) - 第二种:ref属性是在子组件上的
- 这种很重要,后面组件与组件之间交互的基础
- 但是:这种和id就不同了,id是直接获得了子组件的DOM结构,而ref是获得了组件本身VueComponent
ref属性小结
- 被用来给元素( id的替代者 )或子组件注册引用信息
- 应用在HTML标签上获取的是真实DOM元素,应用在组件标签上获取的是组件实例对象( vc )
- 使用方式:
- 做标识:
或......
- 获取:this.$refs.xxx
- 做标识:
2.3.4、props配置-获取外传数据
- 组件中的props配置就是为了获取从外部传到组件中的数据
- 这个东西很有用,后续玩子传父、父传子就需要这个东西,而且开发中这个东西会经常看到
2.3.4.1、只接收数据
Person.vue组件编写内容
{{name}}
{{sex}}
{{age}}
{{job}}
{{address}}
App.vue组件编写内容
欢迎来到对抗路,对手信息如下
ctrl+s重新编译
效果如下
2.3.4.2、接收数据 + 数据类型限定
- 至于限定类型有哪些? 可以是下列原生构造函数中的一种
String
、Number
、Boolean
、Array
、Object
、Date
、Function
、Symbol
、任何自定义构造函数、或上述内容组成的数组
2.3.4.3、接收数据+限定类型+数据有无接收的必要+数据默认值
- 这个东西,玩java的人看起来很熟悉,和ElasticSearch中的mapping映射很像
2.3.4.4、处理外部传入数据类型问题
- 问题就轻轻松松解决了
2.3.4.5、解决props接收数据之后,修改它的值
- props配置中不是什么属性名的值都可以接收的,如:key、ref
- 意思就是:key不能作为props接收的数据,原因就是因为:key这个属性被Vue给征用了,Vue底层需要使用diff算法嘛,它用了这个key关键字,所以我们不可以用它
回到正题,props接收了数据怎么修改它?
- 首先要知道,props被底层监视了的,所以它的东西只可以接收,不可以修改,想要接收了数据,再修改它,我们就需要借助data,中转一下
2.3.4.6、props配置总结
-
功能:让组件接收外部传进来的数据
-
(1)、传递数据
-
(2)、接收数据
-
1)、只接收
- props: ['name']
-
2)、接收数据 + 数据类型限定
-
props: { name:String }
-
-
3)、接收数据 + 数据类型限定 + 必要性限制 + 数据默认值
-
props: { type:String, required:true, default:'紫邪情' 注:一个数据字段不会同时出现required和defautle }
-
-
-
注意:props中的数据是只读的,Vue底层会监测对props的修改,如果进行了修改,就会发出警告
- 如果业务需要修改,则:把props中的数据复制一份到data中,然后去修改data中的数据就可以了
- 须知:vue中优先使用props中的数据,然后再使用data中的数据( 可以使用data中的名字和props中的名字一样,然后去渲染,发现渲染出来的数据是props中的 )
2.3.5、mixin混入 / 混合
- 这个东西就是把多个组件中共同的配置给抽取出来,然后单独弄成一个js文件,使用一个对象把相同配置给封装起来,然后在需要的组件中引入、使用mixins配置进行使用即可
- 这种思想后端的人再熟悉不过了,工具类的编写不就是这么回事吗
2.3.5.1、使用
基础代码
在上面的代码中,methods中的代码是相同的,因此:使用mixin混入来进行简化,也是三板斧而已
但是:mixin混入有一些注意点
- 1、除了生命周期,如果其他配置是在mixin中定义了,同时在组件中也定义了,那么:优先使用的是组件中自己定义的( 无论二者相同与否都一样 )
- 2、如果在mixin中定义了生命周期钩子函数,那么:优先使用mixin中的钩子函数
另外:mixin混入是支持全局配置的,不过这种操作不当会出现问题,因此:目前不建议用,需要时再玩吧,思路如下:
- 1、一样的创建js文件
- 2、在App.vue中引入
- 3、在App.vue中使用vue.mixin( 暴露对象1 ) 、vue.mixin( 暴露对象2 ).......
- 使用了这三板斧之后,就可以实现全局配置了
2.3.5.2、mixin混入总结
-
功能:把多个组件共同的配置提取成一个混入对象
-
使用方法:
-
1、定义混入,如:
-
暴露方式 const 对象名 { data(){......}, methods:{........}, ........ }
-
-
2、在需要的组件中引入混入
-
3、使用混入,如:
- 1)、局部混入:mixins: [ xxxxxx , ......... ] , 注意:这里必须用数组
- 2)、全局混入:Vue.mixin( xxxxx )
-
2.3.6、插件
- 这个东西的作用很大,它可以合理的增强Vue
使用,也简单,还是三板斧
- 1、创建js文件( 包含install()方法的一个对象 )
- 2、引入插件
- 3、使用插件
2.3.6.1、玩一下插件
基础代码效果
1、创建一个包含install()方法的对象的js文件
2、在main.js中引入、使用插件
3、效果如下
- 可以得知:创建的插件中传递的那个参数Vue就是vm( Vue实例对象 )的缔造者 —— vue构造函数
- 得到上面哪那个结果就很重要了,试想:我们使用这个构造函数做过什么事?
- 自定义全局指令 Vue.directive
- 定义全局过滤器 Vue.filter
- 定义全局混入 Vue.mixin
- ........
- 把这些东西放到创建插件的install()中可行?它接受的参数就是Vue嘛
正宗玩法
当然:我们也可以给插件中传东西进去
2.3.6.2、插件总结
-
功能:用于增强Vue
-
本质:是包含install()方法的一个对象的js文件,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据
-
插件的玩法:
-
1、定义插件:
-
// 1、创建插件 export default 是自己选择的暴露方式 export default { install(Vue,[ other params ]){ // 定义全局过滤器 Vue.filter( ..... ), Vue.directive( ...... ), Vue.mixin( ....... ) ......... } }
-
-
2、在main.js中引入插件
-
3、在main.js中向Vue应用插件 Vue.use( 插件名 )
-
[ 4、使用插件中定义的东西 ] ———— 可有可没有,看自己的代码情况
-
这里注意一个东西:定义插件中的install()第一个参数是Vue,即:vm的缔造者,Vue构造函数( 这里可以联想原型对象,也就是前面说的vm和vc的内置关系:
VueComponent.prototype._ _proto _ _ === Vue.prototype
,这也就是说在Vue身上加点东西,那么:vm和vc都可以拿到,如:-
Vue.prototype.$myMethod = function(){ ...... } Vue.prototype.$myProperty = xxxx prototype路线是加东西 _ _proto_ _路线是取东西
-
-
2.3.7、scoped局部样式
- 作用:让样式在局部生效,防止冲突
- 写法:
假如有两个组件,里面都用了同一个class类名,但是做的style却是不一样的
此时如果把两个class名字改成一样呢?开发中样式多了这种事情是在所难免的
凭什么就是Person2.vue组件中的样式优先?
那上述样式冲突了怎么解决?
当然:style标签不止支持scoped属性,还可以用其他的
-
另外:less需要less-loader支持,所以需要安装less-loader,但是:有坑( 版本的问题 )
-
cli中的webpack版本
-
安装适合cli的webpack的less-loader版本
最后还有一个问题:scoped使用在App.vue中就会发生很诡异的事情
- App.vue是大哥,所以这里面的style会全局生效( 也就是多组件都在使用的样式,就可以提到App.vue中写,然后在其他需要的组件中使用即可 )
- 但是:如果App.vue中style使用了scoped,那么就会导致:样式只在App.vue中有效,那么:其他组件中想要用,那对不起,管不了,最后页面就会出现诡异的事情 —— 不是自己写的样式的样子
- 所以:App.vue中最好别用scoped属性,而其他组件中最好都加上scoped属性
2.3.8、组件化应用应该怎么去写?
实例:实现如下的效果( 就是一个人名录入,然后可以对名字做一点操作罢了 )
- 组件编写流程( 基本上都是一样的套路 ),接下来按照套路去弄就可以了
2.3.8.1、分析结构 / 拆分组件
根据页面结构来看,可以拆分成如下的结构:
- 1、外面大的框就是一个组件 —— 也就是App.vue父组件,而App组件中又包含的如下组件:
- 1.1、输入框是一个组件( 子 )
- 1.2、人名的展示框是一个组件( 子 ,却是下面两个的“父” )
- 1.2.1、然后发现展示框里面又有每一个人名组件( 子 )
- 1.2.2、还有一个全选 / 显示已选人数的组件( 子 )
2.3.8.2、创建对应组件并编写内容
1、创建并编写组件对应内容( 统称编写静态组件 )
-
1)、App组件
-
(1)、HTML结构
-
-
(2)、CSS样式 + 后续需要的通用样式
-
body{ background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px rgba(255,255,255,0.2),0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .name-container { width: 600px; margin: 0 auto; } .name-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
-
-
-
2)、输入框组件
-
(1)、HTML结构
-
-
-
3)、人名展示框
-
(1)、HTML结构
-
-
(2)、CSS样式
-
/* #region list */ .name-main { margin-left: 0px; border: 1px solid s#ddd; border-radius: 2px; padding: 0px; } .name-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } /* #endregion */
-
-
-
4、每个人名展示
-
(1)、HTML结构
-
-
(2)、CSS样式
-
/* #region item */ li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: 1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } /* #endregion */
-
-
运行效果如下:
- 自此:静态组件编程就搞定,后续就可以做数据的动态绑定和交互这些了
- 将纯HTML + CSS + JS转成组件化开发也是一样的套路,流程如下:
- 1、把整个HTML结构放到App.vue组件的template模板中
- 2、把所有的CSS放到App.vue组件的style中
- 3、有JS的话,那么把js文件创好,然后引入到App.vue组件中
- 4、开始去分析结构,然后拆分成组件,之后把对应的内容放到对应组件中,最后做后续的动态数据绑定、交互即可
2.3.8.3、动态数据绑定
按照分析,要展示的数据是一堆数据,而数据显示的地方是NameList,所以:data数据就放到NameList中去。本实例中数据放到这里有坑啊,但是:先这么放,后续遇到坑了再调整,所以改一下源码
- 数据是弄好了,但是:真正展示数据的是NameObj组件来显示出来的,而NameObj是NamelList的子组件( 这就是:父传子 ),这种就需要借助props配置项( 从外向内传嘛 ),所以:开始操作
1、父传子
2、获取输入的内容并添加到显示的顶部 —— 和后续知识挂钩的重点来了
3、原生的不同组件通讯
- App.vue是大哥,用它做文章,这样就变成了App这个父组件和输入框以及Namelist这两个子组件之间的关系了
- 第二步:将输入框组件中的数据收集起来,并传给父组件( 这就是子传父 )
4、将子组件传递的数据添加到数据栏的顶部去
2.3.8.4、交互编写
1、实现选择和数据的改变
- 1)、最简单粗暴的方式 —— 但是:不建议用
- 2)、按照逻辑老实编写
2、实现每条数据的删除功能
3、实现底部的已选择人数和总计人数功能
3.1、最原生的方式
3.2、使用数组的reduce()这个API,这个API专做数据统计的
接下来就只剩下底部的全选和清除已选这两个功能了
4、实现全选交互和清除已选人员功能
4.1、实现全选交互( 子传父 + 计算属性使用技巧 )
4.2、清除已选人员
2.3.8.5、组件化开发流程总结
组件化编写流程
- 1、拆分静态组件:组件要按照功能点拆分,命名不要和HTML元素名冲突
- 2、实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用
- 一个组件在用:把数据放到组件自身即可
- 一些组件在用:把数据放到它们共同的父组件上【 这也叫状态提升 】
- 3、实现交互:从绑定事件开始
props配置总结
- 适用于以下过程
- 1、父组件 ——> 子组件 通信
- 2、子组件 ——> 父组件 通信
v-model总结
- 使用v-model时要切记:v-model绑定的是值,但是:这个值不能是props中传递过来的值,因为:props底层被Vue监测了的,不允许修改
- 注:props中传过来的若是对象类型的值时,虽然修改"对象中的属性"时Vue不会报错,但是:不建议用
2.3.9、下一篇链接
- https://www.cnblogs.com/xiegongzi/p/15875808.html