Vue.js学习

2018-10-01  本文已影响0人  蔡华鹏

一、了解Vue.js

1.1.1 Vue.js是什么?

1.1.2 为什么学习Vue.js?

1.1.3 Vue.js的模式

1.1.4 Vue.js环境搭建

二、数据绑定,指令,事件

2.1.1 vue实例和数据绑定

一、

<script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

通过构造函数Vue就可以创建一个Vue的根实例,并启动Vue应用---入口

var app = new Vue({
  el: '',
  data: {
  }
})

二、
其中必不可少的一个选项就是el,el用于指定一个页面中已存在的DOM元素来挂载Vue实例

三、
通过Vue实例的data选项,可以声明应用内需要双向绑定的数据。建议所有会用到的数据都预先在data内声明,这样不至于将数据散落在业务逻辑中,难以维护。也可以指向一个已经有的变量

四、
挂载成功后,我们可以通过app.$el来访问该元素。Vue提供了很多常用的实例属性与方法,都已 $开头,比如 $el,Vue实例本身也代理了data对象里所有属性,所以可以这样访问

五、
如果是访问data里的属性,用app.属性名

2.1.2

created: 实例穿件完成后调用,此阶段完成了数据的观测等,但尚未挂载,$el还不可用。需要初始化处理一些数据时会比较有用。------还未挂载

mounted: el挂载到实例上后调用,一般我们的第一个业务逻辑会从这里开始。------刚刚挂载

beforeDestroy: 实例销毁之前调用。主要解绑一些使用addEventListener监听的事件等。

2.1.3 文本插值和表达式

语法: 使用双大括号(Mustache语法)"{{ }}"是最基本的文本插值方法,他会自动将我们双向绑定的数据实时显示出来

用法:

2.2.1 过滤器

Vue支持在{{ }}插值的尾部添加一小管道符"|"对数据进行过滤,经常用于格式化文本,比如字母全部大写、货币千位使用逗号分隔等。过滤的规则是自定义的,通过给Vue实例添加选项filters来设置
过滤器:{{data | filter1 | filter2}}
{{data | formatData(1,2)}}中的第一个和第二个参数,分别对应过滤器的第二个和第三个参数

2.2.2 指令和事件

指令( Directives )是 Vue 模板中最常用的一项功能,它带有前缀 v-,能帮我们
快速完成DOM操作。循环渲染。显示和隐藏

2.2.3 语法糖

语法糖是指在不影响功能的情况下 , 添加某种简洁方法实现同样的效果 , 从而更加方便程
序开发。

运用以上知识点,总和一个小demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>demo</title>
    <style>
      .data {
          background: red;
          height: 18px;
      }
    </style>
</head>
<body>
    <div id="app">
        {{name}} <br>
        {{name | formatDate}}
        <br>
        <div v-html="html"></div>
        <span v-text="weather"></span>
        <br>
        <div v-bind:class="className"></div>
        <button v-on:click="click">{{countnum}}</button>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        var plusDate = function(value){
            return value < 10 ? '0' + value : value
        }
      var app = new Vue({
          el : '#app',
          data : {
              name: new Date(),
              html: '<div>你好</div>',
              weather: '今天天气不错',
              className: 'data',
              countnum: 0
          },
          
          filters:{
              formatDate: function(value) {
                  var date = new Date(value)
                  var year = date.getFullYear()
                  var month = plusDate(date.getMonth()+1)
                  var day = plusDate(date.getDate())
                  var hours = plusDate(date.getHours())
                  var min = plusDate(date.getMinutes())
                  var sec = plusDate(date.getSeconds())
                  return year + '--' + month + '--' + day + '  ' + hours + ':' + min + ':' + sec
              }
          },
          mounted: function(){
              var _this = this
              this.timer = setInterval(function(){
                  _this.name = new Date()
              },1000)
          },
          methods: {
              click: function(){
                  this.countnum = this.countnum + 1 
              }
          },
          beforeDestroy: function(){
              clearInterval(this.timer)
          }
      })
    </script>
</body>
</html>

三、 计算属性

3.1 什么是计算属性

