美文网首页
Vue基础(上)

Vue基础(上)

作者: 李宏伟_eb5e | 来源:发表于2019-04-24 19:44 被阅读0次

#### vue note

---

1、vue.js是什么?

​ 构建数据驱动的web应用开发框架

2、为什么如此受欢迎?

​ -声明式渲染, 符合前后端分离的趋势

​ -渐进式框架, 适应葛总业务需求及场景

​ -快速交付, 可以结合各种第三方UI框架

​ -企业需求 , 必备技能

3、MVC,MVP,MVVM架构模型对比

​ -MVC:Controller薄,view 厚, 业务逻辑大多集中在View。

​ -MVVM:MVVM是认为Controller做了太多数据加工的事情,所以MVVM把`数据加工`的任务从`Controller`中解放了出来,使得`Controller`只需要专注于数据调配的工作,`ViewModel`则去负责数据加工并通过通知机制让View响应ViewModel的改变。(vue并不是完全遵守MVVM模型)双向数据绑定 ,view的变动映射在viewmodel,反之一样。

​ -MVP:view薄,不部署任何业务逻辑,被称为被动视图(passive view)

---

``` html

<div id="box">

    {{name}}

    <span>{{age}}</span>

    <div>{{htmlname}}</div> //此处只是添加文本,无法添加html标签,支持加减乘除、三目运算,位运算等

    <p v-htlm="showhtml">ss</p>

    <p v-if="isShow">

        动态添加和删除  # 直接删除

    </p>

    <p v-show="isShow">

        动态显示和隐藏  # display:none

    </p>

<button v-on:click="handleClick"> 

    </button>

    <div v-bind:class="isShow?'sss':'ddd'"> 

        v-bind=:

    </div>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            name:"xiaoming",  // vue中的变量改变时,会动态渲染前端页面,如果页面有使用到此变量

            age:18,

            htmlname: "<b>xiaoming</b>",

            showhtml:"<b>xiaoming</b>",

            isShow:true,

        }

        methods:{

            met:function(){

            console.log('111')

        }

            handleClick(){

                console.log(11);

                this.name = "asd";

                this.age = true;

    }

    }

    })

</script>

```

*计算属性*

```html

<div id="box">

    {{name.substring(0,1).toUpperCase()+name.substring(1)}}

    <span>{{age}}</span>

    <div>计算属性{{changeword}} </div>

    <div>普通方法{{changewordmethod}} </div>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            name:"xiaoming",

            age:18,

        }

        methods:{

        changewordmethod:function(){ # 每次加载都会重新计算,因为他是普通方法

        return this.name.substring(0,1).toUpperCase()+this.name.substring(1)

    }

    }

        computed:{ // 涉及到此属性参与的,页面都会重新渲染,在普通方法中,如果方法被两次调用,name会计算两次,但是计算属性只计算一次,并且缓存起来(如果属性参数或者其依赖改变,name也会重新计算)

        changeword:function(){

        return this.name.substring(0,1).toUpperCase()+this.name.substring(1)

    }

    }

    })

</script>

```

*watch VS computed*

```html

<div id="box">

    <P>单价:<input type="text" v-model="price" /> </P>

    {{price}}

    <P>数量::<input type="text" v-model="number" /> </P>

{{number}}

    <P>总额:<span> {{sum}}</span> </P>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            price:100,

            number:10,

            sum: 

        }

            watch:{

            price:function(newvalue){

                this.sum = newvalue*this.number

    },

            number:function(newvalue){

        this.sum = newvalue*this.price

    }

        }

        computed:{

            computedsum:function(){

                return this.number*this.name

            }

        }

    })

</script>

```

*setter*

```html

<div id="box">

    <p class="default" :class="isShow?'aa':'bb'">class样式</p>

    <div class="default" :class="active:isShow,show:isShow2">class样式</div>

    <p class="default" :class="[who, 'show']"> </p>

    // 省略 v-bind -> :

    <p class="default" :style="{background: color}"> style样式</p>

    // 和上面的等同, 都是响应式的

    <p class="default" v-bind:style="obj"> style样式</p>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            name:xiaoming,

            isShow:false,

            isShow2:true, 

            who: "可变变量",

            cloor: "red",

            obj:{

                background:"red",

                fontSize:"30px"

            }

        }

    })

</script>

```

**v-if*  v-show **动态创建和删除DOM节点  动态隐藏和显示

```html

<div id="box">

// 互斥的两个vue标签 如果v-if一开始是假,那么不会创建此节点 如果有多个标签受同一个变量影响,写起来会比较烦,可以考虑提出这些v-if和v-else,放在同一个容器下,统一控制容器,但可能会破话布局

    <P v-if="isCreated">我是v-if创建 </P> 

    <P v-else="isCreated">我是v-else创建</P>

    <P v-if="isCreated">我是v-if创建 </P> 

    <P v-else="isCreated">我是v-else创建</P>

    // template标签并不会实质性的去创建template标签,只是一个虚拟的控制性容器

    <template v-if="isCreated">

        <P v-if="isCreated">我是v-if创建 </P> 

        <P v-else="isCreated">我是v-else创建</P>

        <P v-if="isCreated">我是v-if创建 </P> 

        <P v-else="isCreated">我是v-else创建</P>

    </template>

    // 动态隐藏和显示 如果一开始是假,那么创建出节点,并且为节点加上display=none

    <div v-show="isCreated">

        动态隐藏和显示

    </div>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            isCreated:false,

        }

    })

</script>

```

