Vue_day05

Vue DAY05

vue的自定义组件

vue所管理的标签可以认为是vue组件。 而在项目开发的过程中,经常会用到一些需要复用的标签结构以及相应样式。vue提供了自定义组件的写法,可以让开发者将一些需要复用的页面结构、样式、功能组织在一起,作为一个整体存在在项目中。这样,当需要使用这个组件时,直接引用该组件即可,例如:

<div>
    <!-- 该组件就称为一个自定义组件,由开发者自行设计
         标签名自定义,属性自定义,事件自定义 -->
	<person src="图片路径" name="昵称"></person>
</div>
如何设计并实现一个自定义组件

目标,设计一个组件,模仿标签的样式,方便的进行使用。

实现步骤:

  1. 设计一个自定义组件(包括它的外观、功能、未来怎么复用)。

  2. 定义一个组件:

    1. 在components目录下新建 MyTag.vue。并且在该组件中定义基础样式。
    2. 注意:<script>export default {}</script>
  3. 当需要使用该组件时,需要先引入再使用:

    1. 引用MyTag组件:

      import MyTag from './components/MyTag.vue'
      components: {
          // 组件名:组件对象    
          // 组件名相当于标签名,在页面中可以直接使用
          // vue为了使用方便,自动支持将驼峰命名法 改为 短横线命名法
          // <MyTag></MyTag>     大驼峰
          // <my-tag></my-tag>   短横线
          MyTag: MyTag,
          mytag: MyTag,
          abc: MyTag
      }
      
    2. 直接通过标签名,使用该组件:

      <MyTag></MyTag>
      <my-tag></my-tag>    // 直接看到自定义组件的外观
      <MyTag />
      <mytag></mytag>
      <abc></abc>
      

      1667468480910

如何向子组件传参,修改子组件的内容

1667470047947

实现步骤
  1. 在子组件中的script代码段中,通过props定义自定义属性,接收父组件传进来的参数。

    export default {
        props: {
            自定义属性名: {
                default: 属性的默认值,
                type: 属性的数据类型,
                required: 属性是否为必填属性,
                validate: 通过正则验证属性值的格式
            },
            avatar: {
                type: String,
                default: ''
            }
    	}
    }
    

    在此,vue提供了一种简单语法来定义属性:

    export default {
        props: ['color', 'avatar', 'name']
    }
    
组件插槽

平时在设计子组件时,绝大部分布局内容都已完成定义,但是有些布局需要父组件在使用当前子组件时动态设置,这时就可以使用组件插槽。在设计子组件时,可以在布局中定义插槽位置及基础样式,父组件在使用时通过slot来动态赋值。

默认插槽
  1. 在设计子组件时,在组件某一个位置添加slot标签(在此处安放一个插槽):

    <template>
      <div class="my-tag">
        <slot />   <!-- 在此处安放一个插槽 -->
      </div>
    </template>
    
  2. 在父组件中使用子组件时,需要动态设置子组件的默认插槽内容:

    子组件开始标签与结束标签中的内容,将会作为默认插槽,替换子组件的slot

    <my-tag>标签文本</my-tag>
    <my-tag>
    	<span>另外一个文本</span>
    </my-tag>
    
具名插槽

如果在子组件中,有多个地方都需要在父组件引用时动态设置内容,则可以声明多个插槽,每一个插槽赋予一个名字,称为具名插槽。 在使用该子组件并且为插槽设置内容时,可以使用<slot name='名称'></slot>来动态赋值。

案例:模仿后台管理页面的布局。

实现步骤:
  1. 当设计一个子组件时,子组件中有多个地方都需要插槽来动态赋值时,就可以为slot标签添加name属性(起一个名字):

    <div>
        <slot name="header"/>
        <slot name="left"/>
        <slot name="right"/>
    </div>
    
  2. 当使用该组件时,通过slot属性来指定为哪一个插槽设置内容:

    <Layout>
    	<span slot="header">header的内容</span>
        <span slot="left">left的内容</span>
        <span slot="right">right的内容</span>
    </Layout>
    

VueCli脚手架中的路由系统 VueRouter

多页项目的开发:一个大型网站需要由多个页面共同组成,页面之间可以相互跳转。

开发方式分为两种:

  1. 传统方案:每一个页面都是一个独立的html文件,通过超链接标签a来实现页面之间的跳转。

    特点:先清空之前的页面内容,然后显示新页面 – 浏览器会闪一下

  2. 新方案:通过Ajax实现局部页面更新。

    特点:不需要切换html页面(浏览器不会重新加载新的dom树),只需要将局部内容更新即可。

VueCli脚手架创建的项目属于新方案,

