一、安装Vue和Vite
Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。通
过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。vite中文官
网: https://vitejs.cn/guide/#trying-vite-online 使用 npm:
1 创建文件夹
2 右键打开终端/点进去文件夹里面输入cmd
3 输入命令: npm init vite@latest my-vue-app 。my-vue-app 是项目名,自定义就可以
4 选择Vue JavasSript
5 输入命令:cd my-vue-app。意是进入该项目
6 把项目拖进vscode
7 输入命令:npm itstall
7 在vscode新建终端,输入命令:npm run dev
结构如下:
public目录: 该目录存放了一个html文件,用于挂载vue根组件。整个项目所有的组件都是渲染到一个html
文件(所以叫单页应用)
src目录:vue项目的工作目录,主要编写实现项目功能的各类代码。
assets目录: 静态文件的存放目录(主要是图片)
components: 存放自定义的组件
app.vue 根组件
main.js vue的项目的入口文件,实例化Vue,注册根组件的位置
.gitignore github仓库不提交的文件的配置文件
babel.config.js babel的配置文件
package.json npm的配置相关
README.md 项目的说明文件(是一个markdown文件)
二、根组件
vue 的单文件组件(又叫: *.vue文件,简称SFC)。是一种特殊的vue的文件格式,它允许将vue组件的模板,逻辑与样式封装在当文件中
组件的js逻辑代码,除了template属性以为的所有组件的属性都是写在该标签里面
script部分
<script>
// 1. 需要用es6的模块语法导出vue的组件配置
import ShowMessage from "./components/showMessage.vue" // 引入自定义组件
import TestChild from "./components/testChild.vue"
export default {
name:"com1", // 给组件取别名,一般不会用到该属性
data(){
return {
count: 0,
show: true
}
},
// 2. 注册局部组件
components:{ x
'show-message':ShowMessage,
'test-child':TestChild
},
methods:{
add(){
this.count++
// 获取到ref=div1的元素dom对象,没有特殊需求不建议通过ref操作dom
console.log(this.$refs.div1)
this.$refs.div1.innerHTML='hello ref div'
},
// 父组件获取子组件的值需要通过事件的参数获取
getChildProp(value){
console.log(value)
},
// 把getChildProp通过props属性传值给子组件,再子组件调用该函数并传值
getChildProp1(value){
console.log(value)
},
}
}
</script>
template部分
template是vue组件的html模板,就是组件的ui界面。
一个组件只有一个顶层的template,里面可以包含多个template标签。
<template>
<div>
计数:{{count }}
<button class="btn" @click="add">增加count</button>
</div>
<!-- ref属性,vue会把ref属性值收集到$refs属性里面,通过ref属性可以获取到对应dom的原生对象 -->
<div class="box" ref="div1">box1</div>
<button @click="show=false">隐藏子组件</button>
<!-- 使用注册的自定义组件 -->
<show-message title="自定义组件01" :count="count" v-if="show">
<!-- template 内容插入到name='header'的slot位置 -->
<!-- ctx1是slot插槽属性的集合(就是一个对象,如果slot='header'的插槽有data1属性和age属性) -->
<template v-slot:header="ctx1"><h3>header slot</h3><p>slot的属性{{ctx1.data1 }} {{ctx1}}</p></
<!-- 可以用#代替v-slot -->
<template #footer><h3>footer slot</h3></template>
<!-- 把template包裹内容插入到默认的slot位置 -->
<template v-slot:default>
<div><span>slot1插槽</span></div>
</template>
</show-message>
<!-- 子组件传值给父组件方法1:test-child子组件自定义的childEvent事件,需要在子组件里面通过$emit触发该事件 -->
<!-- 子组件传值给父组件方法2:通过props传函数的方式带值,比$emit更简洁 -->
<test-child :handleGet="getChildProp1" @childEvent="getChildProp" />
</template>
style部分
1.style标签可以写入css样式,scoped表示样式是局部样式,只能在该组件使用~~
- 如果不加scoped则是全局样式,其他组件也可以使用该样式
- 可以有style标签
- 可以通过src属性引入外部的css样式
- 如果要使用sass需要添加lang=‘scss’,并且要安装sass包 cnpm i sass -D
<style lang="scss" scoped>
$red:red;
.btn{
color: $red;
background-color: green;
}
</style>
<style src="./app.css"></style> // 另一个页面的css
三、子组件
export default 导出默认页面,这里是ES6的导出模式
<script>
export default {
props:{
title:String,
count:Number
},
data(){
return {
msg: "hello component01",
data1: "data1 test"
}
},
// 组件的生命周期函数和指令的是一致的(钩子函数),需要的时候才写上,不需要就不写
// 1. 组件开始创建前触发,只触发一次(还没渲染到页面)
beforeCreate(){
console.log("beforeCreate")
},
// 2. 组件创建完成,只触发一次(还没渲染到页面)
created(){
console.log("created")
},
// 3. 开始第一次挂载到真实dom上,触发一次(准备开始渲染到页面)
beforeMount(){
console.log("beforeMount")
},
// 4. 第一次渲染到页面,触发一次
mounted(){
console.log("mounted")
},
// 5. 每次更新组件前触发
beforeUpdate(){
console.log("beforeUpdate")
},
// 6. 更新组件完成触发
updated(){
console.log("updated")
},
// 7. 组件销毁之前触发
beforeUnmount(){
console.log("beforeUnmount")
},
// 8. 组件销毁完成
unmounted(){
console.log("unmounted")
}
}
</script>
<template>
<!-- 插槽可以绑定state状态等数据 -->
<slot name="header" :data1="data1" age="23"></slot>
<h2 class="h2">{{msg}}{{ count }}</h2>
<!-- 插槽slot 使用组件的时候可以向组件指定位置(<slot>标签位置)插入html元素 -->
<!-- 1. 匿名插槽,把tempalte的内容插入该位置,需要指定v-slot:default -->
<slot></slot>
<div>{{title}}</div>
<!-- 2. 具名插槽: 可以给slot取名称。当有多个template的时候需要添加name属性加以区分 -->
<slot name="footer"></slot>
<slot name="test1"></slot>
</template>
<style scoped>
.h2{
color: gray;
}
</style>
四、插槽
插槽slot 使用组件的时候可以向组件指定位置(标签位置)插入html元素
1 匿名插槽:
子组件
<template>
<!-- 插槽可以绑定state状态等数据 -->
<slot name="header" :data1="data1" age="23"></slot>
<h2 class="h2">{{msg}}{{ count }}</h2>
<!-- 插槽slot 使用组件的时候可以向组件指定位置(<slot>标签位置)插入html元素 -->
<!-- 1. 匿名插槽,把tempalte的内容插入该位置,需要指定v-slot:default -->
<slot></slot>
<div>{{title}}</div>
</template>
父组件:
<!-- 可以用#代替v-slot -->
<template #footer><h3>footer slot</h3></template>
<!-- 把template包裹内容插入到默认的slot位置 -->
<template v-slot:default>
<div><span>slot1插槽</span></div>
</template>
2 具名插槽
子组件
<!-- 2. 具名插槽: 可以给slot取名称。当有多个template的时候需要添加name属性加以区分 -->
<slot name="footer"></slot>
<slot name="test1"></slot>
父组件
<!-- template 内容插入到name='header'的slot位置 -->
<!-- ctx1是slot插槽属性的集合(就是一个对象,如果slot='header'的插槽有data1属性和age属性) -->
<template v-slot:header="ctx1"><h3>header slot</h3><p>slot的属性{{ctx1.data1 }}{{ctx1}}<</p></templat
<!-- 可以用#代替v-slot -->
<template #footer><h3>footer slot</h3></template>
四、子组件传值给父组件
1 通过props传函数的方式带值,比$emit更简洁
子组件
export default{
// 1.定义属性
props:["handleGet"],
}
// 2.监听点击事件,并且传值
<button @click="handleGet({name:'test3',age:22})">点击事件2</button>
父组件
// 4.自定义方法,获取子组件传来的值
methods:{
getChildProp1(value) {
console.log(value);
}
},
// 3.绑定动态属性
<test-child :handleGet="getChildProp"/>
2.test-child子组件自定义的childEvent事件,需要在子组件里面通过$emit触发该事件
子组件
export default{
methods:{
// 1.自定义方法
sendEvent(){
//2.触发childEvent事件,并传递参数(参数可以是任意数据类)
this.$emit('childEvent',{name:"test2"})
}
}
}
// 3.绑定自定义的函数
<button @click="sendEvent">点击事件1</button>
父组件
// 5.自定义方法获取子组件传来的值
methods:{
getChildProp1(value) {
console.log(value);
}
},
// 4.侦听事件
<test-child @childEvent="getChildProp1" />