我们己经可以搭建出一个简单的 Vue 应用,在模板中双向绑定一些数据或表达式了。但是表达式如果过长,或逻辑更为复杂时,就会变得雕肿甚至难以阅读和维护

<div>
{{ text.split ( ’,’ ) •reverse () . join (’,’)}}
</div>

3.2 计算属性用法

getter和setter

小技巧: 计算属性还有两个很实用的小技巧容易被忽略:

3.3计算属性缓存

调用 methods 里的方法也可以与计算属性起到同样的作用

何时使用: -----------使用计算属性还是 methods 取决于你是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非你不希望得到缓存。

计算属性demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算属性</title>
</head>
<body>
    <div id="data">
        {{fullName}} <br>
        {{watch()}}
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
      var app = new Vue({
          el: '#data',
          data: {
              firstName:'Cai',
              lastName: 'hua'
          },
          computed: {
             fullName: function(){
                  return this.firstName + ' ' + this.lastName
              }
          },
          methods: {
              watch: function(){
                return this.firstName + ' ' + this.lastName
              }
          }
      })
    </script>
</body>
</html>

四、 v-­bind以及class与style的绑定

应用场景: DOM 元素经常会动态地绑定一些 class 类名或 style 样式

4.1 了解bind指令

v-­bind的复习:

4.2 绑定 class 的几种方式

4.2.1 对象语法

4.2.2 数组语法

当需要应用多个 class 时, 可以使用数组语法 , 给:class 绑定一个数组,应用一个 class列表:

4.2.3 在组件上使用 : 暂时不考虑—­挖坑

4.3 绑定内联样式

使用 v­-bind:style (即:style ) 可以给元素绑定内联样式,方法与 :class 类似,也有对象语法和数组语法,看起来很像直接在元素上写 CSS

注意 : css 属性名称使用驼峰命名( came!Case )或短横分隔命名( kebab­case),应用多个样式对象时 , 可以使用数组语法,在实际业务 中,style 的数组语法并不常用 , 因为往往可以写在一个对象里面, 而较为常用 的应当是计算属性

使用 :style 时, Vue .js 会自动给特殊的 css 属性名称增加前缀, 比如 transform 。

无需再加前缀属性!!!!

v-bind绑定demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>v-bind绑定</title>
    <style>
      .divStyle{
          width: 88px;
          height: 88px;
          background: red;
      }
      .borderStyle{
          border: 8px solid black;
      }
      .color{
          color: red;
      }
      .size{
          font-size: 28px;
      }
      .blueClass{
          color: blue;
      }
      .font{
          font-size: 36px;
      }
    </style>
</head>
<body>
    <div id="demo">
        //对象语法 <br>
        <div v-bind:class="{divStyle : isActive, borderStyle : isBorder}"></div>
        <hr>
        //数组语法<br>
        <div v-bind:class="[colorClass,sizeClass]">Hello word</div>
        <hr>
        //对象和数组混用
        <div v-bind:class="[{blueClass : isBlue},fontClass]">你好!</div>
        <hr>
        //绑定内联样式
        <div v-bind:style="{'background':background,'fontSize':fontSize + 'px'}">真好!</div>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
      var app = new Vue({
          el:'#demo',
          data:{
              isActive: true,
              isBorder: true,
              colorClass:"color",
              sizeClass: "size",
              isBlue:true,
              fontClass:"font",
              background: 'red',
              fontSize:'56'
          }
      })
    </script>
</body>
</html>

五、vueJS中的内置指令

5.1 基本指令

5.1.1 v-­cloak一般与display:none进行结合使用

作用:解决初始化慢导致页面闪动的最佳实践

5.1.2 v-­once

定义:它的元素和组件只渲染一次

5.2 条件渲染指令

5.2.1 v-­if, v-­eles-­if ,v-­else

用法: 必须跟着屁股走

v-if的弊端 :
Vue 在渲染元素时 ,出于效率考虑,会尽可能地复用已有的元素而非重新渲染, 因此会出现乌龙,只会渲染变化的元素,也就是说,input元素被复用了