专业一点称为:SPA(Single Page Application)项目。 单页面应用。意味着VueCli脚手架项目无论设计多少个页面,本质上只有一个html。所有的页面内容显示、跳转都将会在这唯一的一个index.html页面中完成。 (public/index.html

对于单页面应用来说,多个界面之间的跳转本质上就是div #app中内容的动态更新。

脚手架中路由系统相关的文件:
  1. public/index.html 项目中唯一的html网页,提供div#app
  2. src/main.js 入口js文件,将会创建Vue对象,管理 div#app
  3. src/App.vue 页面初始化加载的组件
  4. src/views/HomeView.vue 页面组件
  5. src/router/index.js 定义了 请求资源路径与组件之间的映射关系。
如何为一个页面组件配置路由地址?(访问该地址,可以看到该页面)
  1. 前提: App.vue中添加<router-view />

    <template>
    	<div>
            <!-- 占位符,router-view在页面中具体显示什么组件效果,
                 由当前请求资源路径来决定
         若浏览器访问: http://localhost:8080/  看到 HomeView.vue
         若浏览器访问: http://localhost:8080/about 看到AboutView.vue
            -->
            <router-view />
        </div>
    </template>
    
  2. 前去配置路由地址与组件之间的映射关系:src/router/index.js

    import HomeView from 'HomeView.vue的路径'
    const routes = [{
        path: '/',
        name: '路由名称-需要避免重复',
        component: HomeView
    }]
    

案例:配置路由,实现:

访问:http://localhost:8080/slot    看到:src/App-默认插槽.vue
访问:http://localhost:8080/nameslot    看到:src/App-具名插槽.vue
路由配置中的懒加载与非懒加载的差异

router/index.js中配置路由时,可以选择标准模式与懒加载模式配置路由:

标准模式:

import SlotView from '../App-默认插槽.vue'
const routes = [
  {
    path: '/slot',
    name: 'slot',
    component: SlotView
  },
]

对于标准模式加载组件,在import的时候已经将组件加载到内存中。这样的话,当Vue项目初始化时,就会加载路由系统,从而引入该组件。(虽然还不需要看到这个组件,但是已经下载完毕,在内存中已经存在)

懒加载模式:

const routes = [
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue')
  }
]

对于懒加载模式,使用函数的方式引入该组件,这种引入方式将会在使用的时候才会下载资源,真正做到,随用随下载。

结论

除了首页必须加载的资源使用标准模式之外,其他都可以无脑使用懒加载。

脚手架路由运行流程

在这里插入图片描述

基于路由系统完成页面跳转功能

基于组件方式,实现路由跳转:

<router-link to="目标地址">链接文本</router-link>
<router-link to="/about">点击去往about</router-link>

编程式跳转:

this.$router.push('目标地址')
this.$router是什么?

当前项目中的路由管理器(VueRouter对象),管理了所有的路由对象。除此之外,还提供了很多方法,进行路由操作:

this.$router.push('/about')   跳转到 /about
this.$router.go(-1)           回到上一页

this.$router.push()跳转的过程中,有可能出现如下错误:

在这里插入图片描述

上述错误的原因:当前页面已经是/nameslot页面了,结果在跳转的过程中还要跳转到该路由地址:/nameslot,导致路由重复跳转的问题。在此可以添加一个if判断:如果当前路由地址已经是/nameslot,那么就不再向该地址跳转了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue可以通过使用第三方组件库或自己编写组件来实现日历签到功能。 1. 使用第三方组件库 例如,使用Element UI中的DatePicker组件,可以实现选择日期的功能。在选中日期后,可以将签到状态保存到后端数据库中,再在日历上展示已签到的日期。 2. 自己编写组件 可以使用Vue自带的组件和插件来编写日历签到组件。具体实现方法如下: - 在Vue项目中创建一个Calendar组件; - 使用Vue自带的v-for指令展示日历; - 在每个日期上绑定点击事件,用来切换签到状态; - 将签到状态保存到Vuex或后端数据库中; - 在日历上展示已签到的日期。 下面是一个简单的日历签到组件代码示例: ```html <template> <div class="calendar"> <div class="header">{{ year }}年{{ month }}月</div> <table> <thead> <tr> <th v-for="day in days">{{ day }}</th> </tr> </thead> <tbody> <tr v-for="week in weeks"> <td v-for="date in week" :class="{ active: isSigned(date) }" @click="toggleSign(date)">{{ date }}</td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { year: new Date().getFullYear(), month: new Date().getMonth() + 1, days: ["日", "一", "二", "三", "四", "五", "六"], weeks: [], signedDates: [] }; }, computed: { daysInMonth() { const date = new Date(this.year, this.month, 0); return date.getDate(); } }, mounted() { this.generateCalendar(); }, methods: { generateCalendar() { const firstDay = new Date(this.year, this.month - 1, 1).getDay(); const lastDate = this.daysInMonth; const weeks = []; let week = []; for (let i = 0; i < firstDay; i++) { week.push(""); } for (let i = 1; i <= lastDate; i++) { week.push(i); if (week.length === 7) { weeks.push(week); week = []; } } if (week.length > 0) { for (let i = week.length; i < 7; i++) { week.push(""); } weeks.push(week); } this.weeks = weeks; }, toggleSign(date) { if (this.isSigned(date)) { // 取消签到 const index = this.signedDates.indexOf(date); this.signedDates.splice(index, 1); } else { // 签到 this.signedDates.push(date); } // 将签到状态保存到Vuex或后端数据库中 }, isSigned(date) { return this.signedDates.includes(date); } } }; </script> <style> .calendar { width: 300px; margin: 0 auto; text-align: center; } .header { font-size: 16px; font-weight: bold; margin-bottom: 10px; } table { width: 100%; border-collapse: collapse; } th { height: 30px; line-height: 30px; } td { height: 50px; line-height: 50px; cursor: pointer; } td.active { background-color: #66ccff; color: #fff; } </style> ``` 这个示例中的Calendar组件展示了一个月的日历,并提供了签到功能。你可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值