Vue.js (包含2.x和3.x) 总结03 (项目创建 / 启动、组件、组件传值)

目录

一、vue-cli 脚手架

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>

如图:

4.跨组件传值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值