Vue学习总结-组件

组件化和模块化的区别

模块化:从代码逻辑角度划分,方便代码分层开发,保证每个功能模块的职能单一
组件化:从UI界面角度划分

组件-组件的创建方式1

在这里插入图片描述

组件-组件的创建方式2

在这里插入图片描述
在这里插入图片描述

组件-组件的创建方式3

在这里插入图片描述

组件-组件中的data

在这里插入图片描述
在这里插入图片描述

组件切换-使用v-if和v-else结合flag进行切换

在这里插入图片描述

组件切换-使用Vue提供的component元素实现组件切换

在这里插入图片描述

<template>
  <div id="app">
<!--    <img src="./assets/logo.png">-->
<!--    <router-link to="/About">Go to About</router-link>-->
<!--    <router-link to="/helloWorld">Go to HelloWorld</router-link>-->


    <a href="" @click.prevent="comNAme='About'">关于</a>
    <a href="" @click.prevent="comNAme='HelloWorld'">你好</a>
    <component :is="comNAme"> </component>
  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return{
          comNAme:'About',
      }

    }
}
</script>

组件切换-应用切换动画和mode方式

<template>
  <div id="app">
<!--    <img src="./assets/logo.png">-->
<!--    <router-link to="/About">Go to About</router-link>-->
<!--    <router-link to="/helloWorld">Go to HelloWorld</router-link>-->


    <a href="" @click.prevent="comNAme='About'">关于</a>
    <a href="" @click.prevent="comNAme='HelloWorld'">你好</a>
<!--    通过mode属性,设置组件切换时候的 模式-->
    <transition mode="out-in">
      <component :is="comNAme"> </component>
    </transition>

  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return{
          comNAme:About,
      }

    }
}
</script>

<style>
  .v-enter,
  .v-leave-to{
    opacity: 0;
    transform: translateX(150px);
  }
   v-enter-active,
   v-leave-active{
     transition: all 0.5s ease;
   }

</style>

动画-小球动画flag标识符的作用分析

<template>
  <div>
    <!--    需求:点击h3显示,再点击h3消失-->
    <input type="button" value="加入购物车" @click="flag=!flag">
<!--    <input type="text" :value="msg">-->

    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter">
      <div class="ball" v-show="flag"></div>
    </transition>
  </div>

</template>

<script>
    export default {
        name: 'HelloWorld',
        data() {
            return {
                flag: false,

            }
        },
        methods: {
            //注意:动画钩子函数第一个参数:el要执行动画的那个DOM元素,是原生的JS DOM对象
            beforeEnter(el) {
                //表示动画入场前,此时动画尚未开始,可以在beforeEnter中设置开始动画之前的起始样式
                //    设置小球开始动画的起始位置
                el.style.transform = 'translate(0px,0px)'
            },
            enter(el, done) {
                //没有实际作用,不写动画效果出不来,可认为会强制动画刷新
                el.offsetWidth
                //    动画开始之后的样式,可设置小球完成动画后的结束状态
                el.style.transform = 'translate(150px, 450px)'
                el.style.transition = 'all 1s ease'

                //done其实就是afterEnter这个函数,也就是说done是afterEnter的引用
                //动画完成后立即消失
                 done()
            },
            afterEnter(el) {
                //    动画完成后调用
                //第一个功能:控制小球的显示与隐藏
                //第2个功能:直接跳过后半场动画,让flag=false
                //当第二次点击按钮时候,flag  false->true
                this.flag = !this.flag
                // el.style.opacity = 0.5
            //vue把一个完整的动画,使用钩子函数拆分为2部分
            //    我们使用flag标识符表示动画的切换
            //    刚一开始flag=fase,->true  ->false

            }
        }

    }
</script>

<style>
  .ball {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background-color: #42b983;
  }
</style>


组件传值-父组件向子组件传值和data与props的区别

父组件

<template>
  <div id="app">
<!--    父组件,可以在引用子组件的时候,通过属性绑定(v-bind:)形式
把需要传递给子组件的数据,以属性绑定形式传到子组件内部,供子组件使用-->
    <HelloWorld v-bind:parentmsg="appmsg"></HelloWorld>
  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    //包含的子组件如下
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return{
          appmsg:"APP 父组件中的变量",
          comNAme:About,
      }

    }
}
</script>

子组件

<template>
<!--  子组件中,默认无法访问到父组件中的data上的数据和methods中的方法-->
  <div>
<h3>{{parentmsg}}</h3>

  </div>

</template>

<script>
    export default {
        name: 'HelloWorld',
        //注意:组件中所有props中的数据,都是通过父组件传递给子组件的
        //把父组件传递过来的parentmsg属性,西安在props数组中定义一下,这样才能使用该数据
        //props只读的,data中数据可读可写
        props:['parentmsg'],
        data() {//这些子组件中的data数据,是子组件私有的,通过Ajax请求回来的数据,都可以放到data上
            return {

            }
        },
        methods: {
        }

    }
</script>

<style>

</style>



组件传值-子组件通过事件调用向父组件传值

父组件

<template>
  <div id="app">
<!--    <img src="./assets/logo.png">-->
<!--    <router-link to="/About">Go to About</router-link>-->
<!--    <router-link to="/helloWorld">Go to HelloWorld</router-link>-->
<!--    <router-view></router-view>-->
<!--    父组件,可以在引用子组件的时候,通过属性绑定(v-bind:)形式
把需要传递给子组件的数据,以属性绑定形式传到子组件内部,供子组件使用-->
<!--    父组件向子组件传递方法,使用事件绑定机制:v-on-->
    <HelloWorld v-bind:parentmsg="appmsg" @func="show"></HelloWorld>



