Vue.js的学习笔记

Vue.js

1.简介

vue介绍:vue是一个兴起的前端js库,是一个精简的MVVM。从技术角度讲,Vue.js 专注于 MVVM 模型的 ViewModel 层。它通过双向数据绑定把 View 层和 Model 层连接了起来,通过对数据的操作就可以完成对页面视图的渲染。当然还有很多其他的mvmm框架如Angular,React都是大同小异,本质上都是基于MVVM的理念。 然而vue以他独特的优势简单,快速,组合,紧凑,强大而迅速崛起 

 

官方在线文档:https://cn.vuejs.org/v2/guide/index.html

了解Vue.js :https://www.cnblogs.com/Renyi-Fan/p/9419742.html#_label0_18

 

作为兴起的框架,Vue.js抛弃了对IE8的支持,移动端支持安卓4.2+  和IOS7+

在使用之前首先需要导入Vue.js的库:<script src="js/vue.js"></script>

 

Vue.js的Hell word:  

记住一点,写有Vue语句的script放在html代码的下面,否则不会实现效果

<div id="app">{{message}}</div>

<script>
    new Vue({
        el: '#app',
        data: {
            message: 'Hello world'
        }
    });
</script>

将js中message的值替换到了HTML模版中{{message}}中

 

特性1:数据绑定

H1显示的内容绑定你文本框中内容   v-model为数据绑定组件

一切使用vue从 new Vue开始,这一步不可缺少

<div id="app">
  <h1>Your input is {{message}}</h1>
    <input type="text" v-model="message">
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Hello world'
        }
    });
</script>

 

特性2:组件化(自定义HTML标签)

<div id="app">
    <message content="Hello World"></message>
</div>
<script>
    var Message = Vue.extend({

        props: ['content'],
        template: '<h1>{{content}}</h1>'
    });

    Vue.component('message', Message);
    var vm = new Vue({
        el: '#app',
    });
</script>

 

  1. 基础特性

2.1实例及选项

Vue.js的使用都是通过构造函数Vue{{option}}创建一个Vue的实例:

Var vm=new Vue({}).一个Vue实例相当于一个MVVM模式中的ViewModel,如图:

在实例化时我们可以传入一个选项对象,包含数据,模版,挂载元素,方法,生命周期钩子等选项.

 

2.1.1模版

选项中主要影响模版或DOM的选项有el和template,属性replace和template需要一起使用

el:类型为字符串,DOM元素或函数,例如el:’#app’ 在初始项中指定了el,实例将立即进入编译过程

template:类型为字符串.默认将template值替换挂载元素(el值对应的元素).例子如下:

<div id="app">
    <p>123</p>
</div>
<script id="tpl" type="x-template">
<div class="tpl">
    <a>This</a>
</div>
</script>
<script type="text/javascript">
    var vm=new Vue({
        el:'#app',
        template:'#tpl'
    })
</script>

页面显示的只有This,原因就是因为用#tpl的内容把#app给代替了.

 

2.1.2 数据

Vue.js通过data属性定义数据   使用data的注意事项:1.data的值必须是一个函数,并且返回值是原始对象

2.data中的属性和props中的不能重名.

var data={a:1}
var vm=new Vue({
    data:data
})
    vm.$data===data//true
    vm.a===data.a//true
    //设置属性会影响到原始数据
    vm.a=2
    data.a//2
    //反之亦然
    data.a=3
    vm.a//3

 

自定义一个标签,然后给标签定义属性 解析:

My-component是标签名 ,props用来绑定属性,data定义数据,给desc赋值为123,template为模版,具体表名标签的内容.

<div id="app">
    <my-component title="myTitle" content="myContent"> </my-component>
</div>
<script>
    var Mycomponent = Vue.component('my-component', {
        props: ['title', 'content'],
        data: function () {
            return {
                desc: '123'
            }
        },
        template: '<div><h1>{{title}}</h1><p>{{content}}</p><p>{{desc}}</p></div>'
    })
    new Vue({
        el:'#app'
    })
</script>

 

2.1.3方法

我们可以通过属性methods对象来定义方法,并且使用v-on指令来监听DOM事件,例如:

<div id="app">
<button v-on:click="alert">alert</button>
</div>
<script>
new Vue({
    el:'#app',
    data:{a:1},
    methods:{
        alert:function () {
            alert(this.a)
        }
    }
})
</script>

 

2.1.4生命周期

2.2数据绑定

Vue.js的核心是一个响应式的数据绑定系统,建立绑定后,DOM将和数据保持同步,无需手动维护DOM,是代码简洁易懂.