**v-for** 把一个数组对应为一组元素,可以在模板渲染时进行遍历,显示

```html

<div id="box">

    <ul>

        // 遍历显示

        <li v-for="data in datalist"> {{data}}</li>

    </ul>

    <ul>

        // 索引和元素的共同取用,用 in和of的效果是相同的

    <li v-for="(data,index) in datalist"> {{data}}-----{{index}}</li>

    </ul>

    <input type="text", v-model="mytext" />

    <li v-for="data in computeddatalist"> {{data}} </li>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            // 在vue中,push、pop、shift、unshift、splice、sort、reverse等方法都是可以改变下面的datalist的,并且,vue会对页面进行重新渲染;但是数组如果并未产生实际性的变动时(filter,concat,slice等),页面并不会重新渲染,但可以重新给 通过给数组进行赋值来实现动态刷新

            datalist:["aaa", "bbb", "ccc"],

            mytext:""

        }

        computed:{

        computeddatalist:function(){

        return this.datalist.filter(item=>item.indexOf(this.mytext)>-1)

    }

    }

    })

</script>

```

**键盘事件监听**

```html

<div id="box">

    <button @click="count=count-1">-</button>

    <p>{{count}}</p>

    <button @click="count=count+1">+</button>

    <p>{{name}}</p>

    <button @click="handleClick">click</button>

// 直接在事件中定义想要传的参数

    <button @click="handleClick2('1111', '22222', $event)">click2</button>

    // 只有事件源是自身的时候,事件才会发生,否则不会触发事件

    <ul @click.self="handleUlClick">

        // 阻断冒泡

        <li @click.stop="handleClick">111</li>

        // 点击只有第一次是有效的,后续不会再次触发

        <li @click.once="handeOnce">222</li>

        <li>333</li>

    </ul>

    // 只有在摁下enter的情况下才会触发事件 同理 enter,tab,esc,space,up,down,left,right

    <input type="text" @keyup.enter="handleKeyUp" />

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            count:1,

            name: "xiaoming"

        },

        methods:{

            handleClick(ev){

                // ev就是事件的触发源

                console.log(ev.target.value);

                this.name="aaa";

            },

            handleclick2(data1, data2, ev){

                console.log(data1);

                console.log(data2);

                console.log(ev.target)

            },

            handleClick(){

        console.log("li点击");

    },

            handleUlClick(){

                console.log("ul点击")

            }

            handleKeyUp(ev){

console.log(ev.keyCode);

                if(ev.keyCode==13){

                    console.log(ev.target)

                }

            }

        }

    })

</script>

```

**表单输入绑定**

```html

<div id="box">

// 输入框中输入的值和外面的值是相互绑定的

<input type="text" v-model="mytext" />

  {{mytext}}

    <p>

        <imput type="checkbox" v-mdoel="isChecked">记住用户名 

    </p>

    // 每次勾选都会在checkgroup添加一个checkbox的value值,取消勾选会在checkgroup中再次移除

    <p><input type="checkbox" v-model="checkgroup" value="1"/>aaa</p>

    <p><input type="checkbox" v-model="checkgroup" value="2"/>bbb</p>

    <p><input type="checkbox" v-model="checkgroup" value="3"/>ccc</p>

    // vue提供的单选框功能,无须获取dom节点,直接访问picked

    <p><input type="raido" v-model="picked" value="vue"/>{{picked}}</p>

    // 此处在输入框内修改输入的内容,外面的name并不会随之改变,但是当鼠标移走之后,外部的那么值会立刻改变,此为lazy。如果想限制输入的内容必须为数字的话,可以把lazy换位.number,如果想去除输入内容的头尾空格,那么可以把lazy换位trim

    <p><input type="text" v-model.lazy="name" value=""/>{{name}}</p>

</div>

<script type="text/javascript">

    var vm = new Vue({

        el:"#box",

        data:{

            name:xiaoming,

            mytext:"111",

            isChecked:false,

            checkgroup:[],

            picked:"vue",

        }

    })

</script>

```

**组件的使用**封装的,可重用的html

*组件分为全局组件和局部组件

```html

<div id="box">

    <hello></hello>

<hellobox></hellobox>

</div>

<div id="box2">

    // 重新初始化后可以复用全局组件

    <hello></hello>

    //下面这个并不会被渲染出来,会报错,因为hellobox是box的独有的

    <hellobox></hellobox>

</div>

<script type="text/javascript">

    // 父子组件的状态是无法共享的

    Vue.component("hello",{

            template:

        `

                <div>

                一个hello组件{{name}}