<!--    <a href="" @click.prevent="comNAme='About'">关于</a>-->
<!--    <a href="" @click.prevent="comNAme='HelloWorld'">你好</a>-->
<!--&lt;!&ndash;    通过mode属性,设置组件切换时候的 模式&ndash;&gt;-->
<!--    <transition mode="out-in">-->
<!--      <component :is="comNAme"> </component>-->
<!--    </transition>-->

  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    //包含的子组件如下
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return{
          appmsg:"APP 父组件中的变量",
          comNAme:About,
          dataformson:null
      }
    },
    methods:{
        show(data1){
            console.log('调用了父组件身上的show方法:---'+data1)
            this.dataformson = data1
        }
    }
}
</script>

<style scoped>

</style>

子组件

<template>
  <!--  子组件中,默认无法访问到父组件中的data上的数据和methods中的方法-->
  <div>
    <h1>这是子组件</h1>
    <h3>{{parentmsg}}</h3>
    <input type="button" value="这是子组件的按钮,点击触发父组件传过来的fun方法" @click="myclick">

  </div>

</template>

<script>
    export default {
        name: 'HelloWorld',
        //注意:组件中所有props中的数据,都是通过父组件传递给子组件的
        //把父组件传递过来的parentmsg属性,西安在props数组中定义一下,这样才能使用该数据
        //props只读的,data中数据可读可写
        props: ['parentmsg'],
        data() {//这些子组件中的data数据,是子组件私有的,通过Ajax请求回来的数据,都可以放到data上
            return {
                sonmsg:{name:'小头儿子',age:4}
            }
        },
        methods: {
            myclick() {
                //    当碘酒子组件按钮时,如何拿到父组件传递过来的方法,拿到并调用
                //    emit:触发,调用,发射的意思
                this.$emit('func', this.sonmsg)
            }
        }

    }
</script>

<style>

</style>


组件案例-发表评论功能的实现,自动刷新列表

效果图

在这里插入图片描述

父组件

<template>
  <div id="app">
<HelloWorld @func="loadComments"></HelloWorld>
    <ul class="list-group">
      <li class="list-group-item" v-for="(item,i) in list" :key="i">
        <span class="badge">评论人:{{item.user}}-----</span>
        {{item.content}}
      </li>

    </ul>

  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    //包含的子组件如下
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return{
          list:[
              {id:Date.now(),user:'李白',content:'天生我才必有用'},
              {id:Date.now(),user:'江白',content:'你好你hi你hii'},
              {id:Date.now(),user:'双方都',content:'撒地方东风风光'}
          ]
      }
    },
    beforeCreate(){
    //这里不能调用loadComments方法,因为在执行这个钩子函数时候,因为data和methods还没初始化完成
    },
    created(){
        this.loadComments()
    },
    methods:{
        loadComments() {
            var list = JSON.parse(localStorage.getItem('cmts') || '[]')
            this.list = list
        }
    }
}
</script>

<style scoped>

</style>

子组件

<template>
  <!--  子组件中,默认无法访问到父组件中的data上的数据和methods中的方法-->
  <div>
    <div class="form-group">
      <label>评论人:</label>
      <input type="text" class="form-control" v-model="user">
    </div>

    <div class="form-group">
      <label>评论内容:</label>
      <textarea class="form-control" v-model="content"></textarea>
    </div>

    <div class="form-group">
      <label></label>
      <input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
    </div>


  </div>

</template>

<script>
    export default {
        name: 'HelloWorld',

        data() {
            return {
                user: '',
                content: '',


            }
        },
        methods: {
            postComment() {
            //1评论数据存放到了localStroage中,localStroage.setItem('cmts','')
            //    2先组织出一个最新的评论数据对象
            //    3想办法把第二步中得到的对象保存到localStroage
            //    3.1localStroage只支持存放字符串数据,要先调用JSON.stringify
            //    3.2在保存最新的评论数据之前,
                //    要先从localStroage获取到之前的评论数据,转换为一个数组对象,然后把最新的评论push到这个数组
            //    3.3如果获取到的localStroage中的字符串为空,则返回'[]',让JSON.parse转换
            //    3.4把最新的评论列表数组,再次调用JSON.stringify转为数组字符串,然后调用localStroage.setItem
                var comment ={id:Date.now(),user:this.user,content:this.content}
                //localStorage从获取所有评论
                var list = JSON.parse(localStorage.getItem('cmts')|| '[]')
                list.unshift(comment)
                //保存最新的评论
                localStorage.setItem('cmts',JSON.stringify(list))
                this.user=''
                this.content=''
                this.$emit('func')

            }
        }

    }
</script>

<style>

</style>


使用ref获取DOM元素和组件引用

效果
在这里插入图片描述

父组件

<template>
  <div id="app">

    <input type="button" value="获取元素" @click="getElement" ref="mybtn">
    <h3 id="myh3" ref="myh3">哈哈哈哈胜多负少的</h3>
<hr>
    <HelloWorld ref="myLogin"></HelloWorld>
  </div>
</template>

<script>

  import About from "./components/About.vue"
  import HelloWorld from "./components/HelloWorld.vue";
export default {
    //包含的子组件如下
    components:{
        About,
        HelloWorld
    },
    name: 'App',
    data:function () {
      return {

      }

    },

    methods:{
        getElement(){
            // console.log(document.getElementById('myh3').innerText)
            console.log(this.$refs.myh3.innerText)
            console.log(this.$refs.myLogin.msg)
            this.$refs.myLogin.show()
        }
    }
}
</script>

<style scoped>

</style>

子组件

<template>
  <div>
<h1>登录组件</h1>

  </div>

</template>

<script>
    export default {
        name: 'HelloWorld',

        data() {
            return {
                msg:'son msg'
            }
        },
        methods: {
show(){
    console.log('调用了子组件')
}
        }

    }
</script>

<style>

</style>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值