2.2.1数据绑定语法

v-bind:id可以简写为:id,这时中间的div的id为id-1,span标签显示的值为names的数值

<div id="app">
<span v-once="name">{{names}}</span>
    <div v-bind:id="'id-'+id"></div>
</div>

var vm = new Vue({
    el: '#app',
    data: {
        id: 1,
        index: 0,
        name: 'vue',
        avatar: 'http://...',
        count: [1, 2, 3, 4, 5],
        names: ['vuel.0', 'vue2.0'],
        items: [
            {name: 'vue1.0', version: '1.0'},
            {name: 'vue1.0', version: '1.0'}
        ]
    }
});

 

在{{}}中的数据能使用表达式,但是每个绑定值只能使用单个表达式,不支持正则表达式

{{index==0?'a':'b'}}<br>
{{index+1}}<br>
{{name.split('').join('|')}}

 

指令

格式:v-

  1. 参数

<img v-bind:src=”avatar”/>
指令v-bind可以在后面带一个参数,用冒号(:)隔开,src即参数.此时img标签中的src会与vm实例中的acatar绑定,等同于<img src=”{{acatar}}”>

  1. 修饰符

以半角句号.开始的特殊后缀,用于表示指令应该以特殊方式绑定.
<button v-on:click.stop=”doClick”></button>
v-on的作用是在对应的DOM元素上绑定事件监听器doClick为函数名,stop为修饰符,作用是停止冒泡,相等于调用了e.stopPropagation()

 

2.2.2计算属性

1.computed为计算,它生产了一个对象 fullname的对象,这个对象将 vm这个Vue对象中的data中的两个数值相加,this指的是当前的Vue对象.

<div id="app">
    <p>{{firstname}}</p>
    <p>{{lastname}}</p>
    <p>{{fullname}}</p>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            firstname: 'Gavin',
            lastname: 'GLY'
        },
        computed: {
            fullname: function () {
                return this.firstname + '' + this.lastname
            }
        }
    });
</script>

当你在浏览器中的控制台输出vm.firstname=’xxx’的时候,将会把fullname和firstname的值都改变

 

2.Setter

页面显示为1.00,这种方式能处理价格能避免前后端数据类型转换产生的问题

在更改vm.price=2,vm.cents会更新为200,传给后端就无需转换数据

 

<div id="app">
    <p>{{price}}</p>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            cents: 100,
        },
        computed: {
            price: {
                set: function (newValue) {
                    this.cents = newValue * 100;
                }, get: function () {
                    return (this.cents/100).toFixed(2);
                }
            }
        }
    })
</script>

 

2.2.3表单控件

v-model代表当前标签绑定一个值,绑定的值显示的就是这个标签当前的状态

<div id="app">
    <!--text 用户输入和显示一致-->
    <input type="text" v-model="message">
    <span>输入为:{{message}}</span>
    <!--Radio 单选框--><br>
    <label><input type="radio" value="male" v-model="gender"></label>
    <label><input type="radio" value="female" v-model="gender"></label>
    <p>{{gender}}</p>
    <!--Checkbox 单选--><br>
    <input type="checkbox" v-model="checked">
    <span>checked:{{checked}}</span>
    <!--多选--><br>
    <label><input type="checkbox" value="1" v-model="multiChecked">1</label>
    <label><input type="checkbox" value="2" v-model="multiChecked">2</label>
    <label><input type="checkbox" value="3" v-model="multiChecked">3</label>
    <p>multiChecked:{{multiChecked.join('|')}}</p>
    <!--select 单选--><br>
    <select v-model="selected">
        <option >A</option>
        <option >B</option>
        <option >C</option>
    </select>
    <span>selected:{{selected}}</span>
    <!--多选--><br>
    <select v-model="multiselected" multiple>
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select><br>
    <span>multiselected:{{multiselected}}</span>
    <!--绑定value 选中的话checked的值为a,未选中的话就是b-->
    <input type="checkbox" v-model="checked" v-bind:true-value="a" v-bind:false-value="b">
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            a:'123',
            b:'321',
            message: '',
            gender: '',
            checked: '',
            multiChecked: [],
            selected: '',
            multiselected: []
        }
    });
</script>

 

2.2.4Class与Style绑定

1.Class绑定
语法:v-bind:class接收参数是一个对象,可以和普通的class属性共存

这样一个标签它的class属性就会有多个:

除了对象绑定还有下面的数组绑定[classA,classB]
<div id="app">
    <div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
    <div v-bind:class="[classA,classB]"></div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            hasError: false,
            classA: 'class-a',
            classB: 'class-b'
        }
    })