<ul>

// datalist 也必须用函数方法定义出来

    <li v-for="data in datalist>{{data}}</li>

    </ul>

    </div>

`

        // data:"name" 在组件中,这是无法使用的,并且会报错,必须定义为方法,才可以调用

        data:function(){

            return {

name:"xiaoming",

                datalist:['aaa', 'bbb']

            }

    }

    })

    var vm = new Vue({

        el:"#box",

        data:{

        },

        components:{

            "hellobox":{

                template:

            `<div>box下面独有的组件,非全局组件</div>`

            }

        }

    var vm2 = new Vue({

        el:"#box2",

        data:{

    }

    })

})

</script>

```

**组件之间的通信**父子组件

使用vue绑定自定义事件:

每个Vue的实例都实现了事件的接口:

* 使用 $on(eventname)监听事件;

* 使用$emit(evenvname)触发事件;

  ```html

  <div id="box">

      // hello里面的handleparentclick是父组件定义的监听,也就是说这个事件监听是父组件进行的

      <hello name="xiaoming" :age="100" @event="handleParentClick"></hello>

  </div>

  <script type="text/javascript">

      var obj = {

          template:`

  <div> 我是{{name}}---{{age}}组件</div>

  //

  <button @click="handleclick">click</click>

  `,

          // 接收子组件的一些属性值,并存储,props是单向的,

          props: {

          name:String,

              age:Number,

          },

      }

      var vm = new Vue({

          el:"#box",

          data:{

          },

          components:{

              hello: obj

          },

          methods:{

              handleParentClick(){

                  console.log("parent_click", "click")

              }

          }

      })

  </script>

  ```

```html

<div id="box">

    <hello name="xiaoming"></hello>

</div>

<script type="text/javascript">

    var obj = {

        template:`

<div> 我是{{name}}组件</div>

`,

        // 接收子组件的一些属性值,并存储,props是单向的,

        props: ["name"]

    }

    var vm = new Vue({

        el:"#box",

        data:{

        },

        components:{

            hello:{

            }

        }

    })

</script>

```

**非父子组件之间的通信**

vue的非父子 组件之间的通信一般有两种方法:

-- 中央事件总线 bus=new Vue();

* mounted生命周期中进行监听

# --vuex 状态 管理  后面再说这个

```html

<div id="box">

    <hello name="xiaoming"></hello>

</div>

<script type="text/javascript">

    var bus = new Vue()

    var helloA = {

        template:`

<div>我是组件A

<button @click="handleClick>click</button>

</div>

`

        ,

        methods:{

            handleClick(){

                //将要发消息给B组件

                bus.$emit("xiaoming", "来自组件A的消息")

            }

        }

    }

    var helloB = {

        template:`

        <div>我是组件B</div>

        `,

        //组件生命周期

        mounted(){

            console.log("b组件挂在的钩子函数");

            bus.$on("xiaoming", function(value){

              console.log(value)

            })

        }

    }

    var vm = new Vue({

        el:"#box",

        data:{

        },

        components:{

            helloA:helloA,

            helloB:helloB,

        },

        methods:{

            handleParentClick(data){

                console.log("parent", data);

            }

        }

    })

</script>

```

**slot插槽分发**

``` html

<div id="box">

    <hello name="xiaoming">

    <button @click="handleClick" slot="leftbutton">leftbutton</button>

        <span slot="content">title_content</span>

        <button @click="handleClick" slot="rightbutton">rightbutton</button>

    </hello>

    <hello>

    <span slot="content">标题内容</span>

    <button @click="handleClick" slot="rightButton">右侧按钮</button>

    </hello>

    <hello>

    <button @click="handleClick" slot="leftbutton">左侧按钮</button>

        <span slot="content">标题内容</span>

    </hello>

</div>

<script type="text/javascript">

    var obj = {

        template:`<div>

            <slot name="leftbutton></slot>

            <slot name="content></slot>

            <slot name="rightbutton></slot>

div>

`

    }

    new Vue({

        el:#box,

        data:{

    },

    components:{

hello:obj

            }   

    },

    methods:{

        handleClick(){

            console.log("button_click")

        }

        }

    )

</script>

```

**动态组件**

* component元素,动态的绑定多个组件到它的

* keep-alive,保留状态,避免组件重新渲染

```html

<div id="box">

<keep-alive>

        <component :is="current"></component>

    </keep-alive>

    <footer>

    <ul>

            <li @click="handleclick('home')">home</li>

            <li @click="handleclick('list')">list</li>

            <li @click="handleclick('shopcar')">shopcar</li>

        </ul>

    </footer>

</div>

<script type="text/javascript">

    var home = ({

        template:`

<div>home组件</div>

`

    })

    var list = ({

        template:`

<div>list</div>

`

    })

    var shopcar = ({

        template:`

<div>shopcar</div>

`

    })

</script>

```

相关文章