vue学习-02vue入门之组件

news2024/11/26 4:20:50

删除Vue-cli预设

在用户根目录下(C:\Users\你的用户名)这个地址里有一个.vuerc 文件,修改或删除配置

组件

  1. Props(组件之间的数据传递)
    1. Prop 的大小写 (camelCase vs kebab-case)不敏感
    2. Prop 类型: String Number Boolean Array Object Date Function Symbol
    3. 传递静态或动态 Prop
    4. 单向数据流:只能父传子,不能子传父
    5. Prop 验证:
      类型验证 空验证(是否允许为空) 默认值(缺省值)
      注意:对象或数组默认值必须从一个工厂函数获取
  2. 自定义事件
    子传父
    .sync修饰符
  3. 插槽
    1. 插槽内容:tab切换
    2. 编译作用域:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。(动态数据写在哪里就在哪里声明)
    3. 后备内容(默认值,缺省值)
    4. 具名插槽
    5. 作用域插槽
    6. 解构插槽 Prop
    7. 具名插槽的缩写 v-slot: -> #
    8. 废弃了的语法(了解性知识)
  4. 动态组件 & 异步组件
    1. 动态组件:keep-alive
      include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
      exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
      max - 数字。最多可以缓存多少组件实例。
    2. 异步组件:程序运行时不加载组件,什么时候组件被使用了,才会被加载
  5. 处理边界情况
    $root property $parent
  6. Vue 实例
    Vue是MVVM的模型,但是大家记住,他并不是完整的MVVM
    M:Model
    VM:ViewModel
    V:View
    MVC标准的设计模型,Angular
    **实例生命周期钩子:生命周期函数会随着我们对程序理解越深,可参考价值越高
  7. 进入/离开 & 列表过渡
  8. 自定义指令
    1. 全局指令
    2. 局部指令
      自定义指令存在三个钩子函数
      bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
      inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
      update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
      componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
      unbind:只调用一次,指令与元素解绑时调用。
  9. 渲染函数 & JSX
    过滤器:商城平台,价格¥
    1. 局部过滤器
    2. 全局过滤器

目录结构:
在这里插入图片描述
App.vue

<template>
  <div id="app">
    <!-- <MyComponent :title="num" :age="age" :banner="banner" demo="hello"></MyComponent> -->
    <ul>
      <li>hello</li>
      <li>world</li>
    </ul>
    <hr>
    <!-- <Parent /> -->
    <hr>
    <!-- <SlotParent /> -->
    <hr>
    <keep-alive include="Home">
      <component v-bind:is="currentPage"></component>
    </keep-alive>
    <button @click="changeComponent">切换组件</button>
    <hr>
    <p>{{ $root.foo }}</p>
    <p>{{ $root.getVue() }}</p>
    <hr>
    <!-- <ComponentInstance /> -->
    <hr>
    <!-- <AnimComponent /> -->
    <hr>
    <!-- <DirectiveComponent /> -->
    <RenderComponent>
      <h3>我是插槽</h3>
    </RenderComponent>
    <FilterComponent />
  </div>
</template>

<script>
//引入各个组件
import MyComponent from "./components/MyComponent"
import Parent from "./components/group/Parent"
import SlotParent from "./components/slotComponents/SlotParent"

// import HomePage from "./components/pages/HomePage"
// 异步加载
const HomePage = () => import("./components/pages/HomePage");
import UserPage from "./components/pages/UserPage"
import ComponentInstance  from "./components/ComponentInstance"

import AnimComponent from "./components/AnimComponent"
import DirectiveComponent from "./components/directiveComponent"

import RenderComponent from "./components/renderComponent"
import FilterComponent from "./components/fitlerComponent"

export default {
  name: 'App',
  data(){
    return{
      num:100,
      age:"300",
      banner:["导航","新闻"],
      currentPage:UserPage,
      flag:true
    }
  },
  components: {
    MyComponent,
    Parent,
    SlotParent,
    HomePage,
    UserPage,
    ComponentInstance,
    AnimComponent,
    DirectiveComponent,
    RenderComponent,
    FilterComponent
  },
  methods:{
    changeComponent(){
      if(this.flag){
        this.currentPage = HomePage
      }else{
        this.currentPage = UserPage
      }
      this.flag = !this.flag
    }
  }
}
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