</script>

 

2.内联样式绑定

对象语法:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">123</div>

vue对象中的data语法:

activeColor: 'red',
fontSize: 30


或者直接绑定:

<div v-bind:style="styleObject">312</div>

data内:

styleObject:{
    color:'red',
    fontSize:'30px'
}

 

数组语法:  数组中的值需要和上方的styleObject格式一致,标明属性和属性值

<div v-bind:style="[styleObject,styleObject2]">123</div>

V-bind:style可以简写为:style

 

2.3模版渲染

 

v-if=”true” 类似<c:if>标签  可以和v-else一起使用,但是必须要放在一起使用,不符合条件的内容不会显示在源代码中

v-show=”true” 类型v-if可以和v-else一起使用,不符合条件的只是会隐藏,源代码可见

v-else 同上

 

v-for=” 变量名 in 数组或集合 ”  类似foreach循环 主要用于列表渲染,例如:

<div id="app">
    <ul>
        <li v-for="item in items">
            <h3>{{item.title}}</h3>
            <p>{{item.description}}</p>
        </li>
    </ul>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            items: [
                {title: 'title-1', description: 'description-1'},
                {title: 'title-2', description: 'description-2'},
                {title: 'title-3', description: 'description-3'},
                {title: 'title-4', description: 'description-4'},
            ]
        }
    });
</script>

 

如果想的到循环的次数的话v-for=”(item,index) in items”   index就是循环次数   

也可以充当for循环使用   v-for=”n in 5”

 

2.3.4template标签用法

template也支持v-for    template的作用可以将指令作用到多个兄弟DOM元素上.

<div id="app">
    <template v-if="true">
        <p v-if=false>1</p>
        <p>2</p>
        <p>3</p>
        <p>4</p>
    </template>
</div>
<script>
    new Vue({
        el: '#app',
        data:{
            yes:false
        }
    })
</script>

 

2.4事件监听和绑定

v-on监听DOM事件  v-on:click可以简写为@click

当你点击say的时候它会跳出弹窗,methods是用来定义方法的,方法名在前方法在后,中间用:隔开 function后面的括号中也可以加入参数

<div id="app">
<button v-on:click="say">say</button>
</div>
<script>
new Vue({
    el:'#app',
    data:{
        msg:'hello vue.js'
    },
    methods:{
        say:function () {
            alert(this.msg)
        }
    }
})
</script>

 

获取原生DOM事件对象:

<div id="app">
    <button v-on:click="say">say</button>
    <button v-on:click="say($event)">showsay</button>
    <button v-on:click="say()">say</button>   这个不可实现
</div>
<script>
    new Vue({
        el: '#app',
        methods: {
            say: function (even) {
                console.log(even);
            }
        }
    })
</script>

 

 

2.5 Vue.extend()

组件化开发,将一个页面看成一个大的根组件,里面包含的元素就是不同的子组件,子组件也可以在不同的根组件里被调用.一个页面通常声明一个Vue的实例new Vue({})作为根组件.

Vue.js提供了可被重复使用的子组件:Vue.extend(options)方法,创建基础Vue构造器的’子类’,参数options对象和直接声明Vue实例参数对象基本一致,使用方法如下:  具体看第6章

 

 

3.指令

v-bind 用于动态绑定DOM元素属性,元素实际的值是由vue实例中的data属性提供的.

v-model 2.2.3中已经说明,该指令主要用于input ,select ,textarea标签中,具有trim修饰符

v-if/v-else/v-show

v-for 在2.0中大致包含了以下几个方面:

1.参数顺序变化

当包含index或key时,对象参数改为(item,index)或(value,key),这样与js array对象的新方法forEach和map,一些迭代器的参数保持一致.

v-on 事件绑定  v-on:click可以简写为@click  在2.0中v-on只监听自定义事件,即用$emit触发的事件,如果要监听原生事件,需要修饰符.native  如:v-on:click.native

v-text  参数类型为字符串,作用是更新元素的textContent.  {{}}文本插值本身也会编译成textNode的一个v-text指令,但是v-text需要绑定在某个元素上  如果直接使用{{msg}}的话在生命周期beforeCompile期间,此刻的msg数据还没有编译到{{msg}}中,有一瞬间会显示

但是如果用了v-text就不会出现这种情况.

v-HTML参数类型为字符串 接收的字符串不会进行编译等操作按普通的HTML处理.同v-text一样,也要绑定到某个元素上才不会出现闪现的情况.

 

