Vue学习笔记day03总结

目录

1.使用Vue-resource实现品牌的增删查功能

2.动画

2.1使用过度类名实现动画

2.2自定义v-前缀

2.3使用第三方animate.css类实现动画

2.4钩子函数实现半场动画

2.5使用transition-group元素实现列表动画

3. 组件

3.1组件的创建方式(推荐使用第3种)

3.1.1创建方式1

3.1.2创建方式2

3.1.3创建方式3(推荐)

3.2组件中的data

3.3组件切换

3.3.1切换方式1(通过flag标记变量进行切换)

3.3.2切换方式2(通过component 标签进行切换)--推荐

3.3.3切换动画

3.4 组件传值

3.4.1 父组件向子组件传值

3.4.2 父组件向子组件传方法

 


1.使用Vue-resource实现品牌的增删查功能

  •  
      <script>
        // 如果我们通过全局配置了,请求的数据接口 根域名,则 ,在每次单独发起 http 请求的时候,请求的 url 路径,应该以相对路径开头,前面不能带 /  ,否则 不会启用根路径做拼接;
        Vue.http.options.root = 'http://vue.studyit.io/';
        // 全局启用 emulateJSON 选项
        Vue.http.options.emulateJSON = true;
    
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            name: '',
            list: [ // 存放所有品牌列表的数组
            ]
          },
          created() { // 当 vm 实例 的 data 和 methods 初始化完毕后,vm实例会自动执行created 这个生命周期函数
            this.getAllList()
          },
          methods: {
            getAllList() { // 获取所有的品牌列表 
              // 分析:
              // 1. 由于已经导入了 Vue-resource这个包,所以 ,可以直接通过  this.$http 来发起数据请求
              // 2. 根据接口API文档,知道,获取列表的时候,应该发起一个 get 请求
              // 3. this.$http.get('url').then(function(result){})
              // 4. 当通过 then 指定回调函数之后,在回调函数中,可以拿到数据服务器返回的 result
              // 5. 先判断 result.status 是否等于0,如果等于0,就成功了,可以 把 result.message 赋值给 this.list ; 如果不等于0,可以弹框提醒,获取数据失败!
    
              this.$http.get('api/getprodlist').then(result => {
                // 注意: 通过 $http 获取到的数据,都在 result.body 中放着
                var result = result.body
                if (result.status === 0) {
                  // 成功了
                  this.list = result.message
                } else {
                  // 失败了
                  alert('获取数据失败!')
                }
              })
            },
            add() {  // 添加品牌列表到后台服务器
              // 分析:
              // 1. 听过查看 数据API接口,发现,要发送一个 Post 请求,  this.$http.post
              // 2. this.$http.post() 中接收三个参数:
              //   2.1 第一个参数: 要请求的URL地址
              //   2.2 第二个参数: 要提交给服务器的数据 ,要以对象形式提交给服务器 { name: this.name }
              //   3.3 第三个参数: 是一个配置对象,要以哪种表单数据类型提交过去, { emulateJSON: true }, 以普通表单格式,将数据提交给服务器 application/x-www-form-urlencoded
              // 3. 在 post 方法中,使用 .then 来设置成功的回调函数,如果想要拿到成功的结果,需要 result.body
    
              this.$http.post('api/addproduct', { name: this.name }).then(result => {
                if (result.body.status === 0) {
                  // 成功了!
                  // 添加完成后,只需要手动,再调用一下 getAllList 就能刷新品牌列表了
                  this.getAllList()
                  // 清空 name 
                  this.name = ''
                } else {
                  // 失败了
                  alert('添加失败!')
                }
              })
            },
            del(id) { // 删除品牌
              this.$http.get('api/delproduct/' + id).then(result => {
                if (result.body.status === 0) {
                  // 删除成功
                  this.getAllList()
                } else {
                  alert('删除失败!')
                }
              })
            }
          }
        });
      </script>

     

2.动画

2.1使用过度类名实现动画

  • 使用 transition 元素,把 需要被动画控制的元素,包裹起来(transition 元素,是 Vue 官方提供的)
    •     <input type="button" value="toggle" @click="flag=!flag">
          <!-- 需求: 点击按钮,让 h3 显示,再点击,让 h3 隐藏 -->
          <!-- 1. 使用 transition 元素,把 需要被动画控制的元素,包裹起来 -->
          <!-- transition 元素,是 Vue 官方提供的 -->
          <transition>
            <h3 v-if="flag">这是一个H3</h3>
          </transition>

       

  • 放在<style></style>标签中
    •  
        <!-- 2. 自定义两组样式,来控制 transition 内部的元素实现动画 -->
        <style>
          /* v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入 */
          /* v-leave-to 【这是一个时间点】 是动画离开之后,离开的终止状态,此时,元素 动画已经结束了 */
          .v-enter,
          .v-leave-to {
            opacity: 0;
            transform: translateX(150px);
          }
      
          /* v-enter-active 【入场动画的时间段】 */
          /* v-leave-active 【离场动画的时间段】 */
          .v-enter-active,
          .v-leave-active{
            transition: all 0.8s ease;
          }
        </style>