index.js

import Vue from "vue"

Vue.filter('rmb', (value) => {
    // value就是{{}}或者v-bind绑定的值
    if (value) {
        return "¥" + value
    }
})

focus.js文件

import Vue from "vue"
// 全局指令
Vue.directive("focus", {
    inserted(el) {
        el.focus(); // focus是js的获取input焦点的方法
    }
})

Vue.directive('red',{
    inserted(el){
        el.style.color = '#ff0000'
    }
})

AnimComponent.vue

<template>
    <div>
        <div>
            <button @click="flag = !flag">切换</button>
            <transition name="fade">
                <p v-if="flag">HelloAnim</p>
            </transition>
        </div>
        <div>
            <button @click="flagAnim = !flagAnim">切换</button>
            <transition
                name="custom-classes-transition"
                enter-active-class="animated rollIn"
                leave-active-class="animated rollOut"
            >
                <p v-if="flagAnim">HelloAnim</p>
            </transition>
        </div>
    </div>
</template>
<script>
export default {
    name: "Anim",
    data() {
        return {
            flag: true,
            flagAnim: true
        };
    }
};
</script>
<style scoped>
.fade-enter,
.fade-leave-to {
    opacity: 0;
    font-size: 15px;
}

.fade-enter-to,
.fade-leave {
    opacity: 1;
    font-size: 30px;
}

.fade-enter-active,
.fade-leave-active {
    transition: all 1s;
}
</style>

ComponentInstance.vue

<template>
    <div>
        <p>{{ msg }}</p>
        <button @click="msg = '生命周期钩子函数重新渲染'">修改数据</button>
    </div>
</template>
<script>
export default {
    name: "Life",
    data() {
        return {
            msg:"生命周期钩子函数"
        };
    },
    beforeCreate() {
        // 做初始化操作
        console.log("组件创建之前:beforeCreate");
    },
    created() {
        // 做初始化操作
        console.log("组件创建之后:created");
    },
    beforeMount(){
        // 判断组件渲染之前要做的额外事前
        console.log("组件渲染之前:beforeMount");
    },
    mounted(){
        // 网络请求
        console.log("组件渲染之后:mounted");
    },
    beforeUpdate(){
        console.log("数据更新之前:beforeUpdate");
    },
    updated(){
        console.log("数据更新之后:updated");
    },
    beforeDestory(){
        // 将组件中需要清除掉的在次函数中清除
        // 定时器、持续事件、组件数据清空、清除未完成的网络请求
        console.log("组件销毁之前:beforeDestory");
    },
    destoryed(){
        console.log("组件销毁之后:destoryed");
    }
};
</script>

directiveComponent.vue

<template>
    <div>
        自定义指令
        <input v-focus type="text">
        <p v-red>{{ msg }}</p>
        <button @click=" msg = '嘿嘿嘿' ">修改</button>
    </div>
</template>
<script>
export default {
    name:"dir",
    data(){
        return{
            msg:"哈哈哈哈"
        }
    },
    // 局部指令,只能在当前组件中使用
    directives:{
        focus:{
            inserted(el){
                el.focus();
            }
        },
        red:{
            bind(el,binding,vnode,oldVnode){
                console.log("初始化");
            },
            inserted(el,binding,vnode,oldVnode){
                el.style.color = '#ff0000'
            },
            update(el,binding,vnode,oldVnode){
                console.log("指令有更新的时候调用");
            },
            componentUpdated(el,binding,vnode,oldVnode){
                console.log("指令有更新的时候调用!!");
            },
            unbind(el,binding,vnode,oldVnode){
                console.log("解绑调用");
            }
        }
    }
}
</script>

filterComponent.vue

<template>
    <div>
        filter过滤器:
        <span>{{ money | rmb }}</span>
        <p>{{ text | author | rmb}}</p>
    </div>
</template>

<script>
export default {
    data(){
        return{
            money:"101.00",
            text:"喧闹任其喧闹,自由我自为知,我自风情万种,与世无争"
        }
    },
    filters:{
        author(value){
            if(value){
                return value +"  ____  陈果"
            }
        }
    }
}
</script>

<style>

</style>

MyComponent.vue

