一、项目初始化
""" 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文件夹 i)删除除Home.vue以为的所有组件 ii)初始化Home.vue <template> <div class="home"> </div> </template> 4)分类管理资源:assets文件夹 建立img、css、js子文件夹,删除原来的资源 5)如果要修改页面标签图标 替换public文件夹下的favicon.ico图片文件 """
二、组件数据局部化处理(数据隔离)
""" 1)不管页面组件还是小组件,都可能会被多次复用 2)复用组件的原因,其实就是复用组件的 页面结构、页面样式、页面逻辑 3)但是页面上的数据需要区分(被复用的两个组件数据多少是有区别的),所以组件的数据要做局部化处理 4)借助函数可以产生局部作用域的特点,为每一次复用组件产生一个独立的作用域 语法: 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>
三、路由逻辑跳转
""" 1)很多时候,我们需要通过普通按钮的逻辑,或是直接在某些逻辑中完成页面的跳转 2)可以通过在逻辑中用 this.$router.push() 来完成前往目标页,两种语法如下 this.$router.push('路径') this.$router.push({name: '路由名'}) 3)在做移动端项目时,没有像浏览器那样的前进后台键,页可以用 this.$router.go() 来完成前进后退,语法如下 前进后退:this.$router.go(正负整数),正式代表前进,负数代表后台,数值就是步长 """
<template> <div class="home"> <Nav /> <h1>主页</h1> <button @click="goPage('/first')">前往第一页</button> | <!--由于他不像vue.router有to所以我们绑定点击事件--> <button @click="goPage('/second')">前往第二页</button> | <button @click="goBack(-1)">后退一页</button> | <button @click="goBack(-2)">后退二页</button> | <button @click="goBack(1)">前进一页</button> <Beat/> <Beat/> </div> </template> <script> import Beat from "../components/Beat"; import Nav from "../components/Nav"; // router逻辑跳转 // 1)跳转目标页this.$router.push('路径') | this.$router.push({name:'路径名'}) // 2)前进后退this.$router.go(num)正数代表前进,负数代表后退,数值就是步数长度 export default { methods : { goPage (path) { // console.log(this.$router) //可以通过this.$router完成逻辑跳转 this.$router.push(path) ; //本质上就是一个数组,我们往数组中加载东西,用push }, goBack(num) { this.$router.go(num) //一般用在移动端项目this.$router.go(num) 正数代表前进,负数代表后退 } }, components: {Nav,Beat}, } </script>
四、组件传参(父子组件之间数据交互)
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"> <Nav/> <H1>商品页</H1> <hr> <div class="main"> <!--我们用来.main专门存放goods的--> <GoodsBox v-for="goods in goods_list" :goods="goods"/> <!--第一个goods是GoodsBox自己的变量,第二个goods是Goods中的数据--> </div> </div> </template> <!-- 一、组件传参:父传子 --> <script> import GoodsBox from "../components/GoodsBox"; import Nav from "../components/Nav"; let goods_list = [ { img: require('@/assets/img/001.jpg'), //必须要把图片路径包裹在require中才行 title:'旺财', }, { img: require('@/assets/img/002.jpg'), title:'女友一号', }, { img: require('@/assets/img/003.jpg'), title:'女友二号', }, { img: require('@/assets/img/004.jpg'), title:'小猫', }, { img: require('@/assets/img/005.jpg'), title:'小狗狗', }, ]; export default { name: "Goods", data () { return { goods_list, } }, components:{ GoodsBox, Nav, } } </script> <style scoped> </style>
2、子传父(子组件传数据给父组件)
""" 二、组件传参 - 子传父 前提:子组件是被父组件渲染的,所以子组件渲染要晚于父组件 1)子组件一定要满足一个条件,才能对父组件进行传参(某个时间节点 === 某个被激活的方法) eg:i)子组件刚刚加载成功,给父组件传参 ii)子组件某一个按钮被点击的时刻,给父组件传参 iii)子组件要被销毁了,给父组件传参 2)在子组件满足条件激活子组件的方法中,对父组件发生一个通知,并将数据携带处理(自定义组件事件) <div class="goods-box" @click="boxClick"></div> methods: { 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 { name: "GoodsBox", // 在组件内部通过props定义组件的自定义属性 props:['abc','goods'], methods : { boxClick () { //$emit通知父级 自定义组件的事件 this.$emit('recvDate', this.goods.title) } } } </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"> <Nav/> <H1>商品页</H1> <hr> <h2 style="text-align: center">{{goodsTitle}}商品被选中</h2> <div class="main"> <!--我们用来.main专门存放goods的--> <GoodsBox v-for="goods in goods_list" :goods="goods" @recvDate="recvFn"/> <!--第一个goods是GoodsBox自己的变量,第二个goods是Goods中的数据--> </div> </div> </template> <!-- 一、组件传参:父传子 1)在子组件内部通过props设置组件的自定义属性 props: ['abc', 'goods'] 2)在父组件渲染子组件是对自定义属性赋值即可 <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods"/> 二、组件传参 - 子传父 前提:子组件是被父组件渲染的,所以子组件渲染要晚于父组件 组件标签不能绑定系统定义的事件,没有意义,子组件的事件都是在自己内部完成 1)子组件一定要满足一个条件,才能对父组件进行传参(某个时间节点 === 某个被激活的方法) eg:i)子组件刚刚加载成功,给父组件传参 ii)子组件某一个按钮被点击的时刻,给父组件传参 iii)子组件要被销毁了,给父组件传参 2)在子组件满足条件激活子组件的方法中,对父组件发生一个通知,并将数据携带处理(自定义组件事件) <div class="goods-box" @click="boxClick"></div> methods: { boxClick () { this.$emit('receiveData', this.goods.title, '第二个数据', '第三个数据') } } 3)在父组件渲染子组件时,为自定义事件绑定方法 <GoodsBox @receiveData="recFn"/> 4)在父组件实现绑定方法时,就可以拿到子组件传参的内容(接收到了通知并在父组件中相应) recFn(title, data2, data3) { console.log('接收到了' + title); } --> <script> import GoodsBox from "../components/GoodsBox"; import Nav from "../components/Nav"; let goods_list = [ { img: require('@/assets/img/001.jpg'), //必须要把图片路径包裹在require中才行 title:'旺财', }, { img: require('@/assets/img/002.jpg'), title:'女友一号', }, { img: require('@/assets/img/003.jpg'), title:'女友二号', }, { img: require('@/assets/img/004.jpg'), title:'小猫', }, { img: require('@/assets/img/005.jpg'), title:'小狗狗', }, ]; export default { name: "Goods", data () { return { goods_list, goodsTitle:'那个', } }, methods:{ recvFn(title) { console.log('接收到了'+ title); this.goodsTitle = title; } }, components:{ GoodsBox, Nav, } } </script> <style scoped> </style>
五、组件的生命周期钩子
""" 一、组件的生命周期:一个组件从创建到销毁的整个过程 二、生命周期钩子:在一个组件生命周期中,会有很多特殊的时间节点,且往往会在特定的时间节点完成一定的逻辑,特殊的事件节点可以绑定钩子 注:钩子 - 提前为某个事件绑定方法,当满足这个事件激活条件时,方法就会被调用 | 满足特点条件被回调的绑定方法就称之为钩子 """
<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>
大家如果有兴趣可以去vue.js官网中的学习API中去参考
六、路由传参
""" 路由传参: 一、通过url正则传递数据 i)设置 路由: path: '/goods/detail/:pk' | '/goods/:pk/detail/:xyz' 请求: '/goods/detail/任意字符' | '/goods/任意字符/detail/任意字符' ii)如何传 <router-link :to="`/goods/detail/${pk}`"></router-link> this.$router.push(`/goods/detail/${pk}`) iii)如何取 this.$route对象是管理路由参数的,传递的参数会在this.$route.params字典中 this.$route.params.pk 二、通过url参数传递数据 i)设置 路由: path: '/goods/detail' 请求: '/goods/detail?pk=数据' ii)如何传 <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}}) iii)如何取 this.$route对象是管理路由参数的,传递的参数会在this.$route.query字典中 this.$route.query.pk """
第一种传参
配置:router/index.js
const routes = [ { path: '/goods/detail/:pk', //:pk可以配置任意数字 name: 'GoodsDetail', component: GoodsDetail }, ]
传递:Goods.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>
第二种传参
配置: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>
七、全局配置自定义css与js
先去assets下面新建css与js的文件夹,在css中书写全局的css,在js下面书写全局js,写好之后只需要在main.js中写几句话即可
global.css
html, body { margin: 0; } a { color: black; text-decoration: none; } ul { margin: 0; padding: 0; }
settings.js
export default { base_url: 'https://127.0.0.1:8000' }
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文件的{}数据
八、小结
""" 项目: 环境;node -> npm -> cnpm -> vue/cli 创建:vue create proj 配置:配置npm启动项 项目目录结构:依赖、环境、入口、核心代码们 组件: 构成:template + script + style 导入:import 别名 from '路径' 父加子:1)导入 2)注册 3)使用 组件数据:组件化处理 data(){ return {} } 传参:父传子 - 自定义组件属性 | 子传父 - 自定义组件事件 生命周期钩子:created() { //完成后台请求等 } 路由: 根组件中的页面占位:<router-view /> 导航栏中的页面跳转:<router-link to=""></router-link> 代码中的逻辑跳转:this.$router.push() | this.$router.go() 路由传参:两种方式 两个路由对象: this.$router - 控制路由跳转 this.$route - 控制路由数据 """
来源:https://www.cnblogs.com/yafeng666/p/12310279.html