2.2自定义v-前缀

  •  将style标签中的“ v- ”修改为所要控制标签对应的name属性值
    •  
        <!-- 2. 自定义两组样式,来控制 transition 内部的元素实现动画 -->
        <style>
          .my-enter,
          .my-leave-to {
            opacity: 0;
            transform: translateY(70px);
          }
      
          .my-enter-active,
          .my-leave-active{
            transition: all 0.8s ease;
          }
        </style>

       

  • Html
  •     <input type="button" value="toggle2" @click="flag2=!flag2">
        <transition name="my">
          <h6 v-if="flag2">这是一个H6</h6>
        </transition>

2.3使用第三方animate.css类实现动画

  •  引用<link rel="stylesheet" href="./lib/animate.css">
  •  在transition标签上加上动画样式
  • 在作用标签上加上class="animated" ,否则不起作用。
  • 使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长
  • 使用  :duration="{ enter: 200, leave: 400 }"  来分别设置 入场的时长 和 离场的时长
  •     <transition 
        enter-active-class="bounceIn" 
        leave-active-class="bounceOut" 
        :duration="{ enter: 200, leave: 400 }">
          <h3 v-if="flag" class="animated">这是一个H3</h3>
        </transition> 

     

2.4钩子函数实现半场动画

  • el.style.transform = "translate(0, 0)" :设置小球开始动画之前的,起始位置
  • el.offsetWidth :这句话,没有实际的作用,但是,如果不写,出不来动画效果;可以认为 el.offsetWidth 会强制动画刷新
  • done() :这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
  •   <style>
        .ball {
          width: 15px;
          height: 15px;
          border-radius: 50%;
          background-color: red;
        }
      </style>
    
      <div id="app">
        <input type="button" value="快到碗里来" @click="flag=!flag">
        <!-- 1. 使用 transition 元素把 小球包裹起来 -->
        <transition
          @before-enter="beforeEnter"
          @enter="enter"
          @after-enter="afterEnter">
          <div class="ball" v-show="flag"></div>
        </transition>
      </div>
    
      <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            flag: false
          },
          methods: {
            // 注意: 动画钩子函数的第一个参数:el,表示 要执行动画的那个DOM元素,是个原生的 JS DOM对象
            // 大家可以认为 , el 是通过 document.getElementById('') 方式获取到的原生JS DOM对象
            beforeEnter(el){
              // beforeEnter 表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式
              // 设置小球开始动画之前的,起始位置
              el.style.transform = "translate(0, 0)"
            },
            enter(el, done){
              // 这句话,没有实际的作用,但是,如果不写,出不来动画效果;
              // 可以认为 el.offsetWidth 会强制动画刷新
              el.offsetWidth
              // enter 表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态
              el.style.transform = "translate(150px, 450px)"
              el.style.transition = 'all 1s ease'
    
              // 这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
              done()
            },
            afterEnter(el){
              // 动画完成之后,会调用 afterEnter
              // console.log('ok')
              this.flag = !this.flag
            }
          }
        });
      </script>

2.5使用transition-group元素实现列表动画

  •  .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果
  •   如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性
  •  通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签
  •  
      <style>
        li {
          border: 1px dashed #999;
          margin: 5px;
          line-height: 35px;
          padding-left: 5px;
          font-size: 12px;
          width: 100%;
        }
        li:hover {
          background-color: hotpink;
          transition: all 0.8s ease;
        }
        .v-enter,
        .v-leave-to {
          opacity: 0;
          transform: translateY(80px);
        }
        .v-enter-active,
        .v-leave-active {
          transition: all 0.6s ease;
        }
        /* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */
        .v-move {
          transition: all 0.6s ease;
        }
        .v-leave-active{
          position: absolute;
        }
      </style>
    
      <div id="app">
        <div>
          <label>
            Id:
            <input type="text" v-model="id">
          </label>
          <label>
            Name:
            <input type="text" v-model="name">
          </label>
          <input type="button" value="添加" @click="add">
        </div>
        <!-- <ul> -->
          <!-- 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transitionGroup -->
          <!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性 -->
          <!-- 给 ransition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果 -->
          <!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签 -->
          <transition-group appear tag="ul">
            <li v-for="(item, i) in list" :key="item.id" @click="del(i)">
              {{item.id}} --- {{item.name}}
            </li>
          </transition-group>
        <!-- </ul> -->
      </div>
    
      <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            id: '',
            name: '',
            list: [
              { id: 1, name: '赵高' },
              { id: 2, name: '秦桧' },
              { id: 3, name: '严嵩' },
              { id: 4, name: '魏忠贤' }
            ]
          },
          methods: {
            add() {
              this.list.push({ id: this.id, name: this.name })
              this.id = this.name = ''
            },
            del(i) {
              this.list.splice(i, 1)
            }
          }
        });
      </script>

     