<template>
    <div>
        MyComponent:{{ title }}:{{ age }}
        <ul>
            <li v-for="(item,index) in banner" :key="index">{{item }}</li>
        </ul>
        <p v-if="user">{{ user.username }}</p>
    </div>
</template>
<script>
export default {
    name:"MyComponent",
    data(){
        return{

        }
    },
    // props:["title"]
    props:{
        title:{
            type:Number
        },
        age:{
            type:[Number,String],
            default:1
        },
        banner:{
            type:Array,
            required:true
        },
        user:{
            type:Object,
            default:function(){
                return{
                    username:"iwen"
                }
            }
        }
    }
}
</script>
<style lang="less" scoped>

li{
    list-style: none;
}

</style>

renderComponent.vue

<script>
export default {
    name:"RenderComponent",
    data(){
        return{
            count:10,
            username:''
        }
    },
    methods:{
        clicikHandle(){
            this.count += 1
        }
    },
    render(){
        return(
            <div>
                Render函数:{ this.count }
                <button onClick={ this.clicikHandle }>按钮</button>
                <div>{ this.$slots.default }</div>
                <input v-model={this.username} />
                <p>{ this.username }</p>
            </div>
        )
    }
}
</script>

作为引入的js
registerServiceWorker.js

/* eslint-disable no-console */

import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready () {
      console.log(
        'App is being served from cache by a service worker.\n' +
        'For more details, visit https://goo.gl/AFskqB'
      )
    },
    registered () {
      console.log('Service worker has been registered.')
    },
    cached () {
      console.log('Content has been cached for offline use.')
    },
    updatefound () {
      console.log('New content is downloading.')
    },
    updated () {
      console.log('New content is available; please refresh.')
    },
    offline () {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error (error) {
      console.error('Error during service worker registration:', error)
    }
  })
}

components/group/
Child.vue

<template>
    <div>
        Child
        <input type="text" v-model="username" @keyup="changeHandle">
        <p>{{ username }}</p>
        <button @click="sendMsgHandle">发送数据</button>
        <button @click="sendMsg2Handle">发送数据2</button>
    </div>
</template>
<script>
export default {
    name:"Child",
    data(){
        return{
            msg:[1,2,3],
            username:"",
            msg2:"数据"
        }
    },
    methods:{
        sendMsgHandle(){
            this.$emit('onEvent',this.msg)
        },
        changeHandle(){
            this.$emit("myChange",this.username)
        },
        sendMsg2Handle(){
            this.$emit("update:msg2Event",this.msg2)
        }
    }
}
</script>

components/group/
Parent.vue

<template>
    <div>
        Parent:{{ msg }}:{{ username }}:{{ msg2 }}
        <!-- <Child @update:msg2Event="getMsg2Handle" @onEvent="getMsgHandle" @myChange="getChangeHandle"/> -->
        <Child :msg2Event.sync="msg2" @onEvent="getMsgHandle" @myChange="getChangeHandle"/>
    </div>
</template>
<script>

import Child from "./Child"

export default {
    name:"Parent",
    data(){
        return{
            msg:"",
            username:"",
            msg2:""
        }
    },
    components:{
        Child
    },
    methods:{
        getMsgHandle(data){
            this.msg = data
        },
        getChangeHandle(data){
            this.username = data
        },
        getMsg2Handle(data){
            console.log(data);
        }
    }
}
</script>

components/pages/
HomePage.vue

<template>
    <div>
        Home:{{ msg }}
        <button @click="msg = '我是修改之后的数据'">修改数据</button>
    </div>
</template>
<script>
export default {
    name:"Home",
    data(){
        return{
            msg:"我是修改之前的数据"
        }
    }
}
</script>

components/pages/
UserPage.vue

<template>
    <div>
        User:{{ msg }}
        <button @click="msg = '哈哈哈哈'">修改数据</button>
    </div>
</template>
<script>
export default {
    name:"User",
    data(){
        return{
            msg:"呵呵呵呵"
        }
    }
}
</script>

components/slotComponents/
SlotChild.vue

<template>
    <div>
        <slot :user="user"></slot>
        <slot name="head" :msg="msg">我是默认值1</slot>
        SlotChild
        <slot name='foot'>我是默认值2</slot>
        <p>{{ $parent.message }}</p>
    </div>