v-pre 跳过编译这个元素和子元素,显示原始的{{}},用来减少编译时间

<div id="app">
    <div v-pre>{{un}}</div>
</div>
<script>
    new Vue({
        el:'#app',
        data:{
un:'this is an'
        }
    })
</script>

 

v-cloak 想当与在元素上加了一个[v-cloak]的属性,知道关联的实例结束编译.可以和css规则[v-cloak]{display:none}一起使用,可以隐藏未编译的Mustache标签直到实例准备完毕.例如:

<div v-cloak>{{msg}}</div>

 

v-once 标明元素或者组件只渲染一次,随后绑定数据发送的变化不会影响到.最大的提升了更新行为页面的性能.

 

3.2自定义指令基础

<div id="container">
    <p>{{msg}}</p>
    <!-- 准备实现需求:
    在h1标签上面,加上一个按钮,当点击按钮时候,对count实现一次
    自增操作,当count等于5的时候,在控制台输出‘it is a test’-->
    <button @click="handleClick">clickMe</button>
    <h1 v-if="count < 6" v-change="count">it is a custom directive</h1>

<h1 v-change-background-color="myBgColor" >it is a header1</h1>
</div>
<script>
    // bind 指令在绑定到元素要执行的操作
    // update如果在调用指令时候,传了参数,当参数变化时候,就会执行update所指定的方法
    // unbind解绑要执行的操作
    //directives 定义自定义指令
    new Vue({
        el: '#container',
        data: {
            msg: 'Hello Vue',
            count:0,

myBgColor:'#ff0000'


        },
        methods:{
            handleClick: function () {
                //按钮单击,count自增
                this.count++;
            }
        },
        directives:{
            change:{
                bind: function (el,bindings) {//bindings为指令的参数
                    console.log('指令已经绑定到元素了');
                    console.log(el);
                    console.log(bindings);
                    //准备将传递来的参数
                    // 显示在调用该指令的元素的innerHTML
                    el.innerHTML = bindings.value;
                },
                update: function (el,bindings) {
                    console.log('指令的数据有所变化');
                    console.log(el);
                    console.log(bindings);
                    el.innerHTML = bindings.value;
                    if(bindings.value == 5)
                    {
                        console.log(' it is a test');
                    }
                },
                unbind: function () {
                    console.log('解除绑定了');
                }
            }, changeBackgroundColor: {
        bind: function (el, bindings) {
        console.log('in bind ');
        console.log(bindings.value);
        el.style.backgroundColor = bindings.value;
    }
}
        }
    })
</script>

 

3.4 指令在2.0的变化

 

新的钩子函数componentUpdated,当整个组件都完成了update状态后即所有的DOM都更新后调用该钩子函数,无论指令接受的参数是否发生变化.

在2.0中取消了指令实例这一概念,即在钩子函数中的this不能指向指令的相关属性.指令的相关属性都通过参数的形式传递给钩子函数.

 

  1. 指令绑定bind函数执行后不直接调用update函数
  2. 只要组件发生重绘,无论指令接受的值是否发生变化,都会调用update函数,如果要过滤不必要的更新,可以使用

binding.value=binding.oldValue来判断

 

钩子函数接受的参数binding对象为不可更改,强行设定binding.value的值并不会引起实际的改动,如果一定要用这种方式修改的话,通过el直接修改DOM元素

 

5.过渡

<style>
    .fade-enter-active, .fade-leave-active {
        transition: opacity .5s
    }
    .fade-enter, .fade-leave-active {
        opacity: 0
    }
</style>
<body>
<div id="demo">
    <button v-on:click="show = !show">
        Toggle
    </button>
    <transition name="fade">
        <p v-if="show">hello</p>
    </transition>
</div>
<script>
    new Vue({
        el: '#demo',
        data: {
            show: true
        }
    })
</script>

过渡就是通过操作改变标签的CSS样式,(2.x版本和1.x版本差异过大,请知晓)

详情了解:https://www.jb51.net/article/108616.htm

 

 

6.组件

<div id="app">
    <my-button/>
</div>
<script>
    let myButton = Vue.extend({//创建一个组件构造器
        template: `<button>点击我</button>`
    })
   Vue.component('my-button', myButton)//注册组件,并指定组件的标签,组件的HTML标签为<my-button>
    let app = new Vue({//创建Vue实例,注意实例化vue对象时要在注册组件之后
        el: '#app'
    });
</script>

 

注册组件还可以写成:Vue.component('my-button', { template: `<button>点击我</button>` })

创建这样一个简单的组件并不是很困难的事情,重点是是要理解怎么创建组件