3. 组件

3.1组件的创建方式(推荐使用第3种)

3.1.1创建方式1

  •  使用 Vue.component('组件的名称', 创建出来的组件模板对象)
  • 如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接;
     如果不使用驼峰,则直接拿名称来使用即可;
  •  
        // 1.1 使用 Vue.extend 来创建全局的Vue组件
        // var com1 = Vue.extend({
        //   template: '<h3>这是使用 Vue.extend 创建的组件</h3>' // 通过 template 属性,指定了组件要展示的HTML结构
        // })
        // 1.2 使用 Vue.component('组件的名称', 创建出来的组件模板对象)
        // Vue.component('myCom1', com1)
        // 如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰命名,则在引用组件的时候,需要把 大写的驼峰改为小写的字母,同时,两个单词之前,使用 - 链接;
        // 如果不使用驼峰,则直接拿名称来使用即可;
        // Vue.component('mycom1', com1)
    
    //也可以写成:
        // Vue.component 第一个参数:组件的名称,将来在引用组件的时候,就是一个 标签形式 来引入 它的
        // 第二个参数: Vue.extend 创建的组件  ,其中 template 就是组件将来要展示的HTML内容
        Vue.component('mycom1', Vue.extend({
          template: '<h3>这是使用 Vue.extend 创建的组件</h3>'
        }))

     

3.1.2创建方式2

  •  注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素
  •  
        // 注意:不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素
        Vue.component('mycom2', {
          template: '<div><h3>这是直接使用 Vue.component 创建出来的组件</h3><span>123</span></div>'
        })
    

     

3.1.3创建方式3(推荐)

  •  在外部定义的组件结构,这个方式,有代码的智能提示和高亮
  •   <div id="app">
        <mycom3></mycom3>
        <!-- <login></login> -->
      </div>
    
    
      <div id="app2">
        <mycom3></mycom3>
        <login></login>
      </div>
    
      <!-- 在 被控制的 #app 外面,使用 template 元素,定义组件的HTML模板结构  -->
      <template id="tmpl">
        <div>
          <h1>这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮</h1>
          <h4>好用,不错!</h4>
        </div>
      </template>
    
      <template id="tmpl2">
        <h1>这是私有的 login 组件</h1>
      </template>
    
      <script>
        Vue.component('mycom3', {
          template: '#tmpl'
        })
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {},
          methods: {}
        });
        var vm2 = new Vue({
          el: '#app2',
          data: {},
          methods: {},
          filters: {},
          directives: {},
          components: { // 定义实例内部私有组件的
            login: {
              template: '#tmpl2'
            }
          },
          beforeCreate() { },
          created() { },
          beforeMount() { },
          mounted() { },
          beforeUpdate() { },
          updated() { },
          beforeDestroy() { },
          destroyed() { }
        })
      </script>
    

3.2组件中的data

  • 组件可以有自己的 data 数据
  • 组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法
  • 组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
  • 组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样!!!
  •     Vue.component('mycom1', {
          template: '<h1>这是全局组件 --- {{msg}}</h1>',
          data: function () {
            return {
              msg: '这是组件的中data定义的数据'
            }
          }
        })

     

3.3组件切换

3.3.1切换方式1(通过flag标记变量进行切换)

  <div id="app">
    <a href="" @click.prevent="flag=true">登录</a>
    <a href="" @click.prevent="flag=false">注册</a>

    <login v-if="flag"></login>
    <register v-else="flag"></register>

  </div>

  <script>
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })

    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false
      },
      methods: {}
    });
  </script>

 