</template>
<script>
export default {
    name:"SlotChild",
    data(){
        return{
            msg:"我是插槽数据",
            user:{
                name:"iwens"
            }
        }
    }
}
</script>

components/slotComponents/
SlotParent.vue

<template>
    <div>
        SlotParent
        <SlotChild>
            <template v-slot:head="slotProps">
                <h3>我是头部{{ demo }}:{{ slotProps.msg }}</h3>
            </template>
            <template #foot>
                <h3>我是底部{{ demo }}</h3>
            </template>
            <template v-slot:default="{ user }">
                <h3>哈哈哈:{{ user.name }}</h3>
            </template>
            <!-- <template slot="default" slot-scope="slotProps">
                <h3>哈哈哈:{{ slotProps.user.name }}</h3>
            </template> -->
        </SlotChild>
    </div>
</template>
<script>
import SlotChild from "./SlotChild";

export default {
    name: "SlotParent",
    data() {
        return {
            demo: "我是demo",
            message:"我是SlotParent的数据!!"
        };
    },
    components: {
        SlotChild
    }
};
</script>

运行效果图
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1020210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「聊设计模式」之抽象工厂模式(Abstract Factory)

&#x1f3c6;本文收录于《聊设计模式》专栏&#xff0c;专门攻坚指数级提升&#xff0c;助你一臂之力&#xff0c;带你早日登顶&#x1f680;&#xff0c;欢迎持续关注&&收藏&&订阅&#xff01; 前言 在软件开发中&#xff0c;设计模式是一种被广泛使用的经验…

kudu 1.4.0 离线安装

1.准备rpm安装包 kudu-1.4.0: kudu的基础安装包 kudu-client0-1.4.0: kudu的c++客户端共享库 kudu-client-devel-1.4.0: kudu的c++客户端共享库sdk kudu-master-1.4.0: kudu master kudu-tserver-1.4.0: kudu tserver

任意输入一个整数m,若m不是素数,则对m进行质因数分解,并以质因数从小到大顺序排列的乘积形式输出

每个合数都可以写成几个质数&#xff08;也可称为素数&#xff09;相乘的形式 &#xff0c;这几个质数就都叫做这个合数的质因数。 #include <stdio.h> int isPrime(int num)// 判断一个数是否是素数 {if (num < 2) {return 0;}for (int i 2; i * i < num; i) {…

汽车电子 -- CAN总线波特率计算方法

上一篇文章介绍 PCAN View 安装与使用 的时候&#xff0c;留下了两个问题&#xff0c;CAN总线波特率该怎么计算&#xff1f; 下图里的这些 Prescaler、tseg1、tseg2、sync Jump Width是什么意思&#xff1f; CAN2.0协议中定义标称位速率为一理想的发送器在没有重新同步的情况…

2023年毫米波行业研究报告

第一章 行业概况 1.1 定义 毫米波是一种电磁波&#xff0c;其波长范围在1毫米至10毫米之间&#xff0c;频率介于30GHz至300GHz。与sub-6G (6GHz以下频段&#xff09;的5G系统相比&#xff0c;5G毫米波通信在带宽、时延和灵活弹性空口配置方面具有明显优势。这使其能够有效地满…

风车时间锁管理 - 构建IPA文件加锁+签名+管理一站式解决方案

时间锁管理&#xff1a;是一种用于控制对某些资源、功能或操作的访问权限的机制&#xff0c;它通过设定时间限制来限制对特定内容、系统或功能的访问或执行&#xff0c;以提高安全性和控制性&#xff0c;时间锁管理常见于以下场景&#xff1a; 1. 文件或文档的保密性&#xff…

STL list

文章目录 一、list 类的模拟实现 list 是一个带头双向循环链表&#xff0c;可以存储任意类型 模板参数 T 表示存储元素的类型&#xff0c;Alloc 是空间配置器&#xff0c;一般不用传 一、list 类的模拟实现 iterator 和 const_iterator 除了下述不同外&#xff0c;其他代码基…

优优嗨聚集团:抖音外卖转为区域代理,美团外卖是否胜利

