Vue.js (包含2.x和3.x) 总结03 (项目创建 / 启动、组件、组件传值)
目录
1.安装vue-cli
2.创建项目
3.启动项目
4.拿到空项目怎么办?
1)删除默认内容
5.扩展
1)项目启动时为什么是npm run serve?
2.启动项目,浏览器自动开启、修改端口
二、组件化
1.组件
2.父子组件
3..vue文件使用时,之前的有关用法没有太大改变
4.样式污染
三、组件传值
1.正向传值
1) props属性
props验证
2.逆向传值
1) $emit() 自定义事件
2)
3.同胞/兄弟传值
4.跨组件传值
一、vue-cli 脚手架
就是项目的开发环境,方便快速集成在vue开发中的所有内容。
1.安装vue-cli
1.电脑上必须要有node
window+r ---> cmd ---> node -v ---> npm -v (查看是否安装)
2.需要全局安装vue/cli脚手架( -g是全局下载,需要在新电脑或者重新安装node后,执行一次,之后不再需要),在cmd中输入如下命令:
npm install -g @vue/cli
3.确定安装是否成功
vue --version
2.创建项目
1.必须把cmd路径切换到想创建项目的地方
cd XXXXXX
或 文件夹右键,选择在集成终端打开
或
即可
2.vue create 项目名 创建项目
点击Enter,选择自定义
继续Enter,插件暂不选,直接Enter
可选3.x或2.x,(以3.x为例)
继续回车,直至
等待项目创建成功即可
3.启动项目
1.切换到项目路径下
2.npm run serve 启动项目
4.拿到空项目怎么办?
1)删除默认内容
1.src文件夹下 components文件夹下的Helloword.vue文件
2.删除app.vue如下内容:
5.扩展
1)项目启动时为什么是npm run serve?
项目的启动命令,在项目下的package.json文件中的scripts节点里面配置。
所有的单词,它对应的启动命令都是,npm run + 所配置的名字
唯独有个单词例外,即start。start这个单词启动时可以不加run
(终止操作,Ctrl+C)
2.启动项目,浏览器自动开启、修改端口
在项目下的vue.config.js中添加。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
// 自动开启浏览器
devServer:{
open:true,
host:"localhost",
// 修改端口
port:8899
}
})
二、组件化
组件的本质就是自定义标签
1.组件
组件就是把一个项目的页面,拆分成一个个的小模块,通过这些可以复用的小模块,拼装成一个完整的页面。
1).vue文件,即单文件组件。
<template>
写html
</template>
<script>
export default {
写逻辑
}
</script>
<style>
写样式
</style>
注:安装插件Vetur.
然后可快速创建单文件组件
2)在想使用的地方,引用、调用、使用即可
结果:
2.组件分类
1)全局组件 component
配置一次后,可在所有地方直接使用。(注:不可滥用全局组件,会造成组件名污染 )
需要把引用与调用写在main.js中
//引用
import BottomBar from "@/components/BottomBar.vue";
//调用
Vue.component("给要调用的组件起个名字", 调用的组件)
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 配置全局组件
import BottomBar from "@/components/BottomBar.vue";
Vue.component("BottomBar", BottomBar)
// Vue.component("给要调用的组件起个名字", 调用的组件)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
2)局部组件 components
只在当前页面使用时,进行引用 调用 使用
3.父子组件
就是组件与组件之间的嵌套关系
父子
结果:
4.vue文件使用时,之前的有关用法没有太大改变
data只能用函数式,不能用对象式
例如:
<template>
<div>
<h1>{{text}}</h1>
<button @click="fun()">{{text1}}</button>
<ul>
<li v-for="(v,i) in arr" :key="i">
{{v.name}}---{{v.age}}
</li>
</ul>
<h1>{{upperText}}</h1>
</div>
</template>
<script>
export default {
// 只有data有写法上的要求,其他都一样
// data只能用函数式,不能用对象式
data(){
return{
text:"qwertyui",
arr:[
{name:"A",age:1},
{name:"B",age:2},
{name:"C",age:3},
{name:"D",age:4}
],
text1:"点击",
text2:"cvghnj"
}
},
methods:{
fun(){
this.text1="已完成"
}
},
computed:{
upperText(){
return this.text2.toUpperCase();
}
}
}
</script>
<style>
</style>
5.样式污染
scoped属性来进行样式隔离,即当前样式仅对当前组件生效
<style scoped>
</style>
三、组件传值
父组件的数据默认情况下不能直接相互使用,因为组件与组件之间是一个完整的独立的个体
1.正向传值
1) props属性
父组件把数据传递给子组件
1.子组件设置接收props
export default {
// 1.使用props定义接收参数
props:["AAA","BBB"]
}
2.父组件传递
<ZiDemo :AAA="传递的数据a" :BBB="传递的数据b" />
3.在子组件中使用
<span>{{AAA}}</span><span>{{BBB}}</span>
例子:
如下:
在App.vue中
<template>
<div>
<!-- 3.使用 -->
<Fu/>
<MiaoSha/>
</div>
</template>
<script>
// 1.引用
import Fu from './components/JDItem/FuDemo.vue'
import MiaoSha from "./components/JDItem/MiaoSha.vue"
export default {
name: 'App',
components: {
// 2.调用
Fu,MiaoSha
}
}
</script>
<style>
*{
margin: 0px;padding: 0px;
}
</style>
在FuDemo.vue中
<template>
<div class="content">
<ZiDemo v-for="(v,i) in arr" :key="i" :title="v.title" :img="v.imgurl"></ZiDemo>
</div>
</template>
<script>
import ZiDemo from "./ZiDemo"
export default {
components:{
ZiDemo
},
data(){
return{
arr:[
{id:1,title:"AA",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/187640/12/30456/5256/639c2315Ebc95c142/350a8f0c766f5460.png"},
{id:2,title:"BB",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png"},
{id:3,title:"CC",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/186882/8/12149/5894/60ec1250E9335241a/b22054613aa8ae75.png"},
{id:4,title:"DD",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/208529/13/35972/4081/6497ee53F4f8d38d9/c5267cb385f923fe.png"},
{id:5,title:"EE",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png"},
{id:6,title:"FF",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/208529/13/35972/4081/6497ee53F4f8d38d9/c5267cb385f923fe.png"},
{id:7,title:"GG",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/186882/8/12149/5894/60ec1250E9335241a/b22054613aa8ae75.png"},
{id:8,title:"OO",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png"},
{id:9,title:"PP",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/177902/16/13776/5658/60ec0e71E801087f2/a0d5a68bf1461e6d.png"},
{id:10,title:"QQ",imgurl:"https://m15.360buyimg.com/mobilecms/jfs/t1/186882/8/12149/5894/60ec1250E9335241a/b22054613aa8ae75.png"},
]
}
}
}
</script>
<style scoped>
.content{
width: 100%;height: 200px;background-color: aquamarine;display: flex;flex-wrap: wrap;
}
</style>
在ZiDemo.vue中
<template>
<div class="item">
<img :src="img" >
<br>
<span>{{title}}</span>
</div>
</template>
<script>
export default {
// 1.使用props定义接收参数
props:["title","img"]
}
</script>
<style>
.item>img{width: 70px;}
.item{text-align: center;}
</style>
在MiaoSha.vue中
<template>
<div>
<p>秒杀</p>
<div class="slider">
<MiaoShaItem v-for="(v,i) in arr" :key="i" :price="v.price" :img="v.imgurl"/>
</div>
</div>
</template>
<script>
import MiaoShaItem from "./MiaoShaItem.vue"
export default {
components:{
MiaoShaItem
},
data(){
return{
arr:[
{price:11,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/150751/26/27617/240337/64e48881F9b73d4d1/7515278c1cff7fa6.jpg"},
{price:22,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/106088/1/44673/169681/65012e13F7d8a7378/616262301330609d.jpg"},
{price:33,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/150751/26/27617/240337/64e48881F9b73d4d1/7515278c1cff7fa6.jpg"},
{price:44,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/106088/1/44673/169681/65012e13F7d8a7378/616262301330609d.jpg"},
{price:55,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/150751/26/27617/240337/64e48881F9b73d4d1/7515278c1cff7fa6.jpg"},
{price:66,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/106088/1/44673/169681/65012e13F7d8a7378/616262301330609d.jpg"},
{price:77,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/150751/26/27617/240337/64e48881F9b73d4d1/7515278c1cff7fa6.jpg"},
{price:88,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/106088/1/44673/169681/65012e13F7d8a7378/616262301330609d.jpg"},
{price:99,imgurl:"https://m.360buyimg.com/seckillcms/jfs/t1/150751/26/27617/240337/64e48881F9b73d4d1/7515278c1cff7fa6.jpg"}
]
}
}
}
</script>
<style>
.slider{width:100%;height: 100px;display: flex;overflow-x: auto;}
</style>
在MiaoShaItem.vue中
<template>
<div class="b">
<img :src="img" >
<br>
<span>{{haha(price)}}</span>
</div>
</template>
<script>
export default {
props:["price","img"],
methods:{
haha(val){
return "¥"+val
}
}
}
</script>
<style>
.b>img{width: 50px;}
</style>
例子2:
如下:
在OneCom.vue中
<template>
<div>
<Two :fuarr="OneArr"/>
<Two :fuarr="TwoArr"/>
<Two :fuarr="ThreeArr"/>
</div>
</template>
<script>
import Two from "./TwoCom.vue"
export default {
components:{
Two
},
computed:{
OneArr(){
return this.obj.slice(0,5);
},
TwoArr(){
return this.obj.slice(5,10);
},
ThreeArr(){
return this.obj.slice(10,15);
}
},
data(){
return{
obj:[
{title:"1",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"2",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"3",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"4",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"5",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"6",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"7",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"8",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"9",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"10",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"11",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"12",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"13",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"14",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"15",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"16",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"17",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"18",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"19",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"},
{title:"20",imgurl:"https://img14.360buyimg.com/mobilecms/s360x360_jfs/t1/100221/9/45007/235763/64fed678F19236f79/1d8c3ed48f5bd8e2.jpg!q70.dpg.webp"}
]
}
}
}
</script>
<style scoped>
</style>
在TwoCom.vue中
<template>
<div class="item">
<Three v-for="(v,i) in fuarr" :key="i" :title="v.title" :img="v.imgurl"/>
</div>
</template>
<script>
import Three from "./ThreeCom.vue"
export default {
components:{
Three
},
props:["fuarr"]
}
</script>
<style scoped>
.item{width: 100%;height: 2rem;background-color: pink;display: flex;margin: 0.1rem 0;overflow-x: auto;}
</style>
在ThreeCom.vue中
<template>
<div>
<img :src="img">
<br>
<span>{{title}}</span>
</div>
</template>
<script>
export default {
props:["title","img"]
}
</script>
<style scoped>
img{width: 1.5rem;}
span{font-size: 0.16rem;}
div{text-align: center;
/* 可以让换行符、空格等不占空 */
font-size: 0px;
}
</style>
在App.vue中
<template>
<div id="app">
<One />
</div>
</template>
<script>
import One from './components/no2/OneCom.vue'
export default {
name: 'App',
components: {
One
}
}
</script>
<style>
*{margin: 0px;padding: 0px;}
html{
font-size: 26.66667vw;
/* 此时1rem=100px */
}
</style>
props验证
在接收父组件传递过来的数据时,进行一个验证,验证数据类型,默认值或非空等校验,约束传递过来的数据。
语法:
props:{
接收参数:{
type:数据类型
// Number String Boolean Object Array
}
}
.
props:{
num:{
type:Number
}
}
设置默认值:
props:{
接收参数:{
type:数据类型
// Number String Boolean Object Array
defalut:设置的默认值
}
}
.
props:{
num:{
type:Number,
default:9527
}
}
非空设置:不能和默认值同时使用,required
props:{
num:{
type:Number,
// default:9527
required:true
}
}
2.逆向传值
子组件把数据传递给父组件.
在vue中,逆向传值默认是不被允许的,所以需要使用 $emit() 自定义事件来完成 .
1) $emit() 自定义事件
在子组件中
<template>
<div>
zi
<!-- 逆向传值必须要用事件来触发 -->
<button @click=fun()>点击传递数据</button>
</div>
</template>
<script>
export default {
data(){
return{
text:"子组件的数据"
// text2:"数据2"
}
},
methods:{
fun(){
// 2.自定义事件,携带子组件的数据
// this.$emit("给自定义事件起个名字",传递的数据)
// this.$emit("haha",this.text)
this.$emit("haha",{a:this.text})
// this.$emit("haha",{a:this.text,b:this.text2})
}
}
}
</script>
<style>
</style>
在父组件中
<template>
<div>
<!-- 逆向传值 -->
<!-- 3.绑定自定义事件 -->
<!-- <Zi @自定义事件="函数"/> 该函数不加() -->
<Zi @haha="dem"/>
</div>
</template>
<script>
import Zi from "./ZiDemo.vue"
export default {
components:{
Zi
},
methods:{
// 4.定义函数,并接收自定义事件上的数据
dem(val){
console.log(val);
}
}
}
</script>
<style>
</style>
即
2)
3.同胞/兄弟传值
什么是同胞组件(多个组件有一个相同的父组件)两个兄弟之间的数据传递
什么是中央事件总线:凌驾在多个兄弟组件之上的一个空vue实例,这个空vue实例就是中央事件总线。
1.创建中央事件总线,在src下创建一个文件夹,里面创建一个xxx.js
import Vue from "vue"
export default new Vue()
2.要传递的组件,把数据交给中央事件总线 $emit
<template>
<div>
<!-- 1.使用事件触发自定义事件 -->
<button @click="fun()">点我传递数据</button>
</div>
</template>
<script>
// 2.引用中央事件总线
// 扩展 (1)vue中无论在任何层级,只要路径中出现@,就直接代表src这个文件夹
// (2)如果路径上只指定了文件夹,那么程序会自己进入这个文件夹找下面的index.js
// import from "../../eventBus/index.js"
// import from "@/eventBus/index.js"
import eventBus from "@/eventBus"
export default {
data(){
return{
texta:"aaaaa"
}
},
methods:{
fun(){
// 3.给中央事件总线上绑定自定义事件并传递数据
// eventBus.$emit("自定义事件名",要传递的数据)
eventBus.$emit("qqq",{a:this.texta})
}
}
}
</script>
<style>
</style>
3.要接收的组件从中央事件总线中拿过来,$on() 监听实例上面的自定义事件
<template>
<div>
</div>
</template>
<script>
// 1.引用中央事件总线
import eventBus from "@/eventBus"
export default {
// 生命周期 在组件创建完毕后自动执行
created(){
// 2.使用$on来获取实例上的自定义事件
// eventBus.$on("要找的那个自定义事件",(val自定义事件上的参数)=>{
// 逻辑
// })
eventBus.$on("qqq",(val)=>{
console.log(val);
})
}
}
</script>
<style>
</style>
如图:
神的力量: 谢谢,真的秒开了,请问是什么原理呢
CSDN-Ada助手: CS入门 技能树或许可以帮到你:https://edu.csdn.net/skill/gml?utm_source=AI_act_gml
唐小橘子: 调完真的秒打开诶
问就是做不了: 可以使用vscode来进行代码开发,微信开发者工具来预览展示(充当浏览器的作用)
CSDN-Ada助手: 非常感谢您分享这篇关于Vue.js的总结,标题看起来很有吸引力!恭喜您写了第13篇博客,这是一项了不起的成就。您在项目创建、启动以及组件传值方面的总结一定会为其他学习Vue.js的人提供很大的帮助。我期待着您未来更多关于Vue.js的文章,也希望您可以进一步探讨Vue.js的高级特性或者与其他前端框架的比较。谢谢您的分享,继续加油!