vue-cli
Vue-cli(Command-Ling-Interface:命令行界面或者字符用户界面)家族
成员:cli2,cli3
环境搭建以及项目创建
Node.js环境安装
下载
安装
下载安装包到本地磁盘,运行安装包,进行安装.
可以自定义安装路径
至此,安装完成,可以打开命令行,输入命令node -v
查看node.js安装版本.
我们发现此处该命令不可用,需要配置环境变量.
配置
配置系统环境变量:
编辑path变量,添加,node.js的安装路径.
Path:E:\software\software\node\installPath
在命令行中输入node -v
,可以查看版本
输入npm -v
,查看npm版本
Vue-cli安装
NPM
NPM介绍
NPM是随同NodeJS一起安装的包管理工具. 能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:
允许用户从NPM服务器下载别人编写的第三方包到本地使用。
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
新版的nodejs已经集成了npm,所以之前npm也一并安装好了。
NPM与CNPM的区别
NPM使用
Install可以使用i代替,则npm install -g vue-cli
可以使用npm i -g vue-cli
代替
命令: npm i -g –save --dev vue-cli
:表示安装包信息加入到开发阶段的依赖.
可以缩写为npm i -g --d vue-cli
CNPM
安装完成CNPM
安装vue-cli
安装方式
在命令行中输入下载命令:npm install -g vue-cli
此种方式是从国外的网站下载,受各种因素影响,可能下载比较慢,可以使用淘宝镜像安装.
ctrl+c
:终止安装
使用淘宝镜像安装:
通过如下图设置之后,可以使用
npm install -g vue-cli
来从淘宝镜像下载vue-cli
安装配置好CNPM之后,可以使用
cnpm install -g vue-cli
命令,在淘宝镜像安装
安装vue-cli
一般情况下使用cnpm install -gd vue-cli
从淘宝镜像安装.
安装过程不需要手动干预,等待安装完成即可.
安装完之后,使用
vue -V
命令来查看版本,检测是否安装成功.
创建vue-cli项目
创建命令:vue init webpack projectName
Webpack:创建项目的模板
projectName:创建vue-cli项目的项目名.
创建过程中的配置
下图所示的两个配置我们需要注意,其他的配置采取默认即可.
如果在执行vue init webpack projectName
创建指令时失败,可以在此文件夹下重新运行安装vue-cli的语句.
创建过程参数说明:
Project name :项目名称----不能有大写字母
Project description:项目描述
Author:作者
Vue build:如何构建项目
Install vue-router:是否安装路由
Use ESLint to lint your code:是否使用ESLint来规范我们的代码
Pick an ESLint preset:选择一个ESLint代码规范
Set up unit tests:是否需要自动化单元测试
Setup e2e tests with Nightwatch:是否需要自动化用户界面测试
Should we run ‘npm install’ for your after the project has been created?(recommend):在后续安装依赖包是是否使用npm install安装
安装完成之后显示: Project initialization finished
接下来,根据提示,输入命令来启动项目
启动项目
项目启动成功之后显示:
我们在浏览器端输入
链接: http://localhost:8080
便可以访问vue-cli脚手架.
至此,我们已经成功在本地创建了一个vue-cli脚手架.
使用vue-cli开发
项目结构说明
脚手架结构如图所示:
项目主结构文件说明
build:项目webpack配置文件
config:针对开发环境和线上环境的配置文件
node_modules:项目依赖包
src:源代码目录
static:静态资源
.babelrc:JavaScript 语法的编译器
.editorconfig:针对babel的编译,浏览器配置
.eslintignore:针对babel的编译,eslint检测规则配置
.eslintrc.js:针对babel的编译,eslint检测规则配置
.gitignore:git 配置文件
.postcssrc.js:转换成css格式的插件
index.html:整个项目的入口index页,包含根实例的挂载点
package.json:定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)
package-lock.json:其实package-lock就是锁定安装时的包版本号,需要上传到git上,以保证其他人在install时候,大家的依赖版本相同
node_modules
通过npm install安装的依赖代码库.
src目录文件
存放项目源码,开发的所有源码均放在此目录下
main.js:整个项目入口文件
el:#app
创建了一个vue的实例app让其挂载在index.html的id=app的节点上
components: { App }
注册局部组件APP,APP来源:import App from ‘./App’,即引入当前目录下的APP.vue组件
template: ‘’
定义模板为APP组件的内容,即main中创建vue实例展示的就是APP.vue组件中的内容
APP.vue:
单文件组件,包含三部分
第一部分:<template>
模板部分
第二部分:<script>
逻辑部分
第三部分:<style>
样式部分
static文件目录
存放第三方静态资源.
.gitkeep
这是一个空文件,此文件的作用是:
即使创建的空文件,在将项目提交到getHub上时,也会被提交.
地址栏网址
去除地址栏”#”
在路由管理(index.js)中,进行如下图所示修改.
修改访问地址根目录
显示效果
组件安装与卸载
安装
以安装与卸载eslint组件为例.
打开命令行工具,切换到vue-cli项目目录下(可以看到vue-cli整个的项目结构).
生产环境
成功之后,在package.json文件中的指点位置出现eslint组件的依赖.
开发环境
卸载
生产环境
开发环境
如何导入vue-cli项目
Dos命令行
将vue-cli项目放到磁盘的某个目录下,在dos中切换到该目录下,输入如图所示的命令进行安装,待安装完成后便可以启动.
按照如下图所示的命令启动.
使用编辑软件
直接在编辑软件中导入.
使用Vue-cli—知识点
Router路由
Router实现页面跳转
实现有first页面跳转到A页面和B页面.
<router-link to="跳转路径">… </router-link>
:表示路径跳转
创建first页面
<template>
<div>
<router-link to="/A">跳转到A页面</router-link>
<router-link to="/B">跳转到B页面</router-link>
<router-view></router-view>
<br/>
</div>
</template>
<script>
</script>
<style>
</style>
创建A页面
<template>
<div>
A页面...
<br/>
<router-link to="/">返回首页</router-link>
</div>
</template>
<script>
</script>
<style>
</style>
创建B页面
<template>
<div>
b页面...
<br/>
<router-link to="/">返回</router-link>
</div>
</template>
<script>
</script>
<style>
</style>
在路由管理页面添加路由
注意:
在添加路由时,首先要在路由管理界面引入该vue组件(页面)
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import First from '@/components/First'
import A from '@/components/A'
import B from '@/components/B'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'First',
component: First
},
{
path: '/A',
name: 'A',
component: A
},
{
path: '/B',
name: 'B',
component: B
}
]
})
Router实现父-子路由(组件之间存在父子关系)
此种路由管理方式,当从父页面跳转到子页面时,子页面会显示父页面和子页面的内容
添加A页面的子页面
<template>
<div>
A页面的子页面A1页面
<br/>
<router-link to="/A">返回上一级</router-link>
<br/>
<router-link to="/">返回首页</router-link>
</div>
</template>
<script>
</script>
<style>
</style>
修改A页面
<router-view></router-view>
:表示将子页面挂载到此页面.如果在父页面中不添加这个标签,则无法实现跳转到子页面,即路由管理采用子路由方式无效.
<template>
<div>
A页面...
<br/>
<router-link to="/A1">A1页面</router-link>
<br/>
<router-link to="/">返回首页</router-link>
<router-view></router-view>
</div>
</template>
<script>
</script>
<style>
</style>
添加路由管理
在A页面的路由管理中添加跳转到子页面的路由.
删除掉A页面的标签
{
path: '/A',
name: 'A',
component: A,
children:[
{
path:'/A1',
name:'A1',
component:A1
}
]
},
Router实现平级路由(组件之间是平级关系)
两个组件之间的路由管理是平级关系,此种路由管理方式下,当从A组件到A1组件时,A1组件的页面不再显示A组件的内容.
修改路由管理
是A组件和A1组件的路由在路由管理中以平级关系呈现.
修改A页面
此种情况下,不再需要在A页面挂载A1页面
Router路由管理实现首页
即将所有页面路由管理以首页面路由的子路由的方式管理.
注意:
如果路由管理以父-子路由的方式进行管理,那么一定要在父组件中添加
<router-view></router-view>
标签,否则路由无效.
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import First from '@/components/First'
import A from '@/components/A'
import B from '@/components/B'
import A1 from '@/components/A1'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'First',
component: First,
children:[
{
path: '/A',
name: 'A',
component: A,
},
{
path:'/A1',
name:'A1',
component:A1
},
{
path: '/B',
name: 'B',
component: B
}
]
},
]
})
自定义组件与组件通信
自定义组件
Parent组件
<template>
<div>
</div>
</template>
<script>
export default{
name:'Parent',
data(){
return{
}
}
}
</script>
<style>
</style>
Child组件
<template>
<div>
</div>
</template>
<script>
export default{
name:'Child',
data(){
return{
}
}
}
</script>
<style>
</style>
添加路由
// 引入组件
import Parent from '@/components/StudyComponent/Parent'
import Child from '@/components/StudyComponent/Child'
// 添加路由
{
path:'/Parent',
name:'Parent',
component:Parent
},
{
path:'/Child',
name:'Child',
component:Parent
}
父组件与子组件通信
父组件中引用子组件
父组件中注册子组件
运用自定义标签传递数据
子组件中注册父组件传递的参数
子组件引用该参数
传递数据类型
父子组件之间传递的可以是基本类型,对象类型,数组.
具体代码如下:
父组件:
<template>
<div>
<child text="父子组件"></child>
<!-- 传递纯数字-->
<child :number="1"></child>
<!-- 传递变量-->
<child :message="msg"></child>
<!-- 传递对象-->
<child :obj="obj"></child>
<!-- 传递数组-->
<child :arr="arr"></child>
</div>
</template>
<script>
import Child from './Child'
export default{
name:'Parent',
components:{
Child
},
data(){
return{
msg:'中华人名共和国',
obj:{
name:'zcc',
sex:'男',
age:'22岁'
},
arr:[
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
]
}
}
}
</script>
<style>
</style>
子组件
<template>
<div>
<p>{{text}}</p>
<p>{{number}}{{number}}</p>
<p>{{message}}</p>
<!-- 遍历对象-->
<ol>
<li v-for="(keyName,value,index) of obj" :key=index>{{keyName}}:{{value}}</li>
</ol>
<ul>
<li v-for="(item,index) of arr" :key=index>{{item.name}}----{{item.sex}}----{{item.age}}</li>
</ul>
</div>
</template>
<script>
export default{
name:'Child',
props:['text','number','message','obj','arr'],
data(){
return{
}
}
}
</script>
<style>
</style>
数据校验:
<template>
<div>
<div>
</div>
<div>
<p>{{number}}{{number}}</p>
<p>{{message}}</p>
<!-- 遍历对象-->
<ol>
<li v-for="(keyName,value,index) of obj" :key=index>{{keyName}}:{{value}}</li>
</ol>
<ul>
<li v-for="(item,index) of arr" :key=index>{{item.name}}----{{item.sex}}----{{item.age}}</li>
</ul>
</div>
</div>
</template>
<script>
export default{
name:'Child',
// props:['text','number','message','obj','arr'],
props:{
text:{
type:String,
// required:true,
default:"默认值"
},
number:{
type:Number,
validator(val){
return val>100
}
},
message:{
type:String
},
obj:{
type:Object
},
arr:{
type:Array
},
},
data(){
return{
txt:this.text
}
}
}
</script>
<style>
</style>
注意点:
==在传递纯数字时,属性参数应使用绑定方式.
动态传参时,属性也需要绑定方式
在父组件中不要重复使用子组件的标签,不然显示页面元素会重复
子组件与父组件通信
方式一
Parent.vue
<template>
<div>
<!-- 传递纯数字-->
<!-- <child :number="111"></child> -->
<!-- 传递变量-->
<child
:number="111"
:message="msg"
:obj="obj"
:arr="arr"
@on-callback="changeData"
>
</child>
<!-- 传递对象-->
<!-- <child :obj="obj"></child> -->
<!-- 传递数组-->
<!-- <child :arr="arr"></child> -->
</div>
</template>
<script>
import Child from './Child'
export default{
name:'Parent',
components:{
Child
},
data(){
return{
msg:'中华人名共和国',
obj:{
name:'zcc',
sex:'男',
age:'22岁'
},
arr:[
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
]
}
},
methods:{
changeData(val){
this.msg=val
}
}
}
</script>
<style>
</style>
Child.vue
<template>
<div>
<div>
<input type="text" v-model="val"/>
<input type="submit" @click="submit" value="提交" />
<p>{{message}}</p>
</div>
<div>
<p>{{number}}{{number}}</p>
</div>
<div>
<div>
<!-- 遍历对象-->
<ol>
<li v-for="(itemKey,item,index) of obj" :key="index">{{itemKey}}:{{item}}</li>
</ol>
</div>
<div>
<ul>
<li v-for="(item,index) of arr" :key="index">{{item.name}}----{{item.sex}}----{{item.age}}</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Child',
props:['text','number','message','obj','arr'],
/* props: {
text: {
type: String,
// required:true,
// default:"默认值"
},
number: {
type: Number,
validator(val) {
return val > 100
}
},
message: {
type: String
},
obj: {
type: Object
},
arr: {
type: Array
},
}, */
data() {
return {
txt: this.text,
val:this.message
}
},
methods:{
submit(){
this.$emit('on-callback',this.val)
}
}
}
</script>
<style>
</style>
方式二
Child.vue
<template>
<div>
<div>
<input type="text" v-model="val"/>
<input type="submit" @click="submit" value="提交" />
</div>
<div>
<p>{{number}}{{number}}</p>
</div>
<div>
<div>
<!-- 遍历对象-->
<ol>
<li v-for="(itemKey,item,index) of obj" :key="index">{{itemKey}}:{{item}}</li>
</ol>
</div>
<div>
<ul>
<li v-for="(item,index) of arr" :key="index">{{item.name}}----{{item.sex}}----{{item.age}}</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Child',
// props:['text','number','message','obj','arr'],
props: {
text: {
type: String,
// required:true,
// default:"默认值"
},
number: {
type: Number,
validator(val) {
return val > 100
}
},
message: {
type: String
},
obj: {
type: Object
},
arr: {
type: Array
},
info:{
type:String
}
},
model:{
prop:'info',
event:'on-callback'
},
data() {
return {
txt: this.text,
val:this.info
}
},
methods:{
submit(){
this.$emit('on-callback',this.val)
}
}
}
</script>
<style>
</style>
Parent.vue
<template>
<div>
<!-- 传递纯数字-->
<!-- <child :number="111"></child> -->
<!-- 传递变量-->
<child
:number="111"
:message="msg"
:obj="obj"
:arr="arr"
v-model="info"
>
</child>
<!-- 传递对象-->
<!-- <child :obj="obj"></child> -->
<!-- 传递数组-->
<!-- <child :arr="arr"></child> -->
<p>{{info}}</p>
</div>
</template>
<script>
import Child from './Child'
export default{
name:'Parent',
components:{
Child
},
data(){
return{
msg:'中华人名共和国',
info:'子父组件信息传递,数据实时绑定',
obj:{
name:'zcc',
sex:'男',
age:'22岁'
},
arr:[
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
{
name:'zcc',
sex:'男',
age:'22岁'
},
]
}
},
methods:{
/* changeData(val){
this.msg=val
} */
}
}
</script>
<style>
</style>
时间格式化
自定义js格式化文件
data.js
export function formatDate (date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + ''
fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str))
}
}
return fmt
}
function padLeftZero (str) {
return ('00' + str).substr(str.length)
}
使用
在页面引入
由于在date.js
中使用export
,所以此处导入需要使用{}
页面使用
页面代码
<template>
<tbody>
<tr v-for="(item,index) of personArr" v-bind:key="index">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.sex==0?'男':'女'}}</td>
<td>{{formatDate(item.birthday)}}</td>
<td>{{item.age}}</td>
<td></td>
</tr>
</tbody>
</template>
<script>
import {formatDate} from '@/assets/js/date.js'
export default{
name:'Child',
props:{
personArr:{
type:Array,A
}
},
data(){
return {
}
},
methods:{
formatDate:function(time){
const date=new Date(time)
return formatDate(date,'yyyy-MM-dd')
}
}
}
</script>
<style>
#parent{
text-align: center;
}
</style>