3.3.2切换方式2(通过component 标签进行切换)--推荐

  <div id="app">
    <a href="" @click.prevent="comName='login'">登录</a>
    <a href="" @click.prevent="comName='register'">注册</a>

    <!-- Vue提供了 component ,来展示对应名称的组件 -->
    <!-- component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称 -->
    <component :is="comName"></component>

    <!-- 总结:当前学习了几个 Vue 提供的标签了??? -->
    <!-- component,  template,  transition,  transitionGroup  -->

  </div>

  <script>
    // 组件名称是 字符串
    Vue.component('login', {
      template: '<h3>登录组件</h3>'
    })

    Vue.component('register', {
      template: '<h3>注册组件</h3>'
    })

    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        comName: 'login' // 当前 component 中的 :is 绑定的组件的名称
      },
      methods: {}
    });
  </script>

 

3.3.3切换动画

  •  通过 mode 属性,设置组件切换时候的模式
  •   <style>
        .v-enter,
        .v-leave-to {
          opacity: 0;
          transform: translateX(150px);
        }
    
        .v-enter-active,
        .v-leave-active {
          transition: all 0.5s ease;
        }
      </style>
    
      <div id="app">
        <a href="" @click.prevent="comName='login'">登录</a>
        <a href="" @click.prevent="comName='register'">注册</a>
    
        <!-- 通过 mode 属性,设置组件切换时候的 模式 -->
        <transition mode="out-in">
          <component :is="comName"></component>
        </transition>
    
      </div>
    
      <script>
        // 组件名称是 字符串
        Vue.component('login', {
          template: '<h3>登录组件</h3>'
        })
    
        Vue.component('register', {
          template: '<h3>注册组件</h3>'
        })
    
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            comName: 'login' // 当前 component 中的 :is 绑定的组件的名称
          },
          methods: {}
        });
      </script>

     

3.4 组件传值

3.4.1 父组件向子组件传值

  •  父组件,可以在引用子组件的时候, 通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用
  •  注意: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
  • 注意: 组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的
  • data 上的数据,都是可读可写的;props 中的数据,都是只读的,无法重新赋值
  •   <div id="app">
        <!-- 父组件,可以在引用子组件的时候, 通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部,供子组件使用 -->
        <com1 v-bind:parentmsg="msg"></com1>
      </div>
    
      <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            msg: '123 啊-父组件中的数据'
          },
          methods: {},
    
          components: {
            // 结论:经过演示,发现,子组件中,默认无法访问到 父组件中的 data 上的数据 和 methods 中的方法
            com1: {
              data() { // 注意: 子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上;
                // data 上的数据,都是可读可写的;
                return {
                  title: '123',
                  content: 'qqq'
                }
              },
              template: '<h1 @click="change">这是子组件 --- {{ parentmsg }}</h1>',
              // 注意: 组件中的 所有 props 中的数据,都是通过 父组件传递给子组件的
              // props 中的数据,都是只读的,无法重新赋值
              props: ['parentmsg'], // 把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
              directives: {},
              filters: {},
              components: {},
              methods: {
                change() {
                  this.parentmsg = '被修改了'
                }
              }
            }
          }
        });

     

3.4.2 父组件向子组件传方法

  •  父组件向子组件 传递 方法,使用的是 事件绑定机制; v-on, 当我们自定义了 一个 事件属性之后,那么,子组件就能够,通过某些方式,来调用传递进去的这个方法了
  •  emit 英文原意: 是触发,调用、发射的意思。子组件调用父组件的方法。
  •   <div id="app">
        <!-- 父组件向子组件 传递 方法,使用的是 事件绑定机制; v-on, 当我们自定义了 一个 事件属性之后,那么,子组件就能够,通过某些方式,来调用 传递进去的 这个 方法了 -->
        <com2 @func="show"></com2>
      </div>
    
      <template id="tmpl">
        <div>
          <h1>这是 子组件</h1>
          <input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
        </div>
      </template>
    
      <script>
        // 定义了一个字面量类型的 组件模板对象
        var com2 = {
          template: '#tmpl', // 通过指定了一个 Id, 表示 说,要去加载 这个指定Id的 template 元素中的内容,当作 组件的HTML结构
          data() {
            return {
              sonmsg: { name: '小头儿子', age: 6 }
            }
          },
          methods: {
            myclick() {
              // 当点击子组件的按钮的时候,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
              //  emit 英文原意: 是触发,调用、发射的意思
              // this.$emit('func123', 123, 456)
              this.$emit('func', this.sonmsg)
            }
          }
        }
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {
            datamsgFormSon: null
          },
          methods: {
            show(data) {
              // console.log('调用了父组件身上的 show 方法: --- ' + data)
              // console.log(data);
              this.datamsgFormSon = data
            }
          },
          components: {
            com2
            // com2: com2
          }
        });
      </script>

     

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值