cli是什么?
cli是vue提供的一个快速(自动化) 构建项目的一个脚手架 ,类似于我们之前所学的 express-generator
cli的版本
目前最新 3.x
老版本是 2.x
cli的底层的自动化工具是: webpack
cli的安装
npm/cnpm/yarn 都可以使用
$ yarn add @vue/cli global
这个是cli3的版本$ yarn add @vue/cli-init global
如果安装3失败了,
那么你可以使用cnpm继续安装 @vue/cli @vue/cli-init
1. $ cnpm i @vue/cli -g
这个是cli3的版本
如果我们还想使用cli2的脚手架,那么我们可以在安装一个包
1. $ cnpm i @vue/cli-init -g
如果还有问题:
那么你就不要使用cli3了,你可以单独安装cli2
`$ cnpm i vue-cli -g`
验证是否安装成功
命令行输入: $ vue
看是否有东西输出,如果输出命令提示,证明安装成功
创建项目
cli3版本创建
1. 命令创建 【 推荐 】
$ vue create project
- 手动选择配置
- 如果安装node-sass出问题,如何解决:
- 先切换成npm源 nrm use npm
- 使用cnpm 安装 cnpm i node-sass sass-loader -D
2. 图形界面创建
`$ vue ui`
cli2
1. 标准版
$ vue init webpack project
$ vue init webpack-simple project
总结:
cli3 的 webpack 配置放在了node_modules 的 @vue/cli-server 中
cli2 的配置
standard build目录中
simple webpack.config.js
问题: 如果我们在cli3中要进行webpack配置,怎么办?
分析: cli3的基础webpack 配置我们不要动 , 将来node_modules会被删除
解决: 新建一个vue.config.js文件进行webpack的覆盖配置
注意:template是必须有的,script和style可以没有
单文件组件: 一个组件就是一个文件
.vue 文件命名要使用大驼峰 【推荐】 或是 - 的形式
举例:
Father
movie-box
ContentBox MovieBox
要想在编辑器中 .vue 文件代码高亮 , 安装Vetur插件
单文件组件使用:
1. 先创建.vue文件
2. 想在哪里使用就在哪里导入
import xxx from xxx
3. 在当前组件中注册导入的组件
export default {
components: {
xxx
}
}
【HMR】 热重载: 文件修改,浏览器自动刷新
scoped 将当前组件的样式设立独立作用域,只在当前组件中有效
AddInput.vue代码
<template>
<div class="add-input">
<input type="text" v-model = "val"
@keyup.enter = "addItem"
@focus = "getFocus"
>
</div>
</template>
<script>
export default {
data () {
return {
val: '请输入'
}
},
props: ['add'],
methods: {
getFocus () {
this.val = ''
},
addItem () {
this.add( this.val )
this.val = ''
this.$emit('addflag')
}
}
}
</script>
<style scoped>
.add-input{
position: relative;
left: 0;top: 44px;
z-index: 1000000;
}
</style>
Content.vue 代码
<template>
<!-- content -- start -->
<div class="content">
<div
class="card"
v-for = " (todo,index) in newtodos "
:key = " todo.id "
>
<div class="card-content">
<div class="card-content-inner" > {{ todo.task }} </div>
<div class="my-btn-box pull-right">
<button
class="button button-success"
@click = " todo.flag = !todo.flag "
:class = "[ todo.flag?'button-fill':'']"
>
<i class="icon icon-check"></i>
</button>
<button
class="button button-danger"
@click = 'checkItem( index )'
>
<i class="icon icon-remove"></i>
</button>
</div>
</div>
</div>
</div>
<!-- content -- end -->
</template>
<script>
export default {
props: ['newtodos'],
methods: {
removeItem ( index ) {
this.$emit('remove',index)
},
checkItem ( index ){
this.$emit('check',index)
}
}
}
</script>
Foot.vue代码
<template>
<footer>
<ul>
<li
v-for = "btn in btns "
:key = "btn.id"
class="circle"
:class = "['circle-'+btn.mold,type === btn.name?'circle-fill':'']"
@click = "change( btn.name )"
>
{{ btn.content }}
</li>
</ul>
</footer>
</template>
<script>
export default {
props: ['btns','type'],
methods: {
change ( val ) {
this.$emit('changetype',val)
}
}
}
</script>
Head.vue代码
<template>
<!-- header -- start -->
<header class="bar bar-nav">
<a class="icon icon-star pull-left"></a>
<a class="icon icon-edit pull-right" @click = 'edit'></a>
<h1 class="title"> Todo_List </h1>
</header>
<!-- header -- end -->
</template>
<script>
export default {
methods: {
edit () {
this.$emit('edit')
}
}
}
</script>
LayOut.vue 代码
<template>
<div class="page-group">
<div class="page page-current">
<Head @edit = "editChange"></Head>
<add-input
v-if = "add_todo_flag"
:add = "addTodoItem"
@addflag = "editChange"
></add-input>
<Content
:newtodos = 'newTodos'
@remove = 'remove'
@check = 'check'
></Content>
<mask-component
v-show = "mask_flag"
@mask = "maskHandler"
@remove = "remove"
:active-index = 'active_index'
></mask-component>
<Foot
:btns = 'btns'
:type = 'type'
@changetype = 'changeType'
></Foot>
</div>
</div>
</template>
<script>
import Head from './Head'
import Content from './Content'
import Foot from './Foot'
import MaskComponent from './MaskComponent'
import AddInput from './AddInput.vue'
export default {
components: {
Head,Content,Foot,MaskComponent,AddInput // 大部分人都会忘记
},
data () {
return {
todos: [
{
id: 1,
task: '做作业',
flag: true
},
{
id: 2,
task: '打游戏',
flag: true
},
{
id: 3,
task: '化妆',
flag: true
}
],
add_todo_flag: false, //编辑按钮的开关
add_todo_input: '请输入代办任务',// 这个数据就是编辑添加的 input 的value
mask_flag: false, //遮罩层控制开关
active_index: 0 ,//保存index,在mask点击确定按钮的时候使用
btns: [
{
id: 1,
content: 'A', // all 全部的任务
name: 'all',
mold: 'success' //类型
},
{
id: 2,
content: 'F', //finish 完成了的任务
name: 'finish',
mold: 'primary'
},
{
id: 3,
content: 'U', //unFinish 未完成的任务
name: 'unfinish',
mold: 'warning'
}
],
type: 'all'
}
},
methods: {
changeType ( type ) {
this.type = type
},
maskHandler () {
this.mask_flag = false
},
editChange() {
this.add_todo_flag = !this.add_todo_flag
},
check ( index ) {
this.active_index = index
if( this.todos[index].flag){
this.remove( index )
}else{
this.mask_flag = true
}
},
remove ( index ) {
this.todos.splice( index,1 )
},
addTodoItem ( value ) {
console.log( 'yyb add ' )
this.todos.push({
id: this.todos.length + 1,
task: value,
flag: true
})
},
getFocus () {
this.add_todo_input = ''
}
},
computed: {
allTodos () {
return this.todos
},
finishTodos () {
//已经完成的任务
// for some filter map forEach every
return this.todos.filter( item => {
return item.flag && item
})
},
unFinishTodos () {
//已经完成的任务
// for some filter map forEach every
return this.todos.filter( item => {
return !item.flag && item
})
},
newTodos () {
switch ( this.type ) {
case 'all':
return this.allTodos
break;
case 'finish':
return this.finishTodos
break;
case 'unfinish':
return this.unFinishTodos
break;
default:
break;
}
}
}
}
</script>
MaskComponent.vue代码
<template>
<!-- mask -- start -->
<div class="mask-box"
@click = "maskHandler"
>
<div class="mask-box-bg"></div>
<div class="card">
<div class="card-content">
<b class="card-content-inner"> 您确定要删除吗? </b>
<div class="my-btn-box pull-right">
<button
class="button button-warning button-fill"
@click = "removeItem( activeIndex )"
>
确定
</button>
</div>
</div>
</div>
</div>
<!-- mask -- end -->
</template>
<script>
export default {
props: ['activeIndex'],
methods: {
maskHandler () {
this.$emit('mask')
},
removeItem () {
this.$emit('remove')
}
}
}
</script>
<style scoped>
.mask-box{
width: 100%;
height: 100%;
position: fixed;
left: 0; top: 0;
z-index: 10000;
}
.mask-box-bg{
width: 100%;
height: 100%;
position: absolute;
left: 0; top: 0;
background: #000;
opacity: .5;
}
.mask-box .card{
width: 80%;
height: 100px;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
border-radius: 10px;
}
.mask-box button{
width: 100px;
height: 25px;
}
.mask-box b{
display: block;
}
</style>
App.vue代码
<template>
<div id="app">
<lay-out></lay-out>
</div>
</template>
<script>
import LayOut from './components/LayOut'
export default {
name: 'app',
components: {
LayOut
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-top: 60px;
}
*{
list-style: none;
padding: 0;margin: 0;
}
.my-btn-box{
display: flex;
padding: 10px;
}
.my-btn-box button{
margin-left: 10px;
}
.card{
overflow: hidden;
}
footer{
position: fixed;
left: 0;
bottom: 10px;
width: 100%;
height: 80px;
}
footer ul{
width: 100%;height: 100%;
display: flex;
justify-content: space-around;
}
footer li{
width: 80px;
height: 80px;
border-radius: 50%;
}
footer li.circle{
text-align: center;
line-height: 80px;
}
footer li.circle.circle-success{
border: 1px solid #006400;
color: #006400;
}
footer li.circle.circle-success.circle-fill{
background: #006400;
color: white;
}
footer li.circle.circle-primary{
border: 1px solid #00008B;
color: #00008B;
}
footer li.circle.circle-primary.circle-fill{
background: #00008B;
color: white;
}
footer li.circle.circle-warning{
border: 1px solid #FFA500;
color: #FFA500;
}
footer li.circle.circle-warning.circle-fill{
background: #FFA500;
color: white;
}
</style>