vue项目搭建

vue项目搭建

1、项目初始化

1、根组件:App.vue

<template>
    <div id="app">
        <router-view />
    </div>
</template>

2、路由配置:router/index.js

const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home
    }
];

3、组件:views与components文件夹

  1. 删除HOME.vue以外的所有文件

  2. 初始化HOME.vue

    <template>
      <div class="home"></div>
    </template>
  3. 分类管理资源:assets文件夹

    建立img、css、js子文件夹,删除原来的文件

  4. 如果要修改页面标签图标,替换public文件夹下的facicon.ico图片文件

2、项目数据局部化处理

不管页面组件还是小组件都会被多次复用,复用组件的原因其实就是复用组件的页面结构,页面样式,页面逻辑,但是在页面上的数据需要区分,要使每个组件被复用后都是独立的,就需要使用数据局部化处理

借助函数可以产生局部作用的特点,为每次的复用组件产生一个独立的作用域

语法:

data (){
    return{
        // 数据们
    }
}

例子:父组件多次复用子组件,每个被复用的组件都是相互独立的

子组件:

<template>
    <div class="beat" @click="count += 1">
        {{ count }}下
    </div>
</template><script>
    export default {
        name: "Beat",
        // 不管是页面组件还是小组件,都可能被复用,页面结构与样式都可以采用一套,但是数据一定要相互独立
        data () {
            return {
                count: 0
            }
        }
    }
</script><style scoped>
    .beat {
        width: 100px;
        height: 100px;
        background-color: orange;
        text-align: center;
        line-height: 100px;
        border-radius: 50%;
    }
</style>
子组件

父组件:

<template>
    <div class="home">
        <Beat/>
        <Beat/>
    </div>
</template>
<script>
    import Beat from '@/components/Beat'
    export default {
        components: {
            Beat,
        }
    }
</script>
父组件

3、路由逻辑跳转

很多时候我们需要通过普通按钮来控制页面的跳转

1、跳转到指定页

this.$router.push('路径')

或者:this.$router.push({name: '路由名'})

    <button @click="goPage('/first')">前往第一页</button>
    <button @click="goPage('/goods')">前往商品页</button>