解决方法: 加key,唯一,提供key值可以来决定是否复用该元素

5.2.2 v-­show

v­-if和v­-show的比较

v-­if:

v-­show:

5.3 列表渲染指令v­-for

用法: 当需要将一个数组遍历或枚举一个对象属性的时候循环显示时,就会用到列表渲染指令 v­-for。

两种使用场景:

v-for demo

<body>
    <div id="demo">
            //遍历多个对象一定是遍历的数组
            //带索引的写法:括号的第一个变量,代表item,第二个代表index
        <ul>
            <li v-for="vuestu in vueStudy">{{vuestu.name}}</li>
        </ul>
        <br>
        //遍历一个对象的多个属性
        //拿到value,key,index的写法 v-k-i--外开
        <div v-for="(value,key,index) in women">{{index}}-----{{key}}------{{value}}</div>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
      var app = new Vue({
          el:'#demo',
          data:{
              vueStudy:[
                  //每个对象对应一个li
                  {name:'敲代码'},
                  {name:'看资料'},
                  {name:'看蔡华鹏博客'}
              ],
              women:{
              grid1: '张柏芝',
              grid2: '迪丽热巴',
              grid3: '高圆圆'
          }
          }
      })
    </script>
</body>

5.4 数组更新,过滤与排序

改变数组的一系列方法:

两个数组变动vue检测不到:

  1. 改变数组的指定项
  2. 改变数组长度

改变指定项: Vue.set(app.arr,1,”car”);
app.arr.splice(1): 改变数组长度
过滤:filter

解决方法:

1. set
2. splice

5.5 方法和事件

[object MouseEvent]

5.5.1 基本用法

v-­on绑定的事件类似于原生 的onclick等写法:

methods:{
  handle:function (count) {
    count = count || 1;
    this.count += count;
  }
}

如果方法中带有参数,但是你没有加括号,默认传原生事件对象event

5.5.2 修饰符

可以监听键盘事件:

<input @keyup.13 ="submitMe"> ——­指定的keyCode

vueJS为我们提供了:

.enter
.tab
.delete 等等、、、、、、

六、 表单与v-­model

6.1 基本用法

v­-model:

VUE提供了v­model指令, 用于在表单类元素上双向绑定事件

input和textarea

可以用于input框,以及textarea等

注意: 所显示的值只依赖于所绑定的数据,不再关心初始化时的插入的value

单选按钮:

复选框:

下拉框:

总结一下:
如果是单选,初始化最好给定字符串,因为v­model此时绑定的是静态字符串或者布尔值如果是多选,初始化最好给定一个数组

6.2 绑定值

6.3 修饰符

七、 可复用性的组件详解

7.1 使用组件的原因

7.2 组件的使用方法

1. 全局注册
Vue.component('my-component',{
template:'<div>我是组件的内容</div>'
})
优点:所有的vue实例都可以用
缺点:权限太大,容错率降低
2. 局部注册
var app = new Vue({
  el:'#app',
  components:{
    'my-component':{
      template: '<div>我是组件的内容</div>'
    }
  }
})
3. vue组件的模板在某些情况下会受到html标签的限制,比如 <table> 中只能还有 <tr> , <td> 这些元素,所以直接在table中使用组件是无效的,此时可以使用is属性来挂载组件
<table>
  <tbody is="my-component"></tbody>
</table>

7.3 组件使用的奇淫技巧

7.4 使用props传递数据 父亲向儿子传递数据

7.5 单向数据流

一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。这种情况可以在组件 data 内再声明一个数据,引用父组件的 props
步骤一:注册组件
步骤二:将父组件的数据传递进来,并在子组件中用props接收
步骤三:将传递进来的数据通过初始值保存起来

<div id="app">
<my-comp init-count="666"></my-comp>
</div>
<script>
var app = new Vue({
  el:'#app',
  components:{
    'my-comp':{
      props:['init-count'],
      template:'<div>{{count}}</div>',
      data:function () {
        return{
        count:this.initCount
        }
      }
    }
  }
})
</script>