在外卖市场日益激烈的竞争中&#xff0c;抖音和美团两大巨头都有着不同的策略。近期&#xff0c;抖音外卖宣布转为区域代理模式&#xff0c;而美团外卖则持续扩大市场份额。 外卖市场近年来呈现出爆炸性增长&#xff0c;成为消费者日常生活中不可或缺的一部分。根据艾媒咨询数据…

Unity之手游UI的点击和方向移动

一 Button的点击 1.1 新建UI -> Button 1.2 在Button上面右击添加空物体 1.3 创建脚本挂载到空物体上面 脚本内容添加点击方法&#xff0c;来控制物体的显示隐藏 using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using Unit…

Keepalived+LVS负载均衡

Keepalived 是一个用于实现高可用性的开源软件&#xff0c;它基于 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议&#xff0c;允许多台服务器协同工作&#xff0c;以确保在某个服务器出现故障时服务的连续性。Keepalived 的核心思想是将多台服务器配置成…

剑指offer(C++)-JZ67:把字符串转换成整数atoi(算法-模拟)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 写一个函数 StrToInt&#xff0c;实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。…

8种LED显示屏的安装方式

LED显示屏可以根据不同的应用需求和场地条件采用多种安装方式。 LED显示屏的常见安装方式包括&#xff1a; 立柱式&#xff1a;一般多用于大厦门口、大楼大厅等户外场所&#xff0c;可以抵抗风雨侵蚀&#xff0c;更适用于户外广告牌的使用。安装方式有单立柱安装、双立柱安装和…

联合matlab和Arcgis进行netcdf格式的雪覆盖数据的重新投影栅格

图片摘要 本专栏目的是将netcdf格式的雪覆盖数据进行重新投影&#xff0c;需要使用的工具包括matlab和Arcgis&#xff0c;下面进入正题。 1.数据的下载与读取---matlab 最近我需要读取北半球的冰雪覆盖数据&#xff0c;下载的是MODIS/Terra Snow Cover Monthly L3 Global 0.0…

CPU的各种存储器接口

设计电路时往往绕不开要做一些内存或者外存的接口设计&#xff0c;比如接SDRAM、NAND FLASH等等。这些无非是为了扩展原来CPU的内存或者外存资源&#xff0c;方便运行更大的系统。比较常见的就是一些Linux的核心板。I.MX6这个就是很多产品设计中使用的。 那么&#xff0c;在这些…

uniapp 可输入可选择的........框

安装 uniapp: uni-combox地址 vue页面 <uni-combox :border"false" input"selectname" focus"handleFocus" blur"handleBlur" :candidates"candidates" placeholder"请选择姓名" v-model"name"&g…

基于JAVA+SpringBoot+Vue+协同过滤算法+爬虫的前后端分离的租房系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着城市化进程的加快…

Linux下运行Jmeter压测

一、在Linux服务器先安装SDK 1、先从官网下载jdk1.8.0_131.tar.gz&#xff0c;再从本地上传到Linux服务器 2、解压&#xff1a;tar -xzf jdk1.8.0_131.tar.gz&#xff0c;生成文件夹 jdk1.8.0_131 3、在/usr/目录下创建java文件夹&#xff0c;再将 jdk1.8.0_131目录移动到/u…

2023 Google 开发者大会:Web平台新动向

目录 前言一、Open in WordPress playground二、WebGPU三、新的核心 Web 指标INP四、Webview1、Custom Tabs2、JavaScriptEngine 五、Passkeys六、View Transitions API七、Google Chrome开发者工具优化1、覆盖HTTP的响应标头2、改变stack trance 八、Baseline总结 前言 在前不…

会员管理系统实战开发教程07-会员消费

上一篇我们讲解了会员的充值&#xff0c;会员消费和充值的逻辑类似&#xff0c;也是先记录消费金额&#xff0c;然后给会员卡余额减去消费金额&#xff0c;有个逻辑是如果余额不足需要提示信息。 1 创建消费记录表 我们先需要创建表来保存会员的消费记录信息&#xff0c;打开…

讲座2:神经编码与解码

视频来源&#xff1a; 1、面向类脑视觉的生物视觉编码机制和模型&#xff08;余肇飞&#xff09;https://www.bilibili.com/video/BV1rR4y1K7KW/?spm_id_from333.337.search-card.all.click&vd_source897075bbdd61e45006d749612d05a2ab 2、基于视觉编解码的深度学习类脑机…