Vue-cli是Vue.js开发的标准工具,简化了程序员基于webpack创建工程Vue项目的过程。下面这篇文章主要介绍Vue命令行工具Vue-CLI的相关信息,有需要的可以参考一下。
目录
描述了vue-CLI vue CLI的安装,Vue的全家桶默认安装vue/cli脚手架 默认安装失败, 解决模式版本问题解决NVM下载慢的问题安装节点^12.0.0重装VueCli scaffold 3拉2.x模板(旧版本)安装vue指定版本 Blogger节点版本初始化项目 Vue init命令解释项目初始化目录结构详解运行项目节点安装适合小白1去节点官网下载2下载后双击安装包跳出安装弹出。 点击下一步从新的vue-cli安装vue-cli项目初始化项目结构1、build目录(webpack配置)2、config目录(vue项目配置目录)3、Node_modules(项目依赖包)src项目核心文件讲解网页CDN介绍vue@2.6.14示例内部指令生命周期常用选项示例事件自定义指令组件基本制造模板页面跳转1、router-link Tab跳转2、程序化导航-JS代码内部跳转3、其他常用方法汇总
阐述
vue-cli建项目的时候发现官方文档还是不够,需要熟练掌握es6,而vue的全家桶还是要用。
e CLI的包名已从vue-cli更改为@vue/cli。如果您已经全局安装了旧版本的vue-cli(1.x或2.x ),则需要先通过npm uninstall vue-cli -g或yarn global remove vue-cli将其卸载。
对已安装的脚手架节点的新版本也有版本要求。Vue CLI 4.x需要Node.jsv8.9或更高版本(建议使用v10或更高版本)。
vue全家桶
vue的全家桶是基于vue开发的必备和必学的东西,可以总结如下:
1.vue-cli项目构建工具
2 . vue-路由器路由管理
3.vuex状态管理全局变量
4.axios,http请求工具。
5.UI框架元素,iview,vant
简单介绍一下最常用的vue家族桶,希望能帮助你了解和学习vue家族桶!
vue-cli
Vue-cli是一个快速构建Vue项目的搭建工具。
VueCLI是vue.js的官方项目脚手架,可以用来快速搭建vue开发环境和相应的webpack配置。
1.CLI是命令行界面,翻译为命令行界面,但通常被称为脚手架。
2.Vue CLI是vue.js的官方项目脚手架
3.vue-cli可用于快速构建vue开发环境和相应的webpack配置。
关于旧版本
e CLI的包名已从vue-cli更改为@vue/cli。如果您已经全局安装了旧版本的vue-cli (1.x或2.x ),则需要先通过npm uninstall vue-cli -g或yarn global remove vue-cli将其卸载。
搭建依赖于node.js和webpack。
Vue CLI需要Node.js版本8.9或更高版本(建议使用8.11.0)。您可以使用nvm或nvm-windows在同一台计算机上管理多个版本的Node。
Vue CLI 的安装
vucli2初始化项目:vue init webpack my-project
vucli3初始化项目:vue创建我的项目
注意:默认情况下会安装以下版本的Vue CLI3。如果想用Vue CLI2的方式初始化项目,是不行的。
因为博主版本太低,所以出现了切换节点版本,反复安装的操作。第二步是检查Vue Cli要求的节点版本。请总是绕过重复的安装过程。
默认安装 vue/cli 脚手架 3
PS C:\ Windows \ system32 NPM install-g @ vue/CLI
npm警告不赞成使用的订阅-transport-ws@0.9.19:不再维护“订阅-transport-ws”包。我们建议您改用“graphql-ws”。有关将Apollo软件迁移到“graphql-ws”的帮助,请参阅https://www . apollographql . com/docs/Apollo-server/data/subscriptions/# switching-from-subscriptions-transport-ws有关使用“graphql-ws”的一般帮助,请参阅https://github.com/enisdenjo/graphql-ws/blob/master/README.md
npm警告已弃用graphql-tools@4.0.8:此包已弃用,现在它只导出makeExecutableSchema .\ n它将不再接收更新% 22 \ n我们建议您迁移到作用域包,如@graphql-tools/schema 、@graphql-tools/utils等% 22 \ n查看https://www.graphql-tools.com,了解应该使用什么软件包
npm警告不推荐使用阿波罗缓存控制@0.14.0:从阿波罗服务器3开始,“阿波罗-缓存-控制”软件包提供的功能内置于“阿波罗-服务器-核心”中。详见https://www。apollographql。服务器/迁移/#缓存控制.
npm警告不推荐使用阿波罗-追踪@ 0。15 .0:“阿波罗-追踪”包不再是阿波罗服务器3的一部分。详情请见https://www。apollographql。com/docs/Apollo-server/migration/#跟踪
npm警告不推荐使用graph QL-扩展@0.15.0:已经从阿波罗服务器3中删除了“图形QL-扩展”API .请改用插件API:https://www。apollographql。com/docs/Apollo-server/集成/插件/
npm警告已弃用uuid@3.4.0:请升级到版本七或更高版本。旧版本在某些情况下可能会使用Math.random(),这是一个已知的问题。详情见https://v8.dev/blog/math-random。
npm警告不推荐使用的来源-地图-解析@0.5.3:请参见https://github.com/lydell/source-map-resolve#deprecated
npm警告已弃用的解析-URL @ 0。2 .1:https://github . com/ly Dell/resolve-URL #已弃用
npm警告已弃用的urix@0.1.0:请参见https://github.com/lydell/urix#deprecated
npm警告不推荐使用的源映射url@0.4.1:请参见https://github.com/lydell/source-map-url#deprecated
C:\ Program Files \ nodejs \ vue-C:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ bin \ vue。射流研究…
core-js-pure@3.22.0安装后c:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ node _ modules \ core-js-pure
node -e 'try{require(./postinstall')}catch(e){} '
感谢您使用core-js(https://github . com/zloirock/core-js)来填充Java Script语言标准库!
这个项目需要你的帮助!请考虑支持核心-js:
https://opencollective.com/core-js
https://patreon.com/zloirock
比特币:BC 1 qlea 7544 qts mj 2 rayg 01 thv za 9 fau 63 UX 0 fstcz
还有核心-js的作者(https://github.com/zloirock)找好工作-)
@apollo/protobufjs@1.2.2安装后c:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ node _ modules \ @ Apollo \ protobufjs
节点脚本/安装后
npm警告节点-获取@2.6.7需要一个encoding@^0.1.0对等项,但没有安装。您必须自己安装对等依赖项。
npm警告ws@7.5.7需要一个bufferutil@^4.0.1对等项,但没有安装。您必须自己安装对等依赖项。
npm警告ws@7.5.7需要一个utf-8-validate@^5.0.2对等项,但没有安装。您必须自己安装对等依赖项。
@vue/cli@5.0.4
在130.475秒内增加了来自531个贡献者的880个包
结束
默认安装失败,解决mode版本问题
安装之后,你就可以在命令行中访问某视频剪辑软件命令。
检查其版本是否正确:
PS C:\ Windows \ system32 vue-version
您使用的是节点v11.15.0,但此版本的@vue/cli要求节点^12.0.0 ||=14.0.0。
请升级您的节点版本。
您使用的是节点v11.15.0,但是这个版本的@vue/cli需要节点^12.0.0 ||=14.0.0 .
请升级您的节点版本。
PS C:\Windows\system32
nvm下载太慢问题解决
由于nvm默认的下载地址http://nodejs.org/dist/是外国外服务器,国内很慢可以使用淘宝的镜像。
nvm在哪里找到nvm安装路径
找到设置。文本文件(textfile)文件
将下面这两句话复制到settings.txt,并保存
节点_镜像:https://NPM . Taobao . org/mirrors/node/
https://npm.taobao.org/mirrors/npm/
安装 Node ^12.0.0
PS C:\Windows\system32 nvm安装12.0.0
正在下载节点. js版本12.0.0 (64位).
完成
正在创建c:\ Users \ ASUS \ AppData \ Roaming \ nvm \ temp
正在下载npm版本6.9.0.完成
安装npm版本6.9.0.
安装完成。如果您想使用这个版本,请键入
nvm使用12.0.0
PS C:\Windows\system32 nvm使用12.0.0
现在使用节点v12.0.0 (64位)
PS C:\Windows\system32 nvm列表
14.17.6
* 12.0.0(目前使用64位可执行文件)
11.15.0 此版本主项目
PS C:\Windows\system32
从新安装 VueCli 脚手架 3
PS C:\ Windows \ system32 NPM安装-g @ vue/CLI
npm警告不赞成使用的订阅-transport-ws@0.9.19:不再维护"订阅-运输-ws "包。我们建议您改用graphql-ws .有关将阿波罗软件迁移到" graphql-ws "的帮助,请参阅https://www。apollographql。com/docs/Apollo-server/data/subscriptions/# switching-from-subscriptions-transport-ws有关使用" graphql-ws "的一般帮助,请参阅https://github.com/enisdenjo/graphql-ws/blob/master/README.md
npm警告已弃用graphql-tools@4.0.8:此包已弃用,现在它只导出makeExecutableSchema .\ n它将不再接收更新% 22 \ n我们建议您迁移到作用域包,如@graphql-tools/schema 、@graphql-tools/utils等% 22 \ n查看https://www.graphql-tools.com,了解应该使用什么软件包
npm警告不推荐使用阿波罗缓存控制@0.14.0:从阿波罗服务器3开始,“阿波罗-缓存-控制”软件包提供的功能内置于“阿波罗-服务器-核心”中。详见https://www。apollographql。服务器/迁移/#缓存控制.
npm警告不推荐使用阿波罗-追踪@ 0。15 .0:“阿波罗-追踪”包不再是阿波罗服务器3的一部分。详情请见https://www。apollographql。com/docs/Apollo-server/migration/#跟踪
npm警告不推荐使用graph QL-扩展@0.15.0:已经从阿波罗服务器3中删除了“图形QL-扩展”API .请改用插件API:https://www。apollographql。com/docs/Apollo-server/集成/插件/
npm警告已弃用uuid@3.4.0:请升级到版本七或更高版本。旧版本在某些情况下可能会使用Math.random(),这是一个已知的问题。详情见https://v8.dev/blog/math-random。
npm警告不推荐使用的来源-地图-解析@0.5.3:请参见https://github.com/lydell/source-map-resolve#deprecated
npm警告不推荐使用的源映射url@0.4.1:请参见https://github.com/lydell/source-map-url#deprecated
npm警告已弃用的解析-URL @ 0。2 .1:https://github . com/ly Dell/resolve-URL #已弃用
npm警告已弃用的urix@0.1.0:请参见https://github.com/lydell/urix#deprecated
C:\ Program Files \ nodejs \ vue-C:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ bin \ vue。射流研究…
core-js-pure@3.22.0安装后c:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ node _ modules \ core-js-pure
node -e 'try{require(./postinstall')}catch(e){} '
感谢您使用core-js(https://github . com/zloirock/core-js)来填充Java Script语言标准库!
这个项目需要你的帮助!请考虑支持核心-js:
https://opencollective.com/core-js
https://patreon.com/zloirock
比特币:BC 1 qlea 7544 qts mj 2 rayg 01 thv za 9 fau 63 UX 0 fstcz
还有核心-js的作者(https://github.com/zloirock)找好工作-)
@apollo/protobufjs@1.2.2安装后c:\ Program Files \ nodejs \ node _ modules \ @ vue \ CLI \ node _ modules \ @ Apollo \ protobufjs
节点脚本/安装后
npm警告节点-获取@2.6.7需要一个encoding@^0.1.0对等项,但没有安装。您必须自己安装对等依赖项。
npm警告ws@7.5.7需要一个bufferutil@^4.0.1对等项,但没有安装。您必须自己安装对等依赖项。
npm警告ws@7.5.7需要一个utf-8-validate@^5.0.2对等项,但没有安装。您必须自己安装对等依赖项。
@vue/cli@5.0.4
在81.975秒内增加了来自531个贡献者的880个包
安装结束
查看某视频剪辑软件版本,及验证是否安装正确。
PS C:\ Windows \ system32 vue-version
@vue/cli 5.0.4
PS C:\Windows\system32
拉取 2.x 模板 (旧版本)
Vue CLI=3和旧版使用了相同的某视频剪辑软件命令,所以Vue CLI 2 (vue-cli)被覆盖了。
如果你仍然需要使用旧版本的某视频剪辑软件初始化功能,你可以全局安装一个桥接工具:
PS C:\ Windows \ system32 NPM安装-g @ vue/CLI-init
npm警告已弃用的vue-cli@2.9.6:此程序包已弃用,而代之以@vue/cli
npm警告已弃用的请求@2.88.2:请求已弃用,请参见https://github.com/request/request/issues/3142
npm警告弃用的咖啡-脚本@ 1。12 .7:NPM上的咖啡脚本已移动到“咖啡脚本”(无连字符)
npm警告不推荐使用的har验证器@5.1.5:不再支持此库
npm警告已弃用uuid@3.4.0:请升级到版本七或更高版本。旧版本在某些情况下可能会使用Math.random(),这是一个已知的问题。详情见https://v8.dev/blog/math-random。
@vue/cli-init@5.0.4
在38.328秒内增加了来自231个贡献者的259个包
PS C:\Windows\system32
某视频剪辑软件初始化的运行效果将会跟vue-cli@2.x相同。
创建项目提示,原因上面安装已经提示命令都为弃用状态。
PS E:\ node vue init web pack vue-CLI 2-test
vue初始化命令需要安装一个全局插件。
请运行未定义的@vue/cli-init并重试。
命令某视频剪辑软件初始化需要安装全局插件。
请运行未定义的@vue/cli-init并重试。
PS E:\node
安装vue指定版本
【前端开发】Vue-CLI4 Vue-CLI3与Vue-CLI2的区别
1、安装:
Vue-CLI2:
npm安装-g vue-cli或cnpm安装-g vue-cli
Vue-CLI最新版本:
npm安装-g @vue/cli或cnpm安装-g @vue/cli
2、卸载
Vue-CLI2:
npm卸载-g vue-cli或cnpm卸载-g vue-cli
Vue-CLI最新版本:
npm卸载-g @vue/cli或cnpm卸载-g @vue/cli
指定版本安装
可以安装:2.6.0 版本
npm install -g vue-cli@2.6
可以安装:2.6.0 版本
cnpm install -g vue-cli@v2.6.*
卸载某视频剪辑软件
cnpm卸载-g vue-cli
内容交付网络链接
titleVue测试实例-菜鸟教程(运行OOB。com)/标题
script src=' https://UNP kg。com/vue @ 2。6 .14/区/区。量滴js '/脚本
https://unpkg.com/browse/vue@2.6.14/dist/
选择某视频剪辑软件版本
https://unpkg.com/browse/vue@2.6.14/dist/vue.min.js
博主node版本
改某视频剪辑软件版本
PS C:\WINDOWS\system32 npm安装vue-cli -g
npm警告已弃用的vue-cli@2.9.6:此程序包已弃用,而代之以@vue/cli
npm警告已弃用的请求@2.88.2:请求已弃用,请参见https://github.com/request/request/issues/3142
npm警告弃用的咖啡-脚本@ 1。12 .7:NPM上的咖啡脚本已移动到“咖啡脚本”(无连字符)
npm警告不推荐使用的har验证器@5.1.5:不再支持此库
npm警告已弃用uuid@3.4.0:请升级到版本七或更高版本。旧版本在某些情况下可能会使用Math.random(),这是一个已知的问题。详情见https://v8.dev/blog/math-random。
C:\ Program Files \ nodejs \ vue-init-C:\ Program Files \ nodejs \ node _ modules \ vue-CLI \ bin \ vue-init
C:\ Program Files \ nodejs \ vue-list-C:\ Program Files \ nodejs \ node _ modules \ vue-CLI \ bin \ vue-list
C:\ Program Files \ nodejs \ vue-C:\ Program Files \ nodejs \ node _ modules \ vue-CLI \ bin \ vue
vue-cli@2.9.6
增加了来自229个贡献者的244个包,并在22.77秒内更新了一个包
PS C:\WINDOWS\system32 vue -V
2.9.6
PS C:\WINDOWS\system32
如何查看某视频剪辑软件项目某视频剪辑软件的版本号:
如果是用vue-cli创建的项目,则找到项目根目录下的' package.json '文件。
初始化项目
vue init命令讲解
用某视频剪辑软件初始化命令来初始化项目,具体使用方法如下:
某视频剪辑软件初始化模板名称项目名称
初始化:表示要用vue-cli来初始化项目
模板名称:表示模板名称,vue-cli官方提供的5种模板:
1、网络包:
一个全面的webpack vue加载器的模板,功能包括热加载、林挺、检测和半铸钢钢性铸铁(铸造半钢)扩展。
2、网络包——简单:
一个简单webpack vue加载器的模板,不包含其他功能,让你快速的搭建某视频剪辑软件的开发环境。
3、浏览确认:
一个全面的Browserify vueify的模板,功能包括热加载、林挺、单元检测。
4、浏览简单:
一个简单Browserify vueify的模板,不包含其他功能,让你快速的搭建某视频剪辑软件的开发环境。
5、简单:
一个最简单的单页应用模板。
项目名称:标识项目名称,用户根据自己的项目来起名字。
项目初始化
在实际开发中,一般都会使用网络包这个模板,命令使用如下:
第一步操作:
PS E:\ node vue init web pack vue-CLI 296
?项目名称(vue-cli296)
项目名称:项目名称,默认为初始化建项目的名称vue-cli296,不需要直接回车
第二步操作:
项目描述(一个vue . j项目)
项目描述:项目描述,默认为vue . j项目,不需要直接回车
作者(cwgqmxy 1157818690@qq.com)
作者:作者,如果有配置饭桶的作者,自动会读取。直接回车
第三步操作:
两个选项,运行时编译器和仅限运行时:
运行时编译器:推荐大多数用户使用
(运行程序编译器:推荐给大多数用户)
仅限运行时:最小gzip减少了大约6KB,但是模板(或者任何某视频剪辑软件特定的HTML)只允许在100 . vue文件-其他地方需要渲染功能
(仅运行程序:比上面那种模式轻大约6KB最小gzip,但是模板(或任何特定于某视频剪辑软件的html)只允许在。某视频剪辑软件文件中使用——其他地方用需要提供;给予函数)
区别
1、仅运行时比运行时编译器轻6kb
2、仅运行时运行更快
3、仅运行时其实只能识别提供;给予函数,不能识别模板,某视频剪辑软件文件中的也是被模板编译器翻译成了提供;给予函数,所以只能在。某视频剪辑软件里写模板。
两种模式生成的脚手架即(代码模板)其实区别只有在主页。射流研究…中,其他都是一样的:
可以发现一个是用模板组件而另一个则是用提供;给予函数。
第四步操作:
安装某视频剪辑软件路由器?(是/否)
安装某视频剪辑软件路由器?
是否安装某视频剪辑软件的路由插件,需要安装,选择Y
第五步操作:
用埃斯林特皮棉你的代码?(是/否)
输入Y
选择一个埃斯林特预设:选择分支风格
选项有三个(博主选了第一个)
1 .标准版(https://github。com/feross/standard)js的标准风格
2.Airbnb(https://github。com/Airbnb/JavaScript)JavaScript最合理的方法,这个开源代码库地址说是Java脚本语言最合理的方法
3 .无(自己配置)自己配置
用埃斯林特棉绒你的代码?
是否用埃斯林特来限制你的代码错误和风格。不需要输入n,需要选择y,如果是大型团队开发,最好是进行配置。
第六步操作:
设置单元测试(是/否)
是否需要安装单元测试工具,不需要输入n,需要选择y
第七步操作:
用守夜人设置e2e测试?(是/否)
是否安装E2E测试框架守夜人(E2E,也就是端到端,就是所谓的"用户真实场景"。
第八步操作:
项目创建后,我们应该为您运行“国家预防机制安装"吗?(推荐)(使用箭头键)
(译:项目创建后是否要为你运行“国家预防机制安装"?这里选择包管理工具)
选项有三个
是,使用npm(使用npm)
是的,使用纱线(使用纱线)
不,我会自己处理自己配置安装包)
开始创建了项目,初始化完成之后会出现以下信息,表示操作成功。
PS E:\ node vue init web pack vue-CLI 296
?项目名称vue-cli296
?项目描述vue . j项目
?作者1157818690@qq.com
?某视频剪辑软件构建运行时
?安装某视频剪辑软件路由器?是
?用埃斯林特皮棉你的代码?是
?选择一个埃斯林特预设标准
?设置单元测试号
?用守夜人设置e2e测试?不
?项目创建后,我们应该为您运行“国家预防机制安装"吗?(推荐)国家预防机制
vue-cli生成了vue-cli296 .
#安装项目依赖项.
#========================
npm警告弃用的babel-eslint @ 8。2 .6:巴别塔-埃斯林现在是@babel/eslint-parser .此软件包将不再接收更新。
npm警告已弃用的eslint-loader@1.9.0:此加载程序已弃用。请使用eslint-web pack-插件
npm警告已弃用的提取-文本-网页包-插件@ 3。0 .2:已弃用。请用https://github.com/webpack-contrib/mini-css-extract-plugin
npm警告已弃用的html-webpack-plugin@2.30.1:不支持
npm警告不推荐使用的浏览器列表@ 2。11 .3:浏览器列表2在读取其他工具中使用的浏览器列表3.0配置时可能会失败。
npm警告不推荐使用丑陋-es@3.3.9:从3.13.0版开始,对ECMAScript的支持被"丑陋-js "取代
npm警告已弃用的bfj节点4@5.3.1:切换到" bfj "包以获得修复和新功能!
npm警告弃用的core-js@2.6.12: core-js@3.4已不再维护,由于存在大量问题,不建议使用。由于V8发动机的突发事件,旧核心-js版本中的功能检测可能会导致速度降低100倍,即使没有多填充。请将您的依赖项升级到核心-js的实际版本。
npm警告已弃用的乔基达尔@2.1.8:乔基达尔2自2019年起不再接收安全更新。升级到chokidar 3,依赖性减少15倍
NPM警告已弃用的fs事件@ 1。2 .13:fs事件1将在节点v14上中断,并且可能使用不安全的二进制文件。升级到f事件2 .
npm警告已弃用uuid@3.4.0:请升级到版本七或更高版本。旧版本在某些情况下可能会使用Math.random(),这是一个已知的问题。详情见https://v8.dev/blog/math-random。
npm警告不推荐使用扁平化@1.0.3:不推荐使用变平,支持洛达什等实用框架。
npm警告不推荐使用的浏览器列表@ 1。7 .7:浏览器列表2在读取其他工具中使用的浏览器列表3.0配置时可能会失败。
npm警告不推荐使用svgo@0.7.2:不再支持此svgo版本。升级到v2.x.x .
npm警告不推荐使用的循环-JSON @ 0。3 .3:循环JSON仅处于维护状态,展平是其继任者。
npm警告不推荐使用的查询字符串@ 0。2 .0:查询字符串API被认为是旧的。新代码应改为使用URLSearchParams API .
npm警告不推荐使用svgo@1.3.2:不再支持此svgo版本。升级到v2.x.x .
npm警告不推荐使用的来源-地图-解析@0.5.3:请参见https://github.com/lydell/source-map-resolve#deprecated
npm警告已弃用的解析-URL @ 0。2 .1:https://github . com/ly Dell/resolve-URL #已弃用
npm警告不推荐使用的源映射url@0.4.1:请参见https://github.com/lydell/source-map-url#deprecated
npm警告已弃用的urix@0.1.0:请参见https://github.com/lydell/urix#deprecated
core-js@2.6.12安装后e:\ node \ vue-CLI 296 \ node _ modules \ core-js
node -e 'try{require(./postinstall')}catch(e){} '
感谢您使用core-js(https://github . com/zloirock/core-js)来填充Java Script语言标准库!
这个项目需要你的帮助!请考虑在开放集体或订阅模式上支持核心-js:
https://opencollective.com/core-js
https://www.patreon.com/zloirock
还有核心-js的作者(https://github.com/zloirock)找好工作-)
ejs@2.7.4安装后E:\ node \ vue-CLI 296 \节点模块\ ejs
节点. postinstall.js
感谢您安装用杰克JavaScript构建工具(https://jakejs.com/)构建的EJS
es5-
ext@0.10.60 postinstall E:\node\vue-cli296\node_modules\es5-ext > node -e "try{require('./_postinstall')}catch(e){}" # # Fatal error in , line 0 # Check failed: U_SUCCESS(status). # # # #FailureMessage Object: 000000E8857BCE10[ ......] / postinstall: info lifecycle es5-ext@0.10.60~postinstall: npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\watchpack-chokidar2\node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\webpack-dev-server\node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm ERR! Maximum call stack size exceeded npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\Administrator\AppData\Roaming\npm-cache\_logs\2022-04-19T08_59_35_781Z-debug.log Running eslint --fix to comply with chosen preset rules... # ======================== > vue-cli296@1.0.0 lint E:\node\vue-cli296 > eslint --ext .js,.vue src "--fix" # Project initialization finished! # ======================== To get started: cd vue-cli296 npm run dev Documentation can be found at https://vuejs-templates.github.io/webpack PS E:\node>③ 目录结构详解
④ 运行项目
环境崩溃了,从新装node环境。
npm 是什么东东?
npm其实是Node.js的包管理工具(package manager)。
为啥我们需要一个包管理工具呢?
因为我们在Node.js上开发时,会用到很多别人写的JavaScript代码。
(http://caibaojian.com/npm/all.html)
讲了这么多,npm究竟在哪?
其实npm已经在Node.js安装的时候顺带装好了。我们在命令提示符或者终端输入npm -v,
node 安装适合小白
1 去node官网下载
中文官方网址:http://nodejs.cn/
下载网址:http://nodejs.cn/download/
官方网址:https://nodejs.org/en/
2 下载完成后双击安装包,跳出安装弹窗,点击Next
以下一路 Next
? ? ? ? ? ? ? ?node.js runtime:node 运行环境 ? ? ? ? ? ? ? ?orepack manager:npm 包管理 Online documentation shortcuts:在线文件快捷方式 ? ? ? ? ? ? ? ? ? ?Add to Path:添加路径 ? ? ? ? ? ? ? corepack manager:核心包管理
不用打钩,如果打了 √ 会把 node 所有的工具都下载,需要很久,以后要什么工具,直接npm下载。
安装好啦
环境路径已经自动设置好了
可以去 cmd 窗口中查看安装 node 和 npm 的版本号。
从新来过
上面环境崩溃了,从新搭建的环境。
PS E:\node> node -v v11.15.0 PS E:\node>vue-cli 安装
vue-cli是vue官方出品的快速构建单页应用的脚手架,里面集成了webpack,npm,nodejs,babel,vue,vue-router。
PS E:\node> npm install vue-cli -g npm WARN deprecated vue-cli@2.9.6: This package has been deprecated in favour of @vue/cli npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen) npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. C:\Program Files\nodejs\vue-init -> C:\Program Files\nodejs\node_modules\vue-cli\bin\vue-init C:\Program Files\nodejs\vue -> C:\Program Files\nodejs\node_modules\vue-cli\bin\vue C:\Program Files\nodejs\vue-list -> C:\Program Files\nodejs\node_modules\vue-cli\bin\vue-list + vue-cli@2.9.6 added 245 packages from 230 contributors in 27.375s PS E:\node> PS E:\node> vue --version 2.9.6 PS E:\node>vue-cli 项目初始化
PS E:\node> vue init webpack vue296 ? Project name vue296 ? Project description A Vue.js project ? Author cwgqmxy <1157818690@qq.com> ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? Yes ? Pick an ESLint preset Standard ? Set up unit tests No ? Setup e2e tests with Nightwatch? No ? Should we run `npm install` for you after the project has been created? (recommended) npm vue-cli · Generated "vue296". # Installing project dependencies ... # ======================== npm WARN deprecated babel-eslint@8.2.6: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. npm WARN deprecated eslint-loader@1.9.0: This loader has been deprecated. Please use eslint-webpack-plugin npm WARN deprecated extract-text-webpack-plugin@3.0.2: Deprecated. Please use https://github.com/webpack-contrib/mini-css-extract-plugin npm WARN deprecated html-webpack-plugin@2.30.1: out of support npm WARN deprecated browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools. npm WARN deprecated uglify-es@3.3.9: support for ECMAScript is superseded by `uglify-js` as of v3.13.0 npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features! npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies npm WARN deprecated core-js@2.6.12: core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js. npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. npm WARN deprecated flatten@1.0.3: flatten is deprecated in favor of utility frameworks such as lodash. npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools. npm WARN deprecated svgo@0.7.2: This SVGO version is no longer supported. Upgrade to v2.x.x. npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor. npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. npm WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x. npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated > core-js@2.6.12 postinstall E:\node\vue296\node_modules\core-js > node -e "try{require('./postinstall')}catch(e){}" Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library! The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: > https://opencollective.com/core-js > https://www.patreon.com/zloirock Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -) > ejs@2.7.4 postinstall E:\node\vue296\node_modules\ejs > node ./postinstall.js Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/) > es5-ext@0.10.60 postinstall E:\node\vue296\node_modules\es5-ext > node -e "try{require('./_postinstall')}catch(e){}" > uglifyjs-webpack-plugin@0.4.6 postinstall E:\node\vue296\node_modules\webpack\node_modules\uglifyjs-webpack-plugin > node lib/post_install.js npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\watchpack-chokidar2\node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules\webpack-dev-server\node_modules\chokidar\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) added 1395 packages from 715 contributors in 76.245s Running eslint --fix to comply with chosen preset rules... # ======================== > vue296@1.0.0 lint E:\node\vue296 > eslint --ext .js,.vue src "--fix" # Project initialization finished! # ======================== To get started: cd vue296 npm run dev Documentation can be found at https://vuejs-templates.github.io/webpack PS E:\node>cd 命令进入到项目目录
npm run dev成功页面
package.json
{ "name": "vue296", "version": "1.0.0", "description": "A Vue.js project", "author": "cwgqmxy <1157818690@qq.com>", "private": true, "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "lint": "eslint --ext .js,.vue src", "build": "node build/build.js" }, "dependencies": { "vue": "^2.5.2", "vue-router": "^3.0.1" }, "devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-loader": "^7.1.1", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "chalk": "^2.0.1", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.28.0", "eslint": "^4.15.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^11.0.0", "postcss-loader": "^2.0.8", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "semver": "^5.3.0", "shelljs": "^0.7.6", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-loader": "^13.3.0", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] }项目结构
一个 vue-cli 的项目结构如下,其中 src 文件夹是需要掌握,其余了解即可。
文件夹目录如下:
1、build目录(webpack配置)
build 文件主要是 webpack 的配置,目录详情如下:
2、config目录(vue项目配置目录)
config 文件主要是项目相关配置,常用的就是当端口冲突时配置监听端口,打包输出路径及命名等,目录详情如下:
3、node_modules(项目依赖包)
node_modules 里面是项目依赖包,其中包括很多基础依赖,自己也可以根据需要安装其他依赖。安装方法打开命令工具,进入项目目录,输入 npm install [依赖包名称],回车。
安装依赖:npm i
在两种情况下我们会自己去安装依赖:
》项目运行缺少该依赖包
》安装插件:如 vuex
PS:有时会安装指定依赖版本,需在依赖包名称后加上版本号信息,
如 npm install vue-loader@11.1.4
src 项目核心文件讲解
核心文件目录前面已经说明了,下面重点讲解 index.html,main.js,App.vue,router 的 index.js,HelloWorld.vue。
1、index.html(主页)
index.html 为项目的主页,跟其他 html 一样,但一般只定义一个空的根节点,在 main.js 里面定义的实例将挂载在根节点下,内容都通过 vue 组件来填充。
说明如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>my-vue-demo</title> </head> <body> <!-- 定义的vue实例将挂载在#app节点下 --> <div id="app"></div> </body> </html>2、main.js(入口文件)
main.js 为项目的入口文件,即单入口,主要是引入 vue 框架,根组件及路由设置,并且定义 vue 实例,说明如下:
// 引入vue框架 import Vue from 'vue' // 引入根组件 import App from './App' // 引入路由配置 import router from './router' // 关闭生产模式下给出的提示 Vue.config.productionTip = false // 定义实例 new Vue({ el: '#app', router, components: { App }, template: '<App/>' })3、App.vue(根组件)
一个 vue 页面通常由三部分组成:
模板 (template)
js (script)
样式 (style)
说明如下:
<!-- 模板 --><template> <div id="app"> <img src="./assets/logo.png"> <router-view/> </div></template><!-- js代码 --><script>export default {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> name: 'App'}</script><!-- css样式 --><style>#app {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;}</style>[ template-模板 ]
(1) 模板只能包含一个父节点,也就是说顶层的 div 只能有一个
(如上图,父节点为 #app 的 div,其没有兄弟节点)
(2)是子路由视图插槽,后面的路由页面都显示在此处,相当于 iframe
【script-JS代码】
vue 通常用 es6 来写,用 export default 导出,其下面可以包含数据 data,生命周期 ( mounted 等),方法( methods )等。
【style-CSS样式】
样式通过 style 标签 <style></style> 包裹,默认是影响全局的,如需定义作用域只在该组件下起作用,需在标签上加 scoped,<style scoped></style>。
引入外部CSS示例:
<style> import './assets/css/public.css' </style>4、router(路由配置)
router文件夹下,有一个 index,js 的路由配置文件,
说明如下:
// 引入vue框架 import Vue from 'vue' // 引入vue-router路由依赖 import Router from 'vue-router' // 引入页面组件,命名为HelloWorld import HelloWorld from '@/components/HelloWorld' // 使用路由依赖 Vue.use(Router) // 定义路由配置 export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] })5、HelloWorld.vue(页面组件)
最熟悉的 HelloWorld 输出,说明如下:
<template> <div> <!-- 输出变量 --> <h1>{{ msg }}</h1> </div> </template> <script> export default { // 定义页面名称,可以不要 name: 'HelloWorld', data () { return { // 定义变量 msg: 'HelloWorld' } } } </script> <style scoped> h1 { font-size: 16px; font-weight: normal; } </style>网页 CDN 引入 vue@2.6.14 示例
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> https://unpkg.com/browse/vue@2.6.14/dist/ 选择vue版本 https://unpkg.com/browse/vue@2.6.14/dist/vue.min.js <!--第一步:创建文件夹及html文件--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <!--第二步:引入Vue库--> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <!--第三步:创建一个Div--> <div id="app"> <!--Vue的模板的绑定数据的方法,用两对花括号进行绑定Vue中的数据对象的属性 --> {{message}} </div> <!--第四步:创建Vue的对象,并把数据绑定到上面创建好的div上去。--> <script type="text/javascript"> var app=new Vue({ // 创建Vue对象。Vue的核心对象。 el:'#app', // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器 data:{ // data: 是Vue对象中绑定的数据 message:'hello Vue!' // message 自定义的数据 } }) </script> </body> </html>内部指令
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> <style type="text/css"> [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <!-- v-if --> <div v-if="isLogin">你好</div> <!-- v-else --> <div v-else>请登录后操作</div> <!-- v-show --> <div v-show="isLogin">你好</div> <!-- v-else-if --> <div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else-if="type === 'C'">C</div> <div v-else>Not A/B/C</div> <!-- v-for基本使用 --> <ul> <li v-for="item in items"> {{item}} </li> </ul> <!-- v-for高级使用 --> <ul> <li v-for="(value, key, index) in object"> {{ index }}. {{ key }} - {{ value }} </li> </ul> <!-- v-text --> <div v-text="message"></div> <!-- v-html --> <div v-html="msgHtml"></div> <!-- v-on部分 --> <div>本场比赛得分:{{count}}</div> <!-- 常规写法 --> <button v-on:click="add">加分</button> <!-- @缩写 --> <button @click="add">加分</button><br/> <!-- v-model input --> <input type="text" v-model="message"> <br/> <!-- v-model textarea --> <textarea cols="30" rows="10" v-model="message"></textarea> <br/> <!-- v-model checkbox --> <input type="checkbox" id="first" value="1" v-model="status"> <label for="first">有效</label> <input type="checkbox" id="second" value="2" v-model="status"> <label for="second">无效</label> <div>状态:{{status}}</div> <!-- v-model radio --> <input type="radio" id="one" value="男" v-model="sex"> <label for="one">男</label> <input type="radio" id="two" value="女" v-model="sex"> <label for="one">女</label> <div>性别:{{sex}}</div> <!-- v-model select --> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <div>Selected: {{ selected }}</div> <!-- v-model select --> <img v-bind:src="imgSrc" width="200px"><br/> <img :src="imgSrc" width="200px"><br/> <!-- v-pre --> <div v-pre>{{message}}</div> <!-- v-cloak --> <div v-cloak>{{message}}</div> <!-- v-pre --> <div v-once>第一次绑定的值:{{message}}</div> </div> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ isLogin: false, type: 'A', items:[20,23,18,65], object: { firstName: 'John', lastName: 'Doe' }, message: 'hello Vue', msgHtml: '<h2>hello Vue!</h2>', count: 1, status: [], sex: '男', selected: '', imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png' }, methods: { add() { this.count++; } } }) </script> </body> </html>(1)v-if
<div v-if="isLogin">你好</div>(2)v-else
<div v-else>请登录后操作</div>(3)v-show
<div v-show="isLogin">你好</div>(4)v-else-if
<div v-if="type === 'A'">A</div> <div v-else-if="type === 'B'">B</div> <div v-else-if="type === 'C'">C</div> <div v-else>Not A/B/C</div>(5)v-if 与 v-show 的区别
v-if: 在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,开销较高,在运行时条件很少改变时使用。
v-show:调整css dispaly属性,开销较小,在常频繁地切换时使用。
(6)v-for
(1)基本用法
<!-- 模板 --> <div id="app"> <ul> <li v-for="item in items"> {{item}} </li> </ul> </div> <!--JS代码 --> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ items:[20,23,18,65] } }) </script>(2)对象遍历
参数: 第一个为值,第二个为键名,第三个为索引
<!-- 模板 --> <div id="app"> <ul> <li v-for="(value, key, index) in object"> {{ index }}. {{ key }} - {{ value }} </li> </ul> </div> <!--JS代码 --> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ object: { firstName: 'John', lastName: 'Doe' } } }) </script>(7)v-text
{{xxx}} 取值有个弊端,当网速很慢或 javascript 出错时,会在页面显示 {{xxx}},Vue 提供的 v-text 可以解决这个问题。
<div>{{ message }}</div> <!-- 和下面的一样 --> <div v-text="message"></div>(8)v-html
用于输出 html 代码
<span v-html="msgHtml"></span><span v-html="msgHtml"></span>(9)v-on
(1)常规用法
// html <div>本场比赛得分:{{count}}</div> <button v-on:click="add">加分</button> // JS data:{ count: 1 }, methods: { add() { this.count++; } }(2)缩写
<button @click="add">加分</button>指令详情的更多用法参照 v-on 官方 API
(10)v-model
以下的 model 都需要在 data 中声明初始值:
data: { message: 'hello Vue', count: 1, status: [], sex: '男', selected: '' }(1)input
(2)textarea
<input type="text" v-model="message"> <textarea cols="30" rows="10" v-model="message"></textarea>(3)checkbox
<input type="checkbox" id="first" value="1" v-model="status"> <label for="first">有效</label> <input type="checkbox" id="second" value="2" v-model="status"> <label for="second">无效</label> <div>状态:{{status}}</div>(4)radio
<input type="radio" id="one" value="男" v-model="sex"> <label for="one">男</label> <input type="radio" id="two" value="女" v-model="sex"> <label for="one">女</label> <div>性别:{{sex}}</div>(5)select
<select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <div>Selected: {{ selected }}</div>(11)v-bind
用于处理 html 标签的动态属性,即动态赋值。
(1)常规用法
// html <img v-bind:src="imgSrc" width="200px"> // js data: { imgSrc:'http://liangxinghua.com/uploads/image/20180709/1531106987.png' }(2)缩写
<img :src="imgSrc" width="200px">指令详情的更多用法参照 v-bind 官方 API
(12)v-pre
在模板中跳过 vue 的编译,直接输出原始值,如果在标签中加入 v-pre 就不会输出 vue 中的data 值了。
<div v-pre>{{message}}</div>(13)v-cloak
在 vue 渲染完指定的整个 DOM 后才进行显示。它必须和 CSS 样式一起使用。
// css [v-cloak] { display: none; } // html <div v-cloak>{{message}}</div>(14)v-once
只显示 DOM 第一次渲染的值,以后不改变了
<div v-once>第一次绑定的值:{{message}}</div>生命周期
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> {{message}} </div> <script type="text/javascript"> var app=new Vue({ el:'#app', data:{ message:'hello Vue!' }, beforeCreate: function () { console.group('beforeCreate 创建前状态===============》'); console.log("%c%s", "color:red" , "el : " + this.$el); //undefined console.log("%c%s", "color:red","data : " + this.$data); //undefined console.log("%c%s", "color:red","message: " + this.message) }, created: function () { console.group('created 创建完毕状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); //undefined console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, beforeMount: function () { console.group('beforeMount 挂载前状态===============》'); console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, mounted: function () { console.group('mounted 挂载结束状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, beforeUpdate: function () { console.group('beforeUpdate 更新前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, updated: function () { console.group('updated 更新完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, beforeDestroy: function () { console.group('beforeDestroy 销毁前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, destroyed: function () { console.group('destroyed 销毁完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message) } }) </script> </body> </html>生命周期表格
周期说明beforeCreate在实例初始化之后,数据观测和事件配置之前被调用created在实例创建完成后被立即调用,完成数据观测,属性和方法的运算,初始化事件,$el属性未见beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用,只在虚拟DOM生成HTMLmounted在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互beforeUpdate在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程updated在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用activatedkeep-alive 组件激活时调用deactivatedkeep-alive 组件停用时调用beforeDestroy在实例销毁之前调用。实例仍然完全可用destroyed在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用生命周期图解
阶段一:创建和挂载
beforecreated:el 和 data 并未初始化 created:完成了 data 数据的初始化,el没有 beforeMount:完成了 el 和 data 初始化 mounted :完成挂载阶段二:更新
在 chrome console 执行以下命令:
app.message= 'yes !! I do';beforeUpdate:虚拟 DOM 中根据 data 变化去更新 html ? ? ?updated:将虚拟 DOM 更新完成的 HTML 更新到页面中
阶段三:销毁
在 chrome console 执行以下命令:
app.$destroy();beforeDestroy:销毁之前调用 ? ? destroyed:销毁之后调用,之后再执行app.message= ‘hello vue’,页面不会同步更新。
常用选项
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> {{message}} <div>价格: {{newPrice}}</div> <div>数字: {{count}}</div> <div><button @click="add(2)">add</button></div> <div><input v-model="question"></div> <div>过滤: {{filtera | filterA}}</div> </div> <script type="text/javascript"> // 额外临时加入时,用于显示日志 var addLog={ updated:function(){ console.log("数据放生变化,变化成"+this.count+"."); } } // 扩展 var extendObj ={ created: function(){ console.log("我是被扩展出来的"); } } // 实例化vue var app = new Vue({ // 挂载实例 el:'#app', // 页面数据初始化,字符,对象、数组 data:{ message: 'hello Vue!', price: 100, count: 100, question: '', filtera: 'abc' }, // 计算属性:主要是对原数据进行改造输出。 // 改造输出:包括格式化数据(价格,日期),大小写转换,排序,添加符号 computed: { newPrice () { return '¥' + this.price + '元'; } }, // 方法声明:用于绑定html中的方法 methods:{ add (num) { this.count += num; } }, // data属性监听器, 作用v-model watch: { question(val, oldVal) { console.log('new: %s, old: %s', val, oldVal); } }, // 过滤器,通常格式化字符,使用传值 filters: { filterA(value) { return value.toUpperCase(); } }, // 混入,作用:减少代码污染、减少代码量、实现代码重用 mixins: [addLog], // 扩展 extends: extendObj }) </script> </body> </html>1、computed 计算属性、改造输出
计算属性:主要是对原数据进行改造输出。
改造输出:包括格式化数据(价格,日期),大小写转换,排序,添加符号。
computed: { newPrice () { return '¥' + this.price + '元'; } }2、methods 用于绑定 html 中的事件对应的方法
方法属性:用于绑定 html 中的事件对应的方法
methods:{ add (num) { this.count += num; } }3、watch 数据变化监听器
数据变化监听器:主要用于监测 data 中的数据变化, v-model 生效
watch: { question(val, oldVal) { console.log('new: %s, old: %s', val, oldVal); } }4、filters 过滤器:通常格式化字符,使用传值
filters: { filterA(value) { return value.toUpperCase(); } }5、mixins 实现代码重用
混入:用于减少代码污染、减少代码量、实现代码重用
// 额外临时加入时,用于显示日志 var addLog={ updated:function(){ console.log("数据放生变化,变化成"+this.count+"."); } } // 实例化vue var app = new Vue({ // 挂载实例 el:'#app', // 页面数据初始化,字符,对象、数组 data:{ count: 100 }, // 混入 mixins: [addLog] })6、extends 扩展:对构造器进行扩展
// 扩展 var extendObj ={ created: function(){ console.log("我是被扩展出来的"); } } // 实例化vue var app = new Vue({ // 挂载实例 el:'#app', // 页面数据初始化,字符,对象、数组 data:{ }, // 扩展 extends: extendObj })实例事件
vue 有实例属性,实例方法,实例事件,前两个跟选项类似,不是很常用,这次只讲实例事件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之Helloworld</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> <div>数字:{{count}}</div> <button onclick="reduce()">on调用</button> <button onclick="reduceOnce()">once调用</button> <button onclick="off()">off调用</button> </div> <script type="text/javascript"> var app = new Vue({ el:'#app', data:{ count: 1 } }) // $on 在构造器外部添加事件 app.$on('reduce',function(){ console.log('执行了reduce()'); this.count--; }); // 调用 function reduce() { // 事件调用 console.log('emit事件调用'); app.$emit('reduce'); } // $once执行一次的事件 app.$once('reduceOnce',function(){ console.log('只执行一次的方法'); this.count--; }); // 调用 function reduceOnce() { app.$emit('reduceOnce'); } // 关闭事件 function off(){ console.log('关闭事件'); app.$off('reduce'); } </script> </body> </html>1、$on(在构造器外部添加事件)
$on 接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法
app.$on('reduce',function(){ console.log('执行了reduce()'); this.count--; });2、$once(执行一次的事件)
app.$once('reduceOnce',function(){ console.log('只执行一次的方法'); this.count--; });3、$off(关闭事件)
function off(){ console.log('关闭事件'); app.$off('reduce'); }4、$emit(事件调用)
function reduce() { // 事件调用 console.log('emit事件调用'); app.$emit('reduce'); }自定义指令
vue 中的自定义指令通过 Vue.directive 来实现,主要完成内置指令不能完成的一些事情。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之自定义指令</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> <div v-test="color"> {{num}} </div> </div> <button onclick="unbindApp()">解绑</button> <script type="text/javascript"> // 解绑 function unbindApp() { app.$destroy(); } // 自定义指令 Vue.directive("test",{ //1-被绑定 bind:function (el, binding, vnode) { console.log("1-bind 被绑定"); console.log("el:",el); console.log("binding:",binding); console.log("vnode:",vnode); el.style.color = binding.value; }, //2-被插入 inserted:function (el, binding, vnode) { console.log("2-inserted 被插入"); }, //3-更新 update:function (el, binding, vnode) { console.log("3-update 更新"); }, //4-更新完成 componentUpdated:function (el, binding, vnode) { console.log("4-componentUpdated 更新完成"); }, //5-解绑 unbind:function (el, binding, vnode) { console.log("5-unbind 解绑"); } }); var app = new Vue({ el:'#app', data:{ num: 123, color:'red' } }) </script> </body> </html>1、调试步骤
(1)chrome打开控制器查看
(2)控制台输入“ app.num='通过控制台设置的新name'”
(3)点击解绑按钮
2、参数说明
? ? ?el:指令所绑定的元素,可以用来直接操作 DOM binding: 一个对象,包含指令的很多信息 ?vnode::Vue编译生成的虚拟节点
3、生命周期
自定义指令有五个生命周期(也叫钩子函数),分别是 bind、inserted、update、componentUpdated、unbind,说明如下:
1、bind:
只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
2、inserted:
被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)
3、update:
被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。
通过比较更新前后的绑定值,可以忽略不必要的模板更新。
4、componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
5、unbind:只调用一次,指令与元素解绑时调用
组件基础
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之组件</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> <!-- 全局组件 --> <div><button-counter></button-counter></div> <!-- 局部组件 --> <div><button-inner></button-inner></div> <!-- 常规属性传值 --> <div><button-props here="hello" from-here="world"></button-props></div> <!-- v-bind传值 --> <div><button-props v-bind:here="message" :from-here="message"></button-props></div> <!-- 父子组件调用 --> <div><parent></parent></div> </div> <script type="text/javascript"> // 定义全局组件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">全局组件显示: {{ count }}</button>' }); // 子组件 var city = { template:`<div>Sichuan of China</div>` } // 父组件 var parent = { template: `<div> <p> Panda from China!</p> <city></city> </div>`, components:{ "city": city } } // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, // 定义局部组件 components:{ "button-inner":{ data: function() { return { inner: 0 } }, template: '<button v-on:click="inner++">局部组件显示: {{ inner }}</button>' }, // 取值 "button-props":{ template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`, props:['here', 'fromHere'] }, // 组件注册 "parent": parent } }); </script> </body> </html>1、组件注册 component
(1)全局注册
// script Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">全局组件显示: {{ count }}</button>' }); new Vue({ el: '#app' }); // html使用 <button-counter></button-counter>(2)局部注册
// script new Vue({ el: '#app', components:{ "button-inner":{ data: function() { return { inner: 0 } }, template: '<button v-on:click="inner++">局部组件显示: {{ inner }}</button>' } } }); // html使用 <button-inner></button-inner>2、props 属性传值
(1)属性取值
// script new Vue({ el: '#app', components:{ "button-props":{ template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`, props:['here', 'fromHere'] } } }); // html使用 <button-props here="hello" from-here="world"></button-props>PS:如果属性带 “-”,props 中需要驼峰取值
(2)在构造器向组件传值(v-bind)
// script new Vue({ el: '#app', data: { message: 'hello' }, components:{ "button-props":{ template:`<div style="color:red;">参数1: {{ here }}:---参数2: {{fromHere}}</div>`, props:['here', 'fromHere'] } } }); // html使用 <button-props v-bind:here="message" :from-here="message"></button-props>3、父子组件
// script // 子组件 var city = { template:`<div>Sichuan of China</div>` } // 父组件 var parent = { template: `<div> <p> Panda from China!</p> <city></city> </div>`, components:{ "city": city } } // 实例化 new Vue({ el: '#app', // 定义局部组件 components:{ // 组件注册 "parent": parent } }); // html使用 <parent></parent>制作模板
vue 中的模板使用 template 来实现。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue入门之组件</title> <script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script> </head> <body> <div id="app"> <!-- template标签模板 --> <template id="demo2"> <h2 style="color:red">我是template标签模板</h2> </template> </div> <!-- script标签模板 --> <script type="x-template" id="demo3"> <h2 style="color:red">我是script标签模板</h2> </script> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, // 选项模板 //template:`<h1 style="color:red">我是选项模板</h1>` //template:'#demo2' template:'#demo3' }); </script> </body> </html>1、选项模板
<div id="app"> </div> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:`<h1 style="color:red">我是选项模板</h1>` }); </script>2、标签模板
<div id="app"> <template id="demo2"> <h2 style="color:red">我是template标签模板</h2> </template> </div> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:'#demo2' }); </script>3、<script> 标签模板
<div id="app"> </div> <script type="x-template" id="demo3"> <h2 style="color:red">我是script标签模板</h2> </script> <script type="text/javascript"> // 实例化 new Vue({ el: '#app', data: { message: 'hello' }, template:'#demo3' }); </script>插槽 slot
插槽,也就是 slot,是组件的一块HTML模板,一个 slot 最核心的两个问题是显示不显示和怎样显示。
1、单个 slot
单个插槽,别名默认插槽、匿名插槽,不用设置 name 属性。
<div id="app"> <children1> <span>12345</span> </children1> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', components: { children1: { template: "<button><slot></slot>单个插槽</button>" } } }); </script>2、具名 slot
插槽加了 name 属性,就变成了具名插槽。
具名插槽可以在一个组件中出现 N 次,出现在不同的位置。
<div id="app"> <children2> <span slot="first" @click="tobeknow">12345</span> <span slot="second">56789</span> </children2> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', methods: { tobeknow: function () { console.log("It is the parent's method"); } }, components: { children2: {//这个无返回值,不会继续派发 template: "<button><slot name='first'></slot>具名插槽,<slot name='second'></slot></button>" } } }); </script>3、作用域 slot
vue2.5 版本中 slot-scope 取代了 scope,来实现作用域插槽,主要用在组件调用中,具体在 template 标签上面使用 slot-scope 来获取插槽 slot 上面的属性值,获取值的为一个对象,slot-scope=”它可以取任意字符串”,在 element-ui 的组件中经常看到。
<div id="app"> <!-- 将数据传递给组件 --> <tb-list :data="data"> <!-- 获取slot上面的值 --> <template slot-scope="scope"> <p>索引:{{JSON.stringify(scope)}}</p> <p>索引:{{scope.$index}}</p> <p>姓名:{{scope.row.name}}</p> <p>年龄: {{scope.row.age}}</p> <p>性别: {{scope.row.sex}}</p> </template> </tb-list> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { data: [{ name: 'kongzhi1', age: '29', sex: 'man' }] }, components: { // 作用域slot 'tb-list': { template: `<ul> <li v-for="(item, index) in data"> <slot :row="item" :$index="index"></slot> </li> </ul>`, // 获取值 props: ['data'] } } }); </script>Vue 项目中应用 vue-router
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。
包含的功能有:
嵌套的路由/视图表、模块化的、基于组件的路由配置、路由参数、查询、通配符、基于 Vue.js 过渡系统的视图过渡效果、细粒度的导航控制、带有自动激活的 CSS class 的链接、HTML5 历史模式或 hash 模式,在 IE9 中自动降级、自定义的滚动条行为快速入门
vue-router 是 vue 官方的路由解决方案,简单易用,中文官方地址如下:vue-router 中文手册
安装
vue-router 是一个插件包,需要用 npm 来进行安装的。如果采用 vue-cli 构建初始化项目会提示安装,也可以自己使用命令安装:
npm install vue-router --save解读核心文件
用 vue-cli 构建项目之后,在 src/router/index.js 文件中,看到以下的路由核心文件:
// 引入vue框架 import Vue from 'vue' // 引入vue-router路由依赖 import Router from 'vue-router' // 引入页面组件,命名为 HelloWorld import HelloWorld from '@/components/HelloWorld' // Vue全局使用Router Vue.use(Router) // 定义路由配置 export default new Router({ routes: [ //配置路由,这里是个数组 { //每一个链接都是一个对象 path: '/', //链接路径 name: 'HelloWorld', //路由名称, component: HelloWorld //对应的组件模板 } ] })使用
在系统入口文件 main.js 中注入 router,代码如下:
// 引入vue框架 import Vue from 'vue' // 引入根组件 import App from './App' // 引入路由配置 import router from './router' // 关闭生产模式下给出的提示 Vue.config.productionTip = false // 定义实例 new Vue({ el: '#app', router, // 注入框架中 components: { App }, template: '<App/>' })路由属性配置说明
代码如下:
export default new Router({ mode: 'history', //路由模式,取值为history与hash base: '/', //打包路径,默认为/,可以修改 routes: [ { path: string, //路径 ccomponent: Component; //页面组件 name: string; // 命名路由-路由名称 components: { [name: string]: Component }; // 命名视图组件 redirect: string | Location | Function; // 重定向 props: boolean | string | Function; // 路由组件传递参数 alias: string | Array<string>; // 路由别名 children: Array<RouteConfig>; // 嵌套子路由 beforeEnter?: (to: Route, from: Route, next: Function) => void; // 路由单独钩子 meta: any; // 自定义标签属性,比如:是否需要登录 icon: any; // 图标 // 2.6.0+ caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false) pathToRegexpOptions: Object; // 编译正则的选项 } ] })页面跳转
一、router-link 标签跳转
在 html 标签内使用 router-link 跳转,相应于超链接 a 标签,使用方式如下:
<router-link to="/">[显示字段]</router-link>to:导航路径
使用示例如下:
<p>导航 : <router-link to="/">首页</router-link> <router-link to="/hello">hello</router-link> </p>二、编程式导航-JS代码内部跳转
实际项目中,很多时候都是通过在JS代码内部进行导航的跳转,使用方式如下:
this.$router.push('/xxx')具体的简单用法:
(1)先编写一个按钮,在按钮上绑定 goHome( ) 方法。
<button @click="goHome">回到首页</button>(2)在 <script> 模块里加入 goHome 方法,并用 this.$router.push(‘/’) 导航到首页
export default { name: 'app', methods: { goHome(){ this.$router.push('/home'); } } }三、其他常用方法
// 后退一步记录,等同于 history.back() this.$router.go(-1) // 在浏览器记录中前进一步,等同于 history.forward() this.$router.go(1)子路由-路由嵌套
子路由,也叫路由嵌套,采用在 children 后跟路由数组来实现,数组里和其他配置路由基本相同,需要配置 path 和 component,然后在相应部分添加 <router-view/> 来展现子页面信息,相当于嵌入 iframe 。
1、src/components/Home.vue(父页面)
<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 添加子路由导航 --> <p>导航 : <router-link to="/home">首页</router-link> | <router-link to="/home/one">-子页面1</router-link> | <router-link to="/home/two">-子页面2</router-link> </p> <!-- 子页面展示部分 --> <router-view/> </div> </template> <script> export default { name: 'Home', data () { return { msg: 'Home Page!' } } } </script> <style scoped> </style>2、src/components/One.vue(子页面1)
<template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: 'One', data () { return { msg: 'Hi, I am One Page!' } } } </script> <style scoped> </style>3、src/components/Two.vue(子页面2)
<template> <div class="hello"> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: 'Two', data () { return { msg: 'Hi, I am Two Page!' } } } </script> <style scoped> </style>4、src/router/index.js(路由配置)
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' Vue.use(Router) export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children:[ // 嵌套子路由 { path:'one', // 子页面1 component:One }, { path:'two', // 子页面2 component:Two }, ] } ] })路由传递参数
1、通过 <router-link> 标签中的 to 传参
基本语法:
<router-link :to="{name:xxx, params: {key:value}}"> valueString </router-link>PS:上面 to 前边是带冒号,后边跟的是一个对象形势的字符串
? name:在路由配置文件中起的 name 值。叫做命名路由,下一节会讲到。 params:要传的参数,它是对象形式,在对象里可以传递多个值。
具体实例如下:
(1)在 src/components/Home.vue 里面导航中添加如下代码:
<router-link :to="{name: 'one', params:{username:'test123'}}"> 子页面1 </router-link>(2)在 src/router/indes.js 中添加如下代码,重点是 name:
{ path:'one', // 子页面1 name: 'one', // 路由名称-命名路由 component:One }(3)在 src/components/One.vue 里面接受参数,代码如下:
<h2>{{$route.params.username}}</h2>2、url 中传递参数
(1)在路由中以冒号传递,在 src/router/index.js 中加入如下代码:
{ path:'/home/two/:id/:name', // 子页面2 component:Two },(2)接受参数,在 src/components/Two.vue 中加入如下代码:
<p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p>(3)路由跳转,在 src/components/Home.vue 中加入如下代码:
<router-link to="/home/two/1/张三">子页面2</router-link>PS:to 前没有冒号为字符串路由,必须全部匹配。
(4)如果路由参数需要有特定的规则,就需要加入正则表达式了,示例如下:
{ path:'/home/two/:id(\\d+)/:name', // 子页面2 component:Two }源码 E:\node\vue296\src\router\index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' Vue.use(Router) export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children: [ // 嵌套子路由 { path: 'one', // 子页面1 name: 'one', // 路由名称-命名路由 component: One }, { path: '/home/two/:id/:name', // 子页面2 component: Two }, ] } ] })E:\node\vue296\src\components\Two.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p> </div> </template> <script> export default { name: 'Two', data () { return { msg: 'Hi, I am Two Page!' } } } </script> <style scoped> </style>E:\node\vue296\src\components\Home.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 添加子路由导航 --> <p>导航 : <router-link to="/home">首页</router-link> | <router-link to="/home/one">-子页面1</router-link> | <router-link to="/home/two">-子页面2</router-link> <br> <router-link :to="{name: 'one', params:{username:'test123'}}">子页面1传递参数</router-link> <br> <router-link to="/home/two/1/张三">子页面2</router-link> </p> <!-- 子页面展示部分 --> <router-view/> </div> </template> <script> export default { name: 'Home', data () { return { msg: 'Home Page!' } } } </script> <style scoped> </style>编程式导航 -params 传递参数
(1)在 src/router/index.js 页面加入如下代码:
{ path:'/home/three', // 子页面3 name: 'three', component:Three }(2)在 src/components/Three.vue 页面加入如下代码:
<p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p>(3)在 src/components/Home.vue 中加入如下代码:
// template <button @click="toThreePage">页面3-params传参</button> // script methods: { toThreePage() { this.$router.push({name: 'three', params: {id: 1, name: 'zhangsan'}}) } }说明:
A、动态路由使用 params 传递参数,在 this.$router.push() 方法中 path 不能和 params 一起使用,否则 params 将无效。需要用 name 来指定页面。
B、以上方式参数不会显示到浏览器的地址栏中,如果刷新一次页面,就获取不到参数了,改进方式将第一部中的代码改成如下:
{ path:'/home/three/:id/:name', // 子页面3 name: 'three', component:Three }源码 E:\node\vue296\src\router\index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' import Three from '@/components/Three' Vue.use(Router) export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children: [ // 嵌套子路由 { path: 'one', // 子页面1 name: 'one', // 路由名称-命名路由 component: One }, { path: '/home/two/:id/:name', // 子页面2 component: Two }, { path:'/home/three/:id/:name', // 子页面3 name: 'three', component:Three } ] } ] })E:\node\vue296\src\components\Three.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>ID:{{ $route.params.id}}</p> <p>名称:{{ $route.params.name}}</p> </div> </template> <script> export default { name: 'Three', data () { return { msg: 'Hi, I am Three Page!' } } } </script> <style scoped> </style>E:\node\vue296\src\components\Home.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 添加子路由导航 --> <p>导航 : <router-link to="/home">首页</router-link> | <router-link to="/home/one">-子页面1</router-link> | <router-link to="/home/two">-子页面2</router-link> <br> <router-link :to="{name: 'one', params:{username:'test123'}}">子页面1传递参数</router-link> <br> <router-link to="/home/two/1/张三">子页面2</router-link> <br> <button @click="toThreePage">页面3-params传参</button> </p> <!-- 子页面展示部分 --> <router-view/> </div> </template> <script> export default { name: 'Home', data () { return { msg: 'Home Page!' } }, methods: { toThreePage() { this.$router.push({name: 'three', params: {id: 1, name: 'zhangsan'}}) } } } </script> <style scoped> </style>编程式导航 -query 传递参数
(1)在 src/router/index.js 页面加入如下代码:
{ path:'/home/three', // 子页面3 name: 'three', component:Three }(2)在 src/components/Three.vue 页面加入如下代码:
<p>ID:{{ $route.query.id}}</p> <p>名称:{{ $route.query.name}}</p>(3)在 src/components/Home.vue 中加入如下代码:
// template <button @click="toThreePage">页面3-params传参</button> // script methods: { toThreePage() { this.$router.push({path: '/home/three', query: {id: 1, name: 'zhangsan'}}) } }PS:动态路由使用 query 传递参数,会显示到浏览器地址栏中,
以上链接为 /home/three?id=1&name=zhangsan。
源码
E:\node\vue296\src\router\index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' import Three from '@/components/Three' Vue.use(Router) export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children: [ // 嵌套子路由 { path: 'one', // 子页面1 name: 'one', // 路由名称-命名路由 component: One }, { path: '/home/two/:id/:name', // 子页面2 component: Two }, { path:'/home/three', // 子页面3 name: 'three', component:Three } ] } ] })E:\node\vue296\src\components\Three.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>ID:{{ $route.query.id}}</p> <p>名称:{{ $route.query.name}}</p> </div> </template> <script> export default { name: 'Three', data () { return { msg: 'Hi, I am Three Page!' } } } </script> <style scoped> </style>E:\node\vue296\src\components\Home.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <!-- 添加子路由导航 --> <p>导航 : <router-link to="/home">首页</router-link> | <router-link to="/home/one">-子页面1</router-link> | <router-link to="/home/two">-子页面2</router-link> <br> <router-link :to="{name: 'one', params:{username:'test123'}}">子页面1传递参数</router-link> <br> <router-link to="/home/two/1/张三">子页面2</router-link> <br> <button @click="toThreePage">页面3-params传参</button> </p> <!-- 子页面展示部分 --> <router-view/> </div> </template> <script> export default { name: 'Home', data () { return { msg: 'Home Page!' } }, methods: { toThreePage() { this.$router.push({path: '/home/three', query: {id: 1, name: 'zhangsan'}}) } } } </script> <style scoped> </style>命名路由-命名视图-重定向-别名
1、命名路由
给一个路由命一个唯一的名称,然后跳转调用这个名称即可。
(1)在 src/router/index.js 中加一个带 name 的路由,代码如下:
{ path: 'one', // 子页面1 name: 'one', // 路由名称-命名路由 component: One // 页面组件 }(2)在 src/component/Home.vue 页面中调用,代码如下:
// template跳转调用 <router-link :to="{name: 'one'}">子页面1</router-link> // router.push函数跳转调用 router.push({ name: 'user'}})2、命名视图
在同一个页面展示多个视图,如果不用嵌套,只能采用命名视图来实现了。
代码如下:
(1)在 src/router/index.js 中,代码如下:
import Vue from 'vue' import Router from 'vue-router' // 创建页面组件 const Header = { template: '<div>Header</div>' } const Left = { template: '<div>Left</div>' } const Right = { template: '<div>Right</div>' } Vue.use(Router) export default new Router({ routes: [ { path: '/', // 主页路由 components: { default: Header, a: Left, b: Right } } ] })(2)在 src/App.vue 中,代码如下:
<template> <div id="app"> <router-view /> <router-view name="a" class="left" /> <router-view name="b" class="right" /> </div> </template> <script> export default { name: 'App' } </script> <style> #app { text-align: center; color: #2c3e50; width: 500px; border: 1px solid red; margin: 0 auto; } .left,.right{ float: left; width:48%; text-align: center; border:1px solid red } </style>PS:经过实践,命名视图只能放在最顶级的页面中,即第一步中的代码不能放在其他页面中。
3、重定向
重定向是通过 route 的配置中关键词 redirect 来实现的,具体代码如下:
(1)在 src/router/index.js 中,代码如下:
export default new Router({ routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' // 重定向 }, { path: '/home', // 主页路由 component: Home, children:[ // 嵌套子路由 { path:'/home/two/:id/:name', // 子页面2 component:Two }, { path:'/home/three/:id/:name', // 子页面3 name: 'three', // 路由名称-命名路由 redirect: '/home/two/:id/:name' // 重定向-传递参数 }, ] } ] })(2)在 src/components/Home.vue 中,代码如下:
<router-link to="/">首页</router-link> | <router-link to="/home/two/1/lisi">子页面2</router-link> | <router-link :to="{name: 'three', params: {id: 1, name: 'zhangsan'}}"> 子页面3 </router-link>说明1-不带参数的重定向:
redirect: '/home' // 重定向-不带参数说明2-带参数的重定向:
redirect: '/home/two/:id/:name' // 重定向-传递参数4、别名
重定向是通过 route 的配置中关键词 alias 来实现的,具体代码如下:
(1)在 src/router/index.js 中,代码如下:
{ path:'/one', // 子页面1 component:One, alias: '/oneother' }(2)在 src/components/Home.vue 中,代码如下:
<router-link to="/oneother">子页面1</router-link>说明1:redirect 和 alias 的区别
redirect:直接改变了 url 的值,把 ur l变成了真实的 path 路径。\
alias:
url 路径没有别改变,这种更友好,让用户知道自己访问的路径,只是改变了 <router-view> 中的内容。
说明2:别名请不要用在 path 为 ’/’ 中,如下代码的别名是不起作用的。
<router-link to="/oneother">子页面1</router-link>过渡动画
(1)在 <router-view> 标签的外部添加 <transition> 标签,标签还需要一个 name 属性,代码如下:
<transition name="fade" mode="out-in"> <router-view /> </transition>过渡模式 mode
in-out:新元素先进入过渡,完成之后当前元素过渡离开,默认模式。
out-in:当前元素先进行过渡离开,离开完成后新元素过渡进入。
(2)加入CSS,一共4个CSS类名,四个类名与 transition 的 name 属性有关,比如name=”fade”,相应的 css 如下:
/*页面切换动画*/ /*进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除*/ .fade-enter-active { transition: opacity .5s; } /*进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除*/ .fade-enter { opacity: 0; } /*离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除*/ .fade-leave { opacity: 1; } /*离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除*/ .fade-leave-active { opacity:0; transition: opacity .5s; }文件:E:\node\vue296\src\App.vue
<template> <div id="app"> <img src="./assets/logo.png"> <transition name="fade" mode="out-in"> <router-view /> </transition> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } /*页面切换动画*/ /*进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除*/ .fade-enter-active { transition: opacity .5s; } /*进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除*/ .fade-enter { opacity: 0; } /*离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除*/ .fade-leave { opacity: 1; } /*离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除*/ .fade-leave-active { opacity:0; transition: opacity .5s; } </style>mode 与 404
1、mode 模式
代码示例:
export default new Router({ mode: 'history', //mode模式 routes: [...] })mode取值说明:
(1)histroy:URL就像正常的 url,示例:http://localhost:8080/home (2) ? hash:默认值,会多一个 “#”,示例:http://localhost:8080/#/home
2、404页面设置
如果访问的路由不存在,或者用户输入错误时,会有一个404友好的提示页面,配置如下:
(1)在 /src/router/index.js 中加入如下代码:
// 404 { path: '*', component: () => import('@/components/404') }(2)在 src/components/404.vue 中编写如下代码:
<template> <div class="hello"> <h1>404 not found</h1> </div> </template> <script> export default { data () { return { } } } </script> <style scoped> </style>路由钩子
路由钩子,即导航钩子,其实就是路由拦截器,vue-router 一共有三类:
1、全局钩子:最常用
2、路由单独钩子
3、组件内钩子
1、全局钩子
在 src/router/index.js 中使用,代码如下:
// 定义路由配置 const router = new VueRouter({ ... }) // 全局路由拦截-进入页面前执行 router.beforeEach((to, from, next) => { // 这里可以加入全局登陆判断 // 继续执行 next(); }); // 全局后置钩子-常用于结束动画等 router.afterEach(() => { //不接受next }); export default router;每个钩子方法接收三个参数:
? ? ?to: Route : 即将要进入的目标 [路由对象] ? ?from: Route : 当前导航正要离开的路由 next: Function : 继续执行函数
next():继续执行 next(false):中断当前的导航。 next(‘/‘) 或 next({ path: ‘/‘ }):跳转新页面,常用于登陆失效跳转登陆2、路由单独钩子
使用:在路由配置中单独加入钩子,在 src/router/index.js 中使用,代码如下:
{ path:'/home/one', // 子页面1 component: One, // 路由内钩子 beforeEnter: (to, from, next) => { console.log('进入前执行'); next(); } }3、组件内钩子
使用:在路由组件内定义钩子函数:
beforeRouteEnter:进入页面前调用 beforeRouteUpdate (2.2 新增):页面路由改变时调用,一般需要带参数 beforeRouteLeave:离开页面调用任意找一页面,编写如下代码:
<script> export default { name: 'Two', data () { return { msg: 'Hi, I am Two Page!' } }, // 进入页面前调用 beforeRouteEnter(to, from, next) { console.log('进入enter路由钩子') next() }, // 离开页面调用 beforeRouteLeave(to,from, next){ console.log('进入leave路由钩子') next() }, // 页面路由改变时调用 beforeRouteUpdate(to, from, next) { console.log('进入update路由钩子') console.log(to.params.id) next() } } </script>路由懒加载
1、路由正常模式:
// 1、先引入页面组件 import Home from '@/components/Home' // 2、使用组件 { path: '/home', component: Home }2、懒加载模式
大项目中,为了提高初始化页面的效率,路由一般使用懒加载模式,一共三种实现方式。
(1)第一种写法:
component: (resolve) => require(['@/components/One'], resolve)(2)第二种写法:
component: () => import('@/components/Two')(3)第三种写法:
components: r => require.ensure([], () => r(require('@/components/Three')), 'group-home')PS:
一般常用第二种简写 第三种中,’group-home’ 是把组件按组分块打包, 可以将多个组件放入这个组中,在打包的时候 Webpack 会将相同 chunk 下的所有异步模块打包到一个异步块里面。
路由懒加载用法:E:\node\vue296\src\router\index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/components/Home' import One from '@/components/One' import Two from '@/components/Two' import Three from '@/components/Three' Vue.use(Router) export default new Router({ mode: 'history', //mode模式 routes: [ { path: '/', // 默认页面重定向到主页 redirect: '/home' }, { path: '/home', // 主页路由 name: 'Home', component: Home, children: [ // 嵌套子路由 { path: 'one', // 子页面1 name: 'one', // 路由名称-命名路由 component: One }, { path: '/home/two/:id/:name', // 子页面2 component: Two }, { path:'/home/three', // 子页面3 name: 'three', component:Three } ] }, { path: '*', component: () => import('@/components/404') } ] })vuex 背景引言
1、vuex是什么?
vuex是一个专为 Vue.js 应用程序开发的 状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
chrome 安装调试工具 devtools extension。
2、单向数据流
示意图说明:
? State:驱动应用的数据源(单向数据流) ? ?View:以声明方式将 state 映射到视图(静态显示出来的数据源) Actions:处理用户在 view 上面操作而导致的状态变化(数据源变化追踪)
一个简单的 demo 案例: E:\node\vue296\src\router\index.js
// 引入组件 import HelloWorld from '@/components/HelloWorld' // 添加路由 { path: '/hello', name: 'HelloWorld', component: HelloWorld, }E:\node\vue296\src\components\Home.vue 首页
<!-- 添加跳转 --> <router-link to="/hello">Hello页</router-link>E:\node\vue296\src\components\HelloWorld.vue 案例页
<template> <div> <!-- view --> <div>{{ count }}</div> <button @click="increment">increment</button> </div> </template> <script> export default { // state data () { return { count: 0 } }, // actions methods: { increment () { this.count++ } } } </script> <style scoped> </style>3、vuex 解决的问题
多个视图组件,包括父子组件,兄弟组件之间的状态共享。
不同视图组件的行为需要变更同一个状态。
4、vuex 使用场景
中大型单页应用,需要考虑如何更好地在组件外部管理状态,简单应用不建议使用。
5、vuex 与全局变量的区别
响应式:
vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会得到高效更新。
不能直接改变store:
不能直接改变 store 的变化,改变 store 中状态的唯一途径是 commit mutation,方便于跟踪每一个状态的变化。
6、vuex 核心流程
示意图说明:
1、Vue Components Vue组件:
HTML页面上,负责接收用户操作等交互行为,执行 dispatch 方法触发对应 action 进行回应。
2、Dispatch:操作行为触发方法,是唯一能执行 action 的方法。
3、Actions 操作行为处理模块:
负责处理 Vue Components 接收到的所有交互行为。
包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。
向后台API请求的操作就在这个模块中进行,包括触发其他 action 以及提交 mutation 的操作。该模块提供了 Promise 的封装,以支持 action 的链式触发。
4、Commit 态改变提交操作方法:
状对 mutation 进行提交,是唯一能执行 mutation 的方法。
5、Mutations 状态改变操作方法:
是 Vuex 修改 state 的唯一推荐方法,其他修改方式在严格模式下将会报错。
该方法只能进行同步操作,且方法名只能全局唯一。
操作之中会有一些 hook 暴露出来,以进行 state 的监控等。
6、State 页面状态管理容器对象:
集中存储 Vue components 中 data 对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用Vue的细粒度数据响应机制来进行高效的状态更新。
7、Getters:state对象读取方法。
图中没有单独列出该模块,应该被包含在了render 中,Vue Components 通过该方法读取全局 state 对象。
总结说明:
Vue 组件接收交互行为,调用 dispatch 方法触发 action 相关处理,若页面状态需要改变,则调用 commit 方法提交 mutation 修改 state,通过 getters 获取到 state 新值,重新渲染Vue Components,界面随之更新。
入门示例
安装
PS E:\node\vue296> npm install --save vuex@3.6.2 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\watchpack-chokidar2\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules\webpack-dev-server\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) + vuex@3.6.2 removed 1 package and updated 1 package in 8.474s PS E:\node\vue296>(1)新建 src/vuex/store.js 中写入以下代码:
// 引入vue import Vue from 'vue' // 引入vuex import Vuex from 'vuex' // 使用vuex Vue.use(Vuex) // 1、state:创建初始化状态 const state = { // 放置初始状态 count: 1 } // 2、mutations:创建改变状态的方法 const mutations = { // 状态变更函数-一般大写 ADD (state, n) { state.count += n; } } // 3、getters:提供外部获取state const getters = { count: function(state){ return state.count; } } // 4、actions:创建驱动方法改变mutations const actions ={ // 触发mutations中相应的方法-一般小写 add ({commit}, data) { commit('ADD', data) } } // 5、全部注入Store中 const store = new Vuex.Store({ state, mutations, getters, actions }); // 6、输出store export default store;代码说明:
state - mutations - getters - actions - store,以上写法基本固定。
小型项目用上面的简单管理状态即可。
(2)src/main.js 代码中添加
import Vue from 'vue' import App from './App' import router from './router' // 引入store import store from './vuex/store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, // 全局注入 components: { App }, template: '<App/>' })(3)src/compontent/Count.vue 页面组件中代码如下:
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>{{count}}</h2> <button @click="clickAdd">新增</button> </div> </template> <script> export default { data () { return { msg: 'Vuex test!' } }, computed: { // 获取 state 值 count() { return this.$store.state.count; } }, methods: { clickAdd() { //分发action中的add方法 this.$store.dispatch('add', 1); } } } </script> <style scoped> </style>state-状态对象的获取方法
1、在组件的 template 中直接使用
<h2>{{ $store.state.count }}</h2>2、在计算属性 computed 中直接赋值
// 方式1:直接获取 computed: { count() { // this指的是main.js中的vue实例对象 return this.$store.state.count; } }3、通过 mapState 的对象来赋值
// 方式2:利用mapState computed: mapState({ // es5写法 count: function (state) { return state.count; }, // es6写法 count: state => state.count })4、通过 mapState 的数组来赋值
// 方式3:数组获取 computed: mapState(['count'])5、通过 mapState 的 JSON 来赋值
// 方式4:JSON获取 computed: mapState({ count: 'count' })PS:一般 4 和 5 两种比较常用
完整示例代码:E:\node\vue296\src\components\Count.vue
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>{{ $store.state.count }}</h2> <h2>{{count}}</h2> <button @click="clickAdd">新增</button> </div> </template> <script> import {mapState} from 'vuex' export default { data () { return { msg: 'Vuex test!' } }, // 方式1:在计算属性computed中直接赋值 // computed: { // count() { // // this指的是main.js中的vue实例对象 // return this.$store.state.count; // } // }, // 方式2:通过mapState的对象来赋值 // computed: mapState({ // // es5 // // count: function (state) { // // return state.count; // // }, // // es6 // count: state => state.count // }), // 方式3:通过mapState的对象来赋值 // computed: mapState(['count']), // 方式4:通过mapState的JSON来赋值 computed: mapState({ count: 'count' }), methods: { clickAdd() { //分发action中的add方法 this.$store.dispatch('add', 1); } } } </script> <style scoped> </style>mutations - getters - actions 异步 1、mutations(修改状态)
(1)template 中直接使用 $store.commit( ) 触发
// template <button @click="$store.commit('ADD')">+</button> // src/vuex/store.js const mutations = { // 状态变更函数 ADD (state) { state.count++; } }(2)利用 mapMutations 引入触发
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>{{count}}</h2> <!-- 3、、直接调用相应的方法 --> <button @click="ADD">+</button> </div> </template> <script> // 1、引入mapMutations import {mapState, mapMutations} from 'vuex' export default { data () { return { msg: 'Vuex test!' } }, // 通过mapState的JSON来赋值 computed: mapState({ count: 'count' }), // 2、methods中加入mapMutations methods: mapMutations([ 'ADD' ]) } </script> <style scoped> </style>2、getters(获取state和过滤)
(1)基本用法
// src/vuex/store.js const getters = { count: function(state){ // 返回加上100 return state.count + 100; } }(2)常规获取值
computed: { // 获取getters count(){ return this.$store.getters.count; } }(3)mapGetters 获取值
// 1、引入mapMutations import {mapState, mapMutations, mapGetters} from 'vuex' // 2、使用 computed: { // 获取getters ...mapGetters(["count"]) }3、actions(异步状态修改)
actions 和 mutations 功能基本一样,不同点是,actions 是异步的改变 state 状态,而mutations 是同步改变状态。
不过实际项目中一般都是通过 actions 改变 mutations 中的值。
(1)store.js 中增加异步代码
// src/vuex/store.js const actions ={ // 触发mutations中相应的方法 add ({commit}) { // 增加异步 setTimeout(()=>{ commit('ADD') },3000); console.log('我比reduce提前执行'); } }(2)常规使用
// template <button @click="add">+</button> // script methods: { add() { //分发action this.$store.dispatch('add'); } }(3)mapActions 的使用
// template <button @click="add">+</button> // script // 引入mapActions import {mapState, mapActions} from 'vuex' // 使用mapActions methods: { ...mapActions(['add']) }传递参数
在 vuex 的方法调用传递参数,只需要在 mutations 和 actions 相应的地方加上参数,然后调用的时候传入即可。
(1)src/vuex/store.js 中
// actions中传递参数 const mutations = { ADD (state, n) { state.count += n; } } // actions中传递参数 const actions ={ // 触发mutations中相应的方法 add ({commit}, n) { // 增加异步 setTimeout(()=>{ commit('ADD', n); },3000); console.log('我比reduce提前执行'); } }(2)页面组件常规调用传递
// template <button @click="add">+</button> // script methods: { add() { // 分发action this.$store.dispatch('add', 99); } }(3)页面组件使用 mapActions 调用传递
// template <button @click="add(99)">+</button> // script methods: { ...mapActions(['add']) }module-模块组
当应用非常复杂,状态非常多的时候,需要将 store 分割成模块(module)。
每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割。
1、大致的结构
// 模块A const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } // 模块B const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } // 组装 const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) // 取值 store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态2、详细示例
实际开发中建议把 module 分开编写。
(1)src/vuex/module1.js
// 模块1 const module1 = { // 初始化状态 state: { module1: { name: '模块1' } }, // 编写动作 mutations: { CHANGE1 (state, data) { state.module1 = data; } }, // 取值 getters: { module1: function(state){ return state.module1; } }, // 创建驱动,可异步 actions: { change1 ({commit}, data) { commit('CHANGE1', data) } } } export default module1;(2)src/vuex/module2.js
// 模块2 const module2 = { // 初始化状态 state: { module2: { name: '模块2' } }, // 编写动作 mutations: { CHANGE2 (state, data) { state.module2 = data; } }, // 取值 getters: { module2: function(state){ return state.module2; } }, // 创建驱动,可异步 actions: { change2 ({commit}, data) { commit('CHANGE2', data) } } } export default module2;(3)src/vuex/store.js
// 引入vue import Vue from 'vue' // 引入vuex import Vuex from 'vuex' // 引入module1 import module1 from '@/vuex/module1' // 引入module2 import module2 from '@/vuex/module2' // 使用vuex Vue.use(Vuex) // 模块注入 const store = new Vuex.Store({ modules: { a: module1, b: module2 } }) // 输出store export default store;(4)组件中使用,src/compontent/one.vue
<template> <div id="app"> <!-- module1 --> <h2>{{ module1.name }}</h2> <button @click="change1({'name': 'change1'})">module1改变</button> <!-- module2 --> <h2>{{ module2.name }}</h2> <button @click="change2({'name': 'change2'})">module2改变</button> </div> </template> <script> // 引入快捷方法 import {mapState, mapGetters, mapActions} from 'vuex' export default { name: 'app', data () { return { } }, computed:{ // mapState取值 // ...mapState({ // module1: state => state.a.module1.name, // module2: state => state.b.module2.name // }) // mapGetter取值 ...mapGetters(['module1', 'module2']) }, methods: { // mapAction取方法 ...mapActions([ 'change1', 'change2' ]) } } </script> <style> </style>PS:module 中命名要唯一,不然获取值和改变值的时候会冲突,目前亲测 mapGetters 只能获取对象。
总结
到此这篇关于Vue命令行工具Vue-CLI图文的文章就介绍到这了,更多相关Vue命令行工具Vue-CLI内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。