美文网首页
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>

    ```

    相关文章

      网友评论

          本文标题:Vue基础(上)

          本文链接:https://www.haomeiwen.com/subject/xgspnftx.html