• vue学习-02vue入门之组件


    删除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">
        
        <ul>
          <li>helloli>
          <li>worldli>
        ul>
        <hr>
        
        <hr>
        
        <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>
        
        <hr>
        
        <hr>
        
        <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    index.js

    import Vue from "vue"
    
    Vue.filter('rmb', (value) => {
        // value就是{{}}或者v-bind绑定的值
        if (value) {
            return "¥" + value
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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'
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    AnimComponent.vue

    <template>
        <div>
            <div>
                <button @click="flag = !flag">切换button>
                <transition name="fade">
                    <p v-if="flag">HelloAnimp>
                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">HelloAnimp>
                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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    作为引入的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)
        }
      })
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    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">发送数据2button>
        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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    components/group/
    Parent.vue

    <template>
        <div>
            Parent:{{ msg }}:{{ username }}:{{ msg2 }}
            
            <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    components/pages/
    HomePage.vue

    <template>
        <div>
            Home:{{ msg }}
            <button @click="msg = '我是修改之后的数据'">修改数据button>
        div>
    template>
    <script>
    export default {
        name:"Home",
        data(){
            return{
                msg:"我是修改之前的数据"
            }
        }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    components/pages/
    UserPage.vue

    <template>
        <div>
            User:{{ msg }}
            <button @click="msg = '哈哈哈哈'">修改数据button>
        div>
    template>
    <script>
    export default {
        name:"User",
        data(){
            return{
                msg:"呵呵呵呵"
            }
        }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    components/slotComponents/
    SlotChild.vue

    <template>
        <div>
            <slot :user="user">slot>
            <slot name="head" :msg="msg">我是默认值1slot>
            SlotChild
            <slot name='foot'>我是默认值2slot>
            <p>{{ $parent.message }}p>
        div>
    template>
    <script>
    export default {
        name:"SlotChild",
        data(){
            return{
                msg:"我是插槽数据",
                user:{
                    name:"iwens"
                }
            }
        }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    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>
                { slotProps.user.name }}
                 -->
            SlotChild>
        div>
    template>
    <script>
    import SlotChild from "./SlotChild";
    
    export default {
        name: "SlotParent",
        data() {
            return {
                demo: "我是demo",
                message:"我是SlotParent的数据!!"
            };
        },
        components: {
            SlotChild
        }
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

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

  • 相关阅读:
    this.$nextTick()的使用场景
    趋势分析是什么?市场趋势分析的经典方法,从数据中识别机会
    信息系统项目管理师 第四版 第17章 项目干系人管理
    CSP-S 2022 题解
    【Axure】axure rp 导入元件库和使用,主流元件库下载使用
    在 Idea 中配置远程 tomcat 并部署
    app自动化测试
    阿里云通用算力型u1云服务器配置性能评测及价格参考
    识别手势语言
    ESP8266-Arduino编程实例-带MAX6675放大器的K型热电偶驱动
  • 原文地址:https://blog.csdn.net/qq_45922256/article/details/132993717