·  Vue.extend()是Vue构造器的扩展,调用Vue.extend()创建的是一个组件构造器

·  Vue.extend()构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML,简单的理解这个属性用来定义组件的模板(也就是组件的HTML结构)

·  使用Vue.component()注册组件,在注册组件时需要提供两个参数,第一个参数是组件的标签,比如上例中的my-button,第二个参数是组件构造器,比如上例中的myButton

·  组件应该挂载到某个Vue实例下,否则它不会生效。这一点需要特别的注意。另外同一个组件可以同时挂载到多个Vue实例下

以上代码为全局注册,

 

局部注册:,该组件只能在对应的Vue实例中使用,如果别的Vue实例调用该组件,将会报一个提示错误

只需要再实例化Vue的时候使用

let app = new Vue({

 el: '#app',

 components: {

'my-button': myButton

}

})

这样的话这个组件就只能在id为app的标签内使用.

总结:

·  通过Vue.component(tagName, options)注册全局组件,可以在任何Vue实例范围中使用

·  通过Vue实例的components属性注册局部组件,只能在该实例范围中使用

 

传入Vue构造器的多数选项也可以用在Vue.extend()或Vue.component()中,不过有两个特列:data和el。Vue规定:

在定义组件的选项时,data和el选项必须使用函数。

 

组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件A在它的模板中使用了组件B。它们之间必然需要相互通信:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告诉父组件

在Vue中,父子组件的关系总结为prop向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送消息。

示例:

<div id="app">
    <my-search>
    </my-search>
</div>
<script>
       let myButton = Vue.extend({ // 构造子组件
        template: '<button>Search</button>'
    }) // 构造父组件
       let mySearch = Vue.extend({ // 在父组件mySearch中使用<my-button>标签
        template: '<div><label for= "search"> Search the site </label>'+
        '<input type = "search" name = "search" id = "search" placeholder = "Enter keyword"/> ' +
        '<my-button/></div>',
        components: {
           'my-button': myButton//局部注册myButton组件只能在mysearch中使用
        }
    });
       Vue.component('my-search', mySearch);//注册全局组件mysearch
    let app = new Vue({
        el: '#app',
        data: {}
    })
</script>

 

·  先使用Vue.extend()定义了一个myButton组件构造器和mySearch组件构造器

·  components: {'my-button', myButton}将myButton组件注册到mySearch组件,并将myButton组件的标签设置为my-button

·  在mySearch组件内通过template标签,定义了搜索表单mySearch组件所需要的模板,并且引用了myButton组件

·  Vue.component('my-search', mySearch)全局注册mySearch组件

·  在页面中使用my-search标签,挂截到app实例中,渲染整个mySearch组件,其子组件myButton也将被渲染出来

 

 

7.Vue常用插件

首先去https://unpkg.com/[email protected]/dist/vue-router.js,然后Ctrl+s保存下来js文件,使用时和jquery是一样,直接引用,  详情学习v-router文档:https://router.vuejs.org/zh/guide/#html

代码例子:

<div id="app">
    <h1>Hello App!</h1>
    <p><!-- 使用 router-link 组件来导航. --><!-- 通过传入 `to` 属性指定链接. -->
        <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
    </p><!-- 路由出口 --><!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
</div>
<script>// 1. 定义 (路由) 组件。// 可以从其他文件 import 进来
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    // 2. 定义路由// 每个路由应该映射一个组件。 其中"component" 可以是
    // 通过 Vue.extend() 创建的组件构造器, 或者,只是一个组件配置对象。
    // 我们晚点再讨论嵌套路由。
    const routes = [
        { path: '/foo', component: Foo },
        { path: '/bar', component: Bar }
    ]
    // 3. 创建 router 实例,然后传 `routes` 配置 你还可以传别的配置参数, 不过先这么简单着吧。
    const router = new VueRouter({
        routes // (缩写) 相当于 routes: routes
    })
    // 4. 创建和挂载根实例。  记得要通过 router 配置参数注入路由, 从而让整个应用都有路由功能
    const app = new Vue({
        router
    }).$mount('#app')
</script>

关于更多了解情况请见:https://router.vuejs.org/zh/guide/#html

 

vue的ajax请求 :axios

文档:https://www.jianshu.com/p/7a9fbcbb1114

 

let params=new URLSearchParams();
params.append("limit","20");
params.append("name","张三");
axios.post('studentaction.action?methodName=find',params).then(function (value) {
    console.log(value.data);
})

 

 

Vuex教程:https://vuex.vuejs.org/zh/guide/

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_41594146/article/details/83035684