另一种情况就是 prop 作为需要被转变的原始值传入。这种情况用计算属性就可以了
步骤一:注册组件
步骤二:将父组件的数据传递进来,并在子组件中用props接收
步骤三:将传递进来的数据通过计算属性进行重新计算

<body>
    <div id="data">
        <input type="text" v-model="width">
        <my-conponent :width="width"></my-conponent>
    </div>
    
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
      var app = new Vue({
          el:'#data',
          data:{
              width:''
          },
          components:{
              'my-conponent':{
                props:['width'],
                template:'<div :style="style"></div>',
                computed:{
                  style:function(){
                      return{
                          width:this.width+'px',
                          background:'red',
                          height:'30px'
                      }
                  }
              }
              }
          }
      })
    </script>
</body>

7.6 数据验证

@ 在html中, myMessagemymessage 是一致的,,因此在组件中的html
中使用必须使用kebab-­case(短横线)命名方式。在html中不允许使用驼
峰!!!!!!
@ 在组件中, 父组件给子组件传递数据必须用短横线。在template中,必须使用驼峰命名方式,若为短横线的命名方式。则会直接保错。
@ 在组件的data中,用this.XXX引用时,只能是驼峰命名方式。若为短横线
的命名方式,则会报错。

验证的 type 类型可以是:
Vue.component ( ’ my-compopent ’, {
  props : {
  //必须是数字类型
    propA : Number ,
    //必须是字符串或数字类型
    propB : [String , Number] ,
    //布尔值,如果没有定义,默认值就是 true
    propC: {
      type : Boolean ,
      default : true
    },
    //数字,而且是必传
    propD: {
      type: Number ,
      required : true
    },
    //如果是数组或对象,默认值必须是一个函数来返回
    propE: {
      type : Array ,
      default : function () {
      return [] ;
    }
  },
    //自定义一个验证函数
    propF: {
      validator : function (value) {
      return value > 10;
    }
  }
}
});

7.7 组件通信

组件关系可分为父子组件通信、兄弟组件通信、跨级组件通信

7.7.1 自定义事件—子组件给父组件传递数据

使用v-­on 除了监昕 DOM 事件外,还可以用于组件之间的自定义事件。
JavaScript 的设计模式 一一观察者模式, dispatchEventaddEventListener这两个方法。 Vue 组件也有与之类似的一套模式,子组件用$emit()触发事件 ,父组件用$on()监听子组件的事件
直接来代码

<body>
    <div id="app">
        <p>您好,您现在的银行余额是{{total}}元</p>
        <btn-compnent @change="handleTotal"></btn-compnent>
        <!-- <button-component @change="money"></button-component> -->
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        
        var app = new Vue({
            el: '#app',
            data: {
                total: 0
            },
            components: {
                'btn-compnent': {
                    template: '<div>\
                <button @click="handleincrease">+10000</button> \
                <button @click="handlereduce">-10000</button>\
                </div>',
                    data: function () {
                        return {
                            count: 0
                        }
                    },
                    methods: {
                        handleincrease: function () {
                            this.count = this.count + 10000;
                            this.$emit('change', this.count);
                        },
                        handlereduce: function () {
                            this.count = this.count - 10000;
                            this.$emit('change', this.count);
                        }
                    }
                }
            },
            methods: {
                handleTotal: function (total) {
                    this.total = total;
                }
            }
        })
    </script>
</body>

7.7.2 在组件中使用v-­model

$emit的代码,这行代码实际上会触发一个 input事件, ‘input’后的参数就是传递给v-­model绑定的属性的值

v-­model 其实是一个语法糖,这背后其实做了两个操作:

要使用v-­model,要做到:

<body>
    <div id="app">
        <p>您好,您现在的银行余额是{{total}}元</p>
        <btn-compnent v-model="total"></btn-compnent>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        //关于
        var app = new Vue({
            el: '#app',
            data: {
                total: 0
            },
            components: {
                'btn-compnent': {
                    template: '<div>\
                <button @click="handleincrease">+1</button> \
                <button @click="handlereduce">-1</button>\
                </div>',
                    data: function () {
                        return {
                            count: 0
                        }
                    },
                    methods: {
                        handleincrease: function () {
                            this.count++;
----------------------注意观察.这一行,emit的是input事件----------------
                            this.$emit('input', this.count);
                        },
                        handlereduce: function () {
                            this.count--;
                            this.$emit('input', this.count);
                        }
                    }
                }
            },
            methods: {
                /* handleTotal:function (total) {
                this.total = total;
                }*/
            }
        })
    </script>
