Vue-cli启动第一个项目
1.安装VSCode
2.电脑安装node.js
3 .安装vue-cli脚手架
之前代码都写在一个.vue文件中,但真实情况不是这样
真实的vue项目开发中,一般会借助webpack打包工具,帮助我们构建大型项目的开发目录,在开发完成后,会进行打包操作,帮助我们把代码打包生成一个线上可运行的最终代码, 若每个人都自己打包,那么太难了
vue官方提供了脚手架工具Vue-cli
通过这个脚手架,可以快速构建一个标准的vue项目,同时,这个脚手架工具中自带webpack的各种配置
按照官网教程,打开命令行
1.全局安装 vue-cli工具(只需要安装一次即可,后续创建项目不用反复安装)
node -v 出现版本号
npm -v 出现版本号
以上两个说明电脑上已经正确安装了node和npm,如果上面两个没有版本号,需要先安装它们
npm install --global vue-cli
2.在桌面上创建一个基于webpack模板的新项目,项目名叫my-project,当出现项目名字时一直回车选择默认选项即可
cd Desktop
vue init webpack my-project
3.启动项目,就可以看到vue默认的启动页面
下面两个命令都会帮我们启动一个本地服务器来运行我们的代码
npm run dev
或
npm run start
项目结构介绍
build: 项目的webpack配置文件,一般不动
config: 针对于开发环境和线上环境的一些配置文件,一般不动
node_modules: 项目依赖
static: 静态资源
index.html: 是整个网页最外层的html文件,可以看到有个id="app"的挂载点,vue的根实例就挂载到这个挂载点上
src: 源代码目录,代码写在这里
'下面看下src里面的内容'
'main.js文件: 整个项目的入口文件'
创建了Vue实例,看下实例做了什么
1. 让Vue实例的挂载点是'#app',就挂到了index.html的id="app"上
2. router是干嘛的?
3. 注册了一个局部组件App,可以看到有import App from './App',是从当前目录下的App引入的组件, 指得是src下的App.vue
4. 它的模板就是App这个组件的内容
所以,这个Vue实例,展示的内容,就是在这里注册进来的App组件
根实例Vue里面展示的是从外部引入的根组件App
下面看下main.js的代码
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/>'
})
.vue文件:单文件组件编码形式
也就是说,一个组件是一个.vue后缀文件所定义的,在这个文件中,包含了组件的所有内容,包括它的模板,逻辑和样式
一个.vue文件就是一个完整的组件
'App.vue文件: 根组件'
可以看到全新的跟html不一样的页面
是脚手架工具提供给我们一套新的vue编码语法
这种语法叫做单文件组件,也就是说一个vue文件中,包含了一个组件必须的全部内容
有以下三个部分
1. template: 组件的模板,展示部分,这个模板下只能有一个最外层的根标签,不能并列多个
2. script: 组件的逻辑部分,里面有data函数,它的返回值对应着数据
3. style: 组件的样式部分,为模板做美化
如果把App.vue改成以下内容,那么运行如下图,之所以一运行就显示,是因为主入口根Vue里面显示的就是App组件
而App模板里是123,那么页面上就会显示123
<template>
<div>123</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
vue第一个demo:在input中输入内容,点击提交后,自动显示到下面的list上,并且input自动置空
实现代码如下:
在TodoList组件中实现
this指向当前组件
<template>
<div>
<input v-model="inputValue"/>
<button @click="handleSubmit">提交</button>
<ul v-for="(item, index) of list" :key="index">{{item}}</ul>
</div>
</template>
<script>
export default {
data() {
return {
inputValue: '',
list: []
}
},
methods: {
handleSubmit() {
this.list.push(this.inputValue)
this.inputValue = ''
}
}
}
</script>
对上面的demo进行组件拆分和组件通信
组件: 就是指页面上的某一部分
可以把一个大型网页拆成几个部分,每个部分就是一个小的组件,维护每个组件则相对简单很多
将上面demo中的list拆分成一个组件
1.在src的components下新建TodoItem.vue文件,这就是TodoItem组件
2.在TodoList中使用TodoItem组件
-首先在TodoList的script中导入这个组件
-通过components对局部组件进行声明,可以声明为一个对象,例如例子中我们命名为todo-item
意思是在当前的组件模板中,我们通过todo-item这个标签来使用TodoItem组件
以上两步就是把局部组件注册到当前组件中,就可以在上面的ul里面使用这个局部组件了
组件传值:在TodoList组件中使用子组件TodoItem
- 父组件向子组件传值: 父组件通过属性的形式向子组件传值
- 子组件接收值: 子组件中要在script的export default里的props里面对接收的数据进行一个定义,例如子组件要接收content这个数据,就要在子组件的props里声明对content的使用,声明好之后,就可以直接在子组件的template中使用content
- 子组件和父组件通信: 调用this.$emit()方法,向外触发一些事件,将事件名字和下标写在参数里带到父组件中去,事件名是自己定义的
Demo2:在Demo1的基础上,点击列表项,则将此列删除
删除:把index也传给子组件,当子组件被点击时,执行子组件的handleDelete方法,在这里和父组件通信,告诉父组件我要被删除了,将父组件带来的下标传回给父组件
子组件触发了事件出去,父组件就需要在创建子组件的时候,监听这个事件
@delete="handleDelete",意思是一旦监听到delete事件被触发,就会执行handleDelete这个方法 ,删除当前行list即可
代码如下:
'TodoItem组件'
<template>
<li @click="handleDelete">{{content}}</li>
</template>
<script>
export default {
props: ['content', 'index'],
methods: {
handleDelete() {
this.$emit('delete', this.index)
}
}
};
</script>
'TodoList组件'
<template>
<div>
<input v-model="inputValue"/>
<button @click="handleSubmit">提交</button>
<ul>
<todo-item
v-for="(item, index) of list"
:key="index"
:content="item"
:index="index"
@delete="handleDelete"
>
</todo-item>
</ul>
</div>
</template>
<script>
import TodoItem from './components/TodoItem'
export default {
components: {
'todo-item': TodoItem
},
data() {
return {
inputValue: '',
list: []
}
},
methods: {
handleSubmit() {
this.list.push(this.inputValue)
this.inputValue = ''
},
handleDelete(index) {
this.list.splice(index,1)
}
}
}
</script>
全局样式和局部样式
当我们使用vue-cli的时候,每个组件都变成一个单文件组件,在这个文件中,可以对组件的模板,逻辑和样式进行定义,而定义样式时,可以分为全局样式和局部样式
style的scoped代表作用域
加scoped,代表样式只对当前组件有效
不加scoped,代表样式全局生效
Demo3:给Demo2的每个列表项加颜色
也就是给TodoItem加颜色
1. 在TodoItem中的template中,class="自己随便起个名字,例如叫做xixi"
2. 在TodoItem中的style中,定义一个叫做xixi的类,给它添加颜色
其中style的scoped意思是给这个样式增加一个作用域,作用域就是这个组件中,若其他组件使用xixi这个类,也不会改变颜色
若不写scoped,那么不论哪个组件,用到xixix这个类,则样式都会被影响
<template>
<li class="xixi" @click="handleDelete">{{content}}</li>
</template>
<script>
export default {
props: ['content', 'index'],
methods: {
handleDelete() {
this.$emit('delete', this.index)
}
}
};
</script>
<style scoped>
.xixi {
color: green
}
</style>>