​
export default {
methods:{
    goPage(path){
      this.$router.push(path)
    }
}

2、前进后退页

this.$router.go(正负整数),正数表示前进n页,负数表示后退n页,n数字是步长

一般在移动端端开发的时候使用

    <button @click="goBack(1)">前进一步</button>
    <button @click="goBack(-1)">后退一步</button>
​
// 前进后退:this.$router.go(正负整数),正式代表前进,负数代表后台,数值就是步长
    export default {
        methods: {
           goBack(num) {
                this.$router.go(num);  // 一般在移动端项目上运用
            }
    }

4、组件传参

1、父传子

1、在子组件内部通过props设置组件的自定义属性

props: ['abc', 'goods']

2、在父组件渲染子组件时对子组件自定义的属性赋值即可

<GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods"/>

子组件:

<template>
    <div class="goods-box">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
</template><script>
    export default {
        name: "GoodsBox",
        // 在组件内部通过props定义组件的自定义属性
        props: ['abc', 'goods'],
    }
</script><style scoped>
    .goods-box {
        width: 260px;
        height: 300px;
        border: 1px solid black;
        border-radius: 5px;
        margin: 20px;
        float: left;
        overflow: hidden;
        text-align: center;
    }
    img {
        width: 260px;
        height: 260px;
    }
</style>
子组件

父组件:

<template>
    <div class="goods">
        <div class="main">
            <!-- 在使用子组件是对自定义属性赋值即可 -->
            <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods" />
        </div>
    </div>
</template>
<script>
    import GoodsBox from "../components/GoodsBox";
​
    let goods_list = [
        {
            img: require('@/assets/img/001.jpg'),
            title: '小猫',
        },
        {
            img: require('@/assets/img/002.jpg'),
            title: '小猫儿',
        },
        {
            img: require('@/assets/img/003.jpg'),
            title: '小狗',
        },
        {
            img: require('@/assets/img/004.jpg'),
            title: '小狗儿',
        },
    ];
​
    export default {
        name: "Goods",
        data () {
            return {
                goods_list,
            }
        },
        components: {
            GoodsBox,
        },
    }
</script>
父组件

2、子传父

前提:子组件是被父组件渲染的,所以子组件渲染要晚于父组件

  1. 子组件一定要满足一个条件,才能对父组件进行传参(达到某个时间节点,或者某个被激活的状态)

    • 子组件刚加载成功,给父组件传参

    • 子组件要被销毁了,给父组件传参

    • 子组件某一个按钮被点击的时刻,给父组件传参

  2. 在子组件达到满足条件激活后,对父组件发一个通知,将数据携带处理(自定义组件事件), this.$emit()通知父组件,自定义组件事件

        <div class="goods-box" @click="boxClick"></div>
        methods: {
            // this.$emit('自定义的属性',传给父组件的参数1,传给父组件的参数2...)
            boxClick () { this.$emit('receiveData', this.goods.title, '第二个数据', '第三个数据') }
        }
  3. 在父组件渲染子组件的时候为自定义的事件绑定方法

     <GoodsBox @receiveData="recFn"/>
  4. 父组件实现绑定方法时,就能拿到子组件传参的内容

        recFn(title, data2, data3) {
            console.log('接收到了' + title);
        }

    注意:组件不能绑定系统事件,组件的事件都是在自己内部完成

子组件:

<template>
    <div class="goods-box" @click="boxClick">
        <img :src="goods.img" alt="">
        <p>{{ goods.title }}</p>
    </div>
</template><script>
    export default {
        props: ['abc', 'goods'],
        methods: {
            boxClick () {
                // 通知父级 - 自定义组件的事件
                this.$emit('receiveData', this.goods.title)
            }
        }
    }
</script>
子组件

父组件:

<template>
    <div class="goods">
        <div class="main">
            <!-- 实现自定义事件,接收子组件通知的参数 -->
            <GoodsBox v-for="goods in goods_list" @receiveData="recFn"/>
        </div>
    </div>
</template>
<script>
    import GoodsBox from "../components/GoodsBox";
    export default {
        name: "Goods",
        data () {
            return {
                goodsTitle: '哪个',
            }
        },
        methods: {
            recFn(title) {
                console.log('接收到了' + title);
                this.goodsTitle = title;
            }
        },
        components: {
            GoodsBox,
        },
    }
</script>
父组件

5、组件的生命周期钩子

1、组件的生命周期:一个组件从创建到销毁的整个过程

2、在一个组件的生命周期中,会有很多特殊的时间节点,且往往在特定的时间节点完成一定的逻辑,特定的时间节点可以绑定钩子

钩子:提前为某个事件绑定方法,当满足该事件激活条件时,方法就会被调用

最经常用的就是 created(){}:请求后台数据,将请求的结果保存在前台页面

<template>
    <div class="goods">
        <Nav />
    </div>
</template>
<script>
    import Nav from "../components/Nav";
    export default {
        name: "Goods",
        components: {
            Nav,
        },
        beforeCreate() {
            console.log('该组件要被加载了')
        },
        created() {
            console.log('该组件要被加载成功了')
        },
        updated() {
            console.log('数据更新了')
        },
        destroyed() {
            console.log('该组件销毁了')
        }
    }
</script>

6、路由传参

两个父组件之间没有任何关系,想从一个组件点击跳往另一个组件就需要使用路由url正则传递数据进行

路由传参有两种方式:

1、方式一:通过url正则传递数据

  1. 设置

    • 在路由router/index.js路由path设置:path: '/gooddetail/:pk', :pk相当于正则匹配任意字符

    • 请求时:pk就可以换成任意字符

    • '/goods/:pk/detail/:xyz' ==》 '/goods/任意字符/detail/任意字符'

  2. 如何传

    两种方式:

    • 链接跳转:<router-link :to="`/goods/detail/${pk}`"></router-link>

    • 路由逻辑跳转到指定页:this.router.push(/goods/detail/${pk})

  3. 如何取

    this.$route对象是管理路由参数的,传递的参数会在this.$route大字典中,传递的pk参数在this.$route.params字典中

    this.$route.params.pk

配置:router/index.js

const routes = [
    {
        path: '/goods/detail/:pk',
        name: 'GoodsDetail',
        component: GoodsDetail
    },
]

传递:GoodsBox.vue

<router-link class="goods-box" :to="`/goods/detail/${goods.pk}`">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</router-link><!------------------- 或者 -------------------><div class="goods-box" @click="goDetail(goods.pk)">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</div>
<script>
    export default {
        name: "GoodsBox",
        methods: {
            goDetail (pk) {
                this.$router.push(`/goods/detail/${pk}`);
            }
        }
    }
</script>

接收:GoodsDetail.vue

<script>
    export default {
        name: "GoodsDetail",
        data () {
            return {
                pk: '未知',
            }
        },
        // 通常都是在钩子中获取路由传递的参数
        created() {
            this.pk = this.$route.params.pk || this.$route.query.pk;
        }
    }
</script>

2、方式二:通过url参数传递数据

  1. 设置

    路由中直接传入路径,path:'/good/detail ' 后面不要写什么了,不需要正则匹配,请求的时候是?pk=数据

  2. 如何传

    两种方式:将上面/ 换成 ?pk=

    • 链接跳转: <router-link :to="`/goods/detail?pk=${pk}`"></router-link>或者<router-link :to="{name:'GoodsDetail', query:{pk: pk}}"></router-link>

    • 路由逻辑跳转到指定页:this.$router.push(/goods/detail?pk=${pk})或者this.$router.push({name:'GoodsDetail', query:{pk: pk}})

  3. 如何取

    this.$route对象是管理路由参数的,传递的参数会在this.$route.query字典中

    this.$route.query.pk

配置:router/index.js,正常配置即可

const routes = [
    {
        path: '/goods/detail',
        name: 'GoodsDetail',
        component: GoodsDetail
    },
]

传递:GoodsBox.vue

<router-link class="goods-box" :to="`/goods/detail?pk=${goods.pk}`">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</router-link><!------------------- 或者 -------------------><div class="goods-box" @click="goDetail(goods.pk)">
    <img :src="goods.img" alt="">
    <p>{{ goods.title }}</p>
</div>
<script>
    export default {
        name: "GoodsBox",
        methods: {
            goDetail (pk) {
                // this.$router.push(`/goods/detail?pk=${goods.pk}`);
                
                // 或者
                this.$router.push({
                    name: 'GoodsDetail',
                    query: {
                        pk,
                    }
                });
            }
        }
    }
</script>

接收:GoodsDetail.vue

<script>
    export default {
        name: "GoodsDetail",
        data () {
            return {
                pk: '未知',
            }
        },
        // 通常都是在钩子中获取路由传递的参数
        created() {
            this.pk = this.$route.params.pk || this.$route.query.pk;
        }
    }
</script>

7、全局配置自定义的css与js

一些css样式全局都需要使用的叫css reset,或者一些js全局需要使用的我们就全局配置

global.css

html, body {
    margin: 0;
}
​
a {
    color: black;
    text-decoration: none;
}
​
ul {
    margin: 0;
    padding: 0;
}
global.css

settings.js

export default {
    base_url: 'https://127.0.0.1:8000'
}
settings.js

main.js

//1) 配置全局css,四种方式都行,直接导入就行
import '@/assets/css/global.css'
// import global_css from '@/assets/css/global.css'  // 资源需要用变量保存,方便以后使用
// require('@/assets/css/global.css')
// let global_css = require('@/assets/css/global.css')  // 资源需要用变量保存,方便以后使用
​
​
// 2) 配置自定义js设置文件,导入之后要配置
import settings from '@/assets/js/settings.js'
Vue.prototype.$settings = settings;
// 在任何一个组件中的逻辑,可以通过 this.$settings访问settings.js文件的{}数据

 

 

 

 

posted @ 2020-02-14 23:37  Mr沈  阅读(206)  评论(0编辑  收藏  举报