</body>

7.7.3 非父组件之间的通信

官网描述:

image
    <div id="app">
        <my-acomponent></my-acomponent>
        <my-bcomponent></my-bcomponent>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js">
    </script>
    <script>
        Vue.component('my-acomponent', {
            template: '<div><button @click="handle">点击我向B组件传递数据</button></div>',
            data: function () {
                return {
                    aaa: '我是来自A组件的内容'
                }
            },
            methods: {
                handle: function () {
                    this.$root.bus.$emit('lala', this.aaa);
                }
            }
        })
        Vue.component('my-bcomponent', {
            template: '<div></div>',
            created: function () {
                //A组件在实例创建的时候就监听事件---lala事件
                this.$root.bus.$on('lala', function (value) {
                    alert(value)
                });
            }
        })
    </script>

父链:this.$parent

Vue.component('child-component', {
            template: '<button @click="setFatherData">通过点击我修改父亲的数据</button>',
            methods: {
                setFatherData: function () {
                    this.$parent.msg = '数据已经修改了'
                }
            }
        })

子链:this.$refs

提供了为子组件提供索引的方法,用特殊的属性ref为其增加一个索引

var app = new Vue({
            el: '#app',
            data: {
                //bus中介
                bus: new Vue(),
                msg: '数据还未修改',
                formchild: '还未拿到'
            },
            methods: {
                getChildData: function () {
                    //用来拿子组件中的内容 ---- $refs
                    this.formchild = this.$refs.c.msg;
                }
            }
        })

7.8使用slot分发内容

7.8.1 什么是slot(插槽)

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发.Vue.js 实现了一个内容分发 API,使用特殊的 ‘slot’ 元素作为原始内容的插槽。

7.8.2 编译的作用域

在深入内容分发 API 之前,我们先明确内容在哪个作用域里编译。假定模板为:

<child-component>
{{ message }}
</child-component>

message 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:

7.8.3 插槽的用法

<div id="app">
        <my-component>
            <p>我是父组件的内容</p>
        </my-component>
    </div>
    Vue.component('my-component',{ template:'
    <div>\
        <slot>\ 如果父组件没有插入内容,我就作为默认出现\
        </slot>\
    </div>' })

具名插槽:

   具名插槽:
    <name-component>
        <h3 slot="header">我是标题</h3>
        <p>我是正文内容</p>
        <p>正文内容有两段</p>
        <p slot="footer">我是底部信息</p>
    </name-component>
    Vue.component('name-component',{ template:'
    <div>\
        <div class="header">\n' + '
            <slot name="header">\n' + ' \n' + ' </slot>\n' + '
        </div>\n' + '
        <div class="contatiner">\n' + '
            <slot>\n' + ' \n' + ' </slot>\n' + '
        </div>\n' + '
        <div class="footer">\n' + '
            <slot name="footer">\n' + '\n' + ' </slot> \n' + '
        </div>'+ ' </div>' })

7.8.4 作用域插槽

作用域插槽是一种特殊的slot,使用一个可以复用的模板来替换已经渲染的元素——从子组件获取数据
template模板是不会被渲染的

  Vue.component('my-component',{ template:'
    <div>\
        <slot text="我是来自子组件的数据" ss="fdjkfjlsd" name="abc">\
        </slot>\
    </div>' })

7.8.5 访问slot

通过this.$slots.(NAME)

mounted:function () {
        //访问插槽
        var header = this.$slots.header;
        var text = header[0].elm.innerText;
        var html = header[0].elm.innerHTML;
        console.log(header)
        console.log(text)
        console.log(html)
        }

7.9 组件高级用法–动态组件

VUE给我们提供 了一个元素叫component

直接甩代码:

<body>
    <div id="data">
            <component :is ="show"></component>
            <button @click="msg('a')">第一句</button>
            <button @click="msg('b')">第二句</button>
            <button @click="msg('c')">第三句</button>
            <button @click="msg('d')">第四句</button>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        Vue.component('msga', {
                template: '<div>锄禾日当午</div>',
                data:function(){
                    return{                                           
                    }
                }
            })
            Vue.component('msgb', {
                template: '<div>汗滴禾下土</div>',
                data:function(){
                    return{                                           
                    }
                }
            })
            Vue.component('msgc', {
                template: '<div>谁知盘中餐</div>',
                data:function(){
                    return{                                           
                    }
                }
            })
            Vue.component('msgd', {
                template: '<div>粒粒坚辛苦</div>',
                data:function(){
                    return{                                           
                    }
                }
            })
      var app = new Vue({
          el:'#data',
          data:{
              show:'msga'
          },
          methods:{
              msg:function(value){
                  this.show = 'msg' + value
              }
          }
      })
    </script>
</body>

八、 自定义指令

自定义指令的基本用法

和组件类似分全局注册和局部注册,区别就是把component换成了derective

钩子函数

指令定义函数提供了几个钩子函数(可选):

钩子函数的参数有:

自定义的指令
<div v-cuihua:.a.b.c="obq"></div>

九 、render函数

9.1 render函数初步了解

template下只允许有一个子节点

 <template id="hdom">
        <div>
            <h1 v-if="level==1">
                <slot></slot>
            </h1>
            <h2 v-if="level==2">
                <slot></slot>
            </h2>
            <h3 v-if="level==3">
                <slot></slot>
            </h3>
        </div>
    </template>
    <script>
        //是用vue组件定义
        // Vue.component('child',{
        // props:['level'],
        // template:'#hdom'
        // })
        //使用render函数进行定义组件
        Vue.component('child', {
            render: function (createElement) {
                return createElement('h' + this.level,
                    this.$slots.default);
            },
            props: ['level']
        })

9.2 render函数的第一个参数

在render函数的方法中,参数必须是createElement,createElement的类型是function,render函数的第一个参数可以是 String | Object | Function

Vue.component('child', {
            // ----第一个参数必选
            //String--html标签
            //Object---一个含有数据选项的对象
            //FUnction---方法返回含有数据选项的对象
            render: function (createElement) {
                alert(typeof createElement)
                // return createElement('h1')
                // return createElement({
                // template:'<div>锄禾日当午</div>'
                // })
                var domFun = function () {
                    return {
                        template: '<div>锄禾日当午</div>'
                    }
                }
                return createElement(domFun());
            }
        });

9.3 render函数的第二个参数

Vue.component('child', {
            // ----第二个参数可选,第二个参数是数据对象----只能是Object
            render: function (createElement) {
                return createElement({
                    template: '<div>我是龙的传人</div>'
                }, {
                        'class': {
                            foo: true,
                            baz: false
                        },
                        style: {
                            color: 'red',
                            fontSize: '16px'
                        },
                        //正常的html特性
                        attrs: {
                            id: 'foo',
                            src: 'http://baidu.com'
                        },
                        //用来写原生的Dom属性
                        domProps: {
                            innerHTML: '<span style="color:blue;font-size: 18px">我是蓝色</span>'
                        }
                    })
            }
        });

9.3 render函数的第三个参数

第三个参数也是可选===String | Array—作为我们构建函数的子节点来使用的

Vue.component('child', {
            // ----第三个参数是可选的,可以是 String | Array---代表子节点
            render: function (createElement) {
                return createElement('div', [
                    createElement('h1', '我是h1标题'),
                    createElement('h6', '我是h6标题')
                ])
            }
        });

9.4 this.$slots在render函数中的应用

第三个 参数存的就是VNODE
createElement(‘header’,header), 返回的就是VNODE
var header = this.$slots.header; //–这返回的内容就是含有=VNODE的数组

Vue.component('my-component', {
            render: function (createElement) {
                debugger
                var header = this.$slots.header; //--这返回的内容就是含有=V
                NODE的数组
                var main = this.$slots.default;
                var footer = this.$slots.footer;
                return createElement('div', [
                    createElement('header', header),
                    createElement('main', main),
                    createElement('footer', footer)
                ]);
            }
        })

9.5 在render函数中使用props传递数据

    <div id="app">
        <button @click="switchShow">点击切换美女</button>  {{show}}
        <my-component :show="show">

        </my-component>
    </div>
    <script>
            Vue.component('my-component', {
                props: ['show'],
                render: function (createElement) {
                    var imgsrc;
                    if (this.show) {
                        imgsrc = 'img/001.jpg'
                    } else {
                        imgsrc = 'img/002.jpg'
                    }
                    return createElement('img', {
                        attrs: {
                            src: imgsrc
                        },
                        style: {
                            width: '600px',
                            height: '400px'
                        }
                    });
                }
            })
    </script>

9.6 v-­model在render函数中的使用

    <!--<my-component :name="name" @input="showName"></my-componen
t>-->
    <my-component :name="name" v-model="name"></my-component>
    <br> {{name}}

    <script>
        Vue.component('my-component', {
            render: function (createElement) {
                var self = this;//指的就是当前的VUE实例
                return createElement('input', {
                    domProps: {
                        domProps: {
                            value: self.name
                        },

                        value: self.name
                    },
                    on: {
                        input: function (event) {
                            debugger
                            var a = this;
                            //此处的this指的是什么?指的就是window
                            self.$emit('input', event.target.value)
                        }
                    }
                })
            },
            props: ['name']
        })
    </script>

9.7 作用域插槽在render函数中的使用

Vue.component('my-component', {
                render: function (createElement) {
                    return createElement('div', this.$scopedSlots.default({
                        text: '我是子组件传递过来的数据',
                        msg: 'scopetext'
                    }))
                }
            })

9.8 函数化组件的应用

使用context的转变

// this.text----context.props.text
//this.$slots.default-----context.children

functional: true,表示该组件无状态无实例

十、 使用vue-­cli脚手架一键搭建工程

首先电脑上要安装最新版的nodeJS.官网下载,安装完之后安装淘宝npm镜像

npm install -g cnpm --registry=https://registry.npm.taobao.org

五部走:

npm install -g vue-cli
vue init webpack my-project
cd my-project
npm install
npm run dev
目录结构的分析
├── build // 项目构建(webpack)相关代码 记忆:(够贱) 9个
│ ├── build.js // 生产环境构建代码
│ ├── check­versions.js // 检查node&npm等版本
│ ├── dev­client.js // 热加载相关
│ ├── dev­server.js // 构建本地服务器
│ ├── utils.js // 构建配置公用工具
│ ├── vue­loader.conf.js // vue加载器
│ ├── webpack.base.conf.js // webpack基础环境配置
│ ├── webpack.dev.conf.js // webpack开发环境配置
│ └── webpack.prod.conf.js // webpack生产环境配置
二、
├── config// 项目开发环境配置相关代码 记忆: (环配) 3个
│ ├── dev.env.js // 开发环境变量(看词明意)
│ ├── index.js //项目一些配置变量
│ └── prod.env.js // 生产环境变量
三、
├──node_modules// 项目依赖的模块 记忆: (依赖) *个
四、
├── src// 源码目录 5
1
│ ├── assets// 资源目录
│ │ └── logo.png
2
│ ├── components// vue公共组件
│ │ └── Hello.vue
3
│ ├──router// 前端路由
│ │ └── index.js// 路由配置文件
4
│ ├── App.vue// 页面入口文件(根组件)
5
│ └── main.js// 程序入口文件(入口js文件)
五、
└── static// 静态文件,比如一些图片,json数据等
│ ├── .gitkeep
剩余、
├── .babelrc// ES6语法编译配置
├── .editorconfig// 定义代码格式
├── .gitignore// git上传需要忽略的文件格式
├── index.html// 入口页面
├── package.json// 项目基本信息
├── README.md// 项目说明

十一、 vue-­router路由和前端状态管理

11.1 vue­-router路由基本加载

简单四步走

  1. 安装
npm install --save vue-router
  1. 引用
import router from 'vue-router'
Vue.use(router)
  1. 配置路由文件,并在vue实例中注入
var rt = new router({
  routes:[{
    path:'/',//指定要跳转的路径
    component:HelloWorld//指定要跳转的组件
  }]
})
new Vue({
  el: '#app',
  router:router,
  components: { App },
  template: '<App/>'
})
  1. 确定视图加载的位置
<router-view></router-view>

11.2 vue-­router路由的跳转

<router-link to="/"></router-link>
<template>
  <ul>
    <li>
      <router-link to="/helloworld">HELLO WORLD</router-link>
    </li>
    <li>
      <router-link to="/helloearth">HELLO EARTH</router-link>
    </li>
  </ul>
</template>

11.3 vue-­router路由参数的传递

  1. 传递参数和接收参数看下边代码
<router-link
  :to="{name: helloearth,params:{msg: 只有一个地球}}">
  HELLO WORLD
</router-link>
读取参数: $route.params.XXX
方式:===/helloworld/你好世界


<router-link
  :to="{path: '/helloearth',query:{msg: 只有一个地球}}">
  HELLO WORLD
</router-link>
方式:===/helloworld?name=XX&count=xxx
函数模式
你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。
const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({
      query: route.query.q }) }
  ]
})

11.4.1 Axios之get请求详解

axios的简介:

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:

  1. 安装
npm install axios
  1. 引入加载
import axios from 'axios'
  1. 将axios全局挂载到VUE原型上
Vue.prototype.$http = axios;
  1. 发出请求 以cnode社区API为例子
// 为给定 ID 的 user 创建请求
使用传统的function
getData(){
  var self = this;
  this.$http.get('https://cnodejs.org/api/v1/topics')
  .then(function (res) {
//此处的this指向的不是当前vue实例
    self.items = res.data.data
    console.log(res.data.data)
  })
  .catch(function (err) {
    console.log(err)
  })
}
// 可选地,上面的请求可以这样做
两种传递参数的形式
axios.get('/user', {
  params: {
    ID: 12345
  }
})
axios.get('/user', {
  ID: 12345
})
---------------------------------
axios.get('https://cnodejs.org/api/v1/topics?page=1&limit=15')

11.4.2 Axios之post请求详解

// 为给定 ID 的 user 创建请求
使用传统的function
getData(){
  var self = this;
  this.$http.post(url,{
    page:1,
    limit:10
  })
  .then(function (res) {
//此处的this指向的不是当前vue实例
    self.items = res.data.data
    console.log(res.data.data)
  })
  .catch(function (err) {
    console.log(err)
  })
}

POST传递数据有两种格式:

在axios中,post请求接收的参数必须是form­data
qs插件—­qs.stringify

11.5 Vuex之store

用来管理状态,共享数据,在各个组件之间管理外部状态如何使用?

//创建状态仓库,注意Store,state不能改
var store = new Vuex.Store({
  state:{
    XXX:xxx
  }
})
//直接通过this.$sore.state.XXX拿到全局状态

11.6 Vuex的相关操作

vuex状态管理的流程
view———­>actions———–>mutations—–>state————­>view

除了能够获取状态如何改变状态呢?

//创建状态仓库,注意Store,state不能改
var store = new Vuex.Store({
  state:{
    XXX:xxx
  },
  mutations:{
  }
})
this.$store.commit(XXX);
// 此处的XXX是你在mucations中定义的方法名
var store = new Vuex.Store({
  state:{
    XXX:xxx
  },
  mucations:{
    a:function(state){
    }
  },
  actions:{
    b:function(context){
      context.commit('a');
    }
  }
})
// 如何调用
this.$store.dispatch(XXX);
getters:{
}
this.$store.getters.getCount

注意:actions提交的是mutation,而不是直接变更状态
actions可以包含异步操作,但是mutation只能包含同步操作

The early bird catches the worm

上一篇下一篇

猜你喜欢

热点阅读