vue学习

vue

MVVM思想
M:model 包括数据和一些基本操作
V:view 视图,页面渲染结果
VM:View-model,模型与视图间的双向操作(无需开发人员干涉)
视图和数据通过VM绑定起来,model里有变化会自动地通过Directives填写到视view中,
视图表单中添加了内容也会自动地通过DOM Listeners保存到模型中。

将vue文档下载到本地预览

1下载:https://github.com/vuejs/cn.vuejs.org   到本地
npm install
npm start # 开发服务器地址为 http://localhost:4000

基础案例

在VSCode中安装vue 2 snippets语法提示插件,在谷歌浏览器中安装vue.js devtools

<!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>Document</title>
</head>

<body>

    <div id="app">
        <input type="text" v-model="num">
        v-model实现双向绑定
        <button v-on:click="num++">点赞</button>
        v-on:click绑定事件,实现自增
        <button v-on:click="cancel">取消</button>
        回到自定义的方法
        
        <h1> {{name}} ,非常帅,有{{num}}个人为他点赞{{hello()}}</h1>
    </div>

    <!-- 导入依赖 -->
    <script src="./node_modules/vue/dist/vue.js"></script>

    <script>
        //1、vue声明式渲染
        let vm = new Vue({ //生成vue对象
            el: "#app",//绑定元素 div id="app"
            data: {  //封装数据
                name: "张三",  // 也可以使用{} //表单中可以取出
                num: 1
            },
            methods:{  //封装方法
                cancel(){
                    this.num -- ;
                },
                hello(){
                    return "1"
                }
            }
        });
        还可以在html控制台vm.name

        //2、双向绑定,模型变化,视图变化。反之亦然。
        //3、事件处理

        //v-xx:指令

        //1、创建vue实例,关联页面的模板,将自己的数据(data)渲染到关联的模板,响应式的
        //2、指令来简化对dom的一些操作。
        //3、声明方法来做更复杂的操作。methods里面可以封装方法。

    </script>
</body>

</html>

v-text、v-html.html

<!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>Document</title>
</head>
<body>
   
    <div id="app">
        {{msg}}  {{1+1}}  {{hello()}}<br/>
        用v-html取内容
        <span v-html="msg"></span>
        
        <br/>
        原样显示
        <span v-text="msg"></span>

        
    </div>
   
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        new Vue({
            el:"#app",
            data:{
                msg:"<h1>Hello</h1>",
                link:"http://www.baidu.com"
            },
            methods:{
                hello(){
                    return "World"
                }
            }
        })
    </script>
    
</body>
</html>

插值表达式

花括号:只能写在标签体内,不能用在标签内。用v-bind解决
{{}}必须有返回值

单向绑定v-bind

<!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>Document</title>
</head>
<body>

    <!-- 给html标签的属性绑定 -->
    <div id="app"> 

        <a v-bind:href="link">gogogo</a>

        <!-- class,style  {class名:加上?}-->
        <span v-bind:class="{active:isActive,'text-danger':hasError}"
          :style="{color: color1,fontSize: size}">你好</span>


    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                link: "http://www.baidu.com",
                isActive:true,
                hasError:true,
                color1:'red',
                size:'36px'
            }
        })
    </script>

</body>
</html>

双向绑定v-model

<!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>Document</title>
</head>
<body>

    <!-- 表单项,自定义组件 -->
    <div id="app">

        精通的语言:
            <input type="checkbox" v-model="language" value="Java"> java<br/>
            <input type="checkbox" v-model="language" value="PHP"> PHP<br/>
            <input type="checkbox" v-model="language" value="Python"> Python<br/>
        选中了 {{language.join(",")}}
    </div>
    
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                language: []
            }
        })
    </script>

</body>
</html>

v-on

<!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>Document</title>
</head>

<body>
    <div id="app">
                
        <!--事件中直接写js片段-->
        <button v-on:click="num++">点赞</button>
        <!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
        <button @click="cancel">取消</button>
        <!--  -->
        <h1>有{{num}}个赞</h1>


        <!-- 事件修饰符 -->
        <div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">
            大div
            <div style="border: 1px solid blue;padding: 20px;" @click.stop="hello">
                小div <br />
                <a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a>
            </div>
        </div>



        <!-- 按键修饰符: -->
        <input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num=10"><br />

        提示:

    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        new Vue({
            el:"#app",
            data:{
                num: 1
            },
            methods:{
                cancel(){
                    this.num--;
                },
                hello(){
                    alert("点击了")
                }
            }
        })
    </script>
</body>

</html>

v-for

<!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>Document</title>
</head>

<body>

    <div id="app">
        <ul>
            <li v-for="(user,index) in users" :key="user.name" v-if="user.gender == '女'">
                <!-- 1、显示user信息:v-for="item in items" -->
               当前索引:{{index}} ==> {{user.name}}  ==>   {{user.gender}} ==>{{user.age}} <br>
                <!-- 2、获取数组下标:v-for="(item,index) in items" -->
                <!-- 3、遍历对象:
                        v-for="value in object"
                        v-for="(value,key) in object"
                        v-for="(value,key,index) in object" 
                -->
                对象信息:
                <span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span>
                <!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 -->
            </li>

            
        </ul>

        <ul>
            <li v-for="(num,index) in nums" :key="index"></li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>         
        let app = new Vue({
            el: "#app",
            data: {
                users: [{ name: '柳岩', gender: '女', age: 21 },
                { name: '张三', gender: '男', age: 18 },
                { name: '范冰冰', gender: '女', age: 24 },
                { name: '刘亦菲', gender: '女', age: 18 },
                { name: '古力娜扎', gender: '女', age: 25 }],
                nums: [1,2,3,4,4]
            },
        })
    </script>
</body>

</html>

v-if和v-show

v-if进行dom的删除和插入,v-show,通过样式进行隐藏

<!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>Document</title>
</head>

<body>
    <!-- 
        v-if,顾名思义,条件判断。当得到结果为true时,所在的元素才会被渲染。
        v-show,当得到结果为true时,所在的元素才会被显示。 
    -->
    <div id="app">
        <button v-on:click="show = !show">点我呀</button>
        <!-- 1、使用v-if显示 -->
        <h1 v-if="show">if=看到我....</h1>
        <!-- 2、使用v-show显示 -->
        <h1 v-show="show">show=看到我</h1>
    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>
        
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                show: true
            }
        })
    </script>

</body>

</html>

vue-ref指令

v-else和v-else-if

<!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>Document</title>
</head>

<body>
    <div id="app">
        <button v-on:click="random=Math.random()">点我呀</button>
        <span>{{random}}</span>

        <h1 v-if="random>=0.75">
            看到我啦?! &gt;= 0.75
        </h1>

        <h1 v-else-if="random>=0.5">
            看到我啦?! &gt;= 0.5
        </h1>

        <h1 v-else-if="random>=0.2">
            看到我啦?! &gt;= 0.2
        </h1>

        <h1 v-else>
            看到我啦?! &lt; 0.2
        </h1>

    </div>


    <script src="../node_modules/vue/dist/vue.js"></script>
        
    <script>         
        let app = new Vue({
            el: "#app",
            data: { random: 1 }
        })     
    </script>
</body>

</html>

计算属性和侦听器

<!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>Document</title>
</head>

<body>
    <div id="app">
        <!-- 某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。来完成 -->
        <ul>
            <li>西游记; 价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"> </li>
            <li>水浒传; 价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"> </li> 
            <li>总价:{{totalPrice}}</li>
            {{msg}}
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        //watch可以让我们监控一个值的变化。从而做出相应的反应。
        new Vue({
            el: "#app",
            data: {
                xyjPrice: 99.98,
                shzPrice: 98.00,
                xyjNum: 1,
                shzNum: 1,
                msg: ""
            },
            computed: {
                totalPrice(){
                    return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum
                }
            },
            watch: {
                xyjNum(newVal,oldVal){
                    if(newVal>=3){
                        this.msg = "库存超出限制";
                        this.xyjNum = 3
                    }else{
                        this.msg = "";
                    }
                }
            },
        })
    </script>

</body>

</html>

vue 事件监听和es6模板语法

es6模板语法的反引号是通过左上角的飘字符弄出来了,学废了吗?

img

过滤器

<!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>Document</title>
</head>

<body>
    <!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 -->
    <div id="app">
        <ul>
            <li v-for="user in userList">
                {{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>
                {{user.gender | genderFilter}} ==> {{user.gender | gFilter}}
            </li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>

        Vue.filter("gFilter", function (val) {
            if (val == 1) {
                return "男~~~";
            } else {
                return "女~~~";
            }
        })

        let vm = new Vue({
            el: "#app",
            data: {
                userList: [
                    { id: 1, name: 'jacky', gender: 1 },
                    { id: 2, name: 'peter', gender: 0 }
                ]
            },
            filters: {
                 filters 定义局部过滤器,只可以在当前vue实例中使用
                genderFilter(val) {
                    if (val == 1) {
                        return "男";
                    } else {
                        return "女";
                    }
                }
            }
        })
    </script>
</body>

</html>

vue-通过name进行数据过滤

<template>
<div>
    <h3>搜索列表</h3>
<input type="text" placeholder="请输入要搜索的名字" v-model="searchName"> 
<ul>
<li v-for="(person,index) in fileterPersons" :key="personsKeys[index]">
 {{personsKeys[index]}}--
{{person.name}}--
{{person.age}}--
{{person.sex}}--

</li>
</ul>

</div>
</template>
<script>
import shortid from 'shortid'
export default{
    name:"list",
    data(){
        return {
            searchName:'',
            persons:[
                {name:'张三',age:18,sex:'男'},
                {name:'李四2',age:128,sex:'男'},
                {name:'王五',age:138,sex:'男'},
                {name:'赵六',age:148,sex:'男'},
                {name:'田七',age:158,sex:'男'},
                {name:'邢八',age:168,sex:'男'},
                {name:'高久',age:178,sex:'男'},

                
                ],
               personsKeys:[],
        }
    },
    //生命周期方法
mounted(){
    this.personsKeys=this.persons.map(v=>shortid.generate())
},
computed:{
    //过滤
    fileterPersons(){
//1获取数据
let {searchName,persons}=this;
//2取出数组中的数据
let arr=[...persons];
//3.过滤数组
        if(searchName.trim()){
            arr=persons.filter((p)=>(p.name.indexOf(searchName)!==-1));
        }
        return arr;
    }
}
}
</script>
<style scoped>

ul{
    list-style: none;
}
ul li{
    padding:3px 0;
}
</style>

  

思路:

1.要知道使用计算属性来进行操作,computed

 

vue进行代码排序

<template>

<div>
    <div>
    <h3>排序
    </h3>
    <button @click="orderByAge(0)">默认</button>
    <button @click="orderByAge(2)">升序</button>
    <button @click="orderByAge(1)">降序</button>
</div>
    <h3>搜索列表</h3>
<input type="text" v-model="searchName" placeholder="请输入名字">

<ul>
    <li v-for="(p,index) in fileterPersons">
        {{index}} --{{p.name}}--{{p.age}}
    </li>
</ul>
</div>
</template>
<script>
export default{
    name:"list",
    data(){
        return {
            orderType:0,
          searchName:'',
            persons:[
                {name:'张三',age:18,sex:'男'},
                {name:'李四2',age:128,sex:'男'},
                {name:'王五',age:138,sex:'男'},
                {name:'赵六',age:148,sex:'男'},
                {name:'田七',age:158,sex:'男'},
                {name:'邢八',age:168,sex:'男'},
                {name:'高久',age:178,sex:'男'},

                
                ],
        }
    },

    methods:{
        orderByAge(orderType)
        {
            this.orderType=orderType;
        }
    },
    computed:{
//过滤的
fileterPersons(){
    //ordertype传过来
let {searchName,persons,orderType}=this;
let arr=[...persons];
//
if(searchName.trim()){
    arr=persons.filter((p)=>(p.name.indexOf(searchName)!==-1));
}
//排序
if(orderType){
    arr.sort((p1,p2)=>{
        if(orderType===1){//1为降序
       return  p2.age-p1.age;
        }else{
          return   p1.age-p2.age;
        }



    });
}
return arr;
}
    },
}
</script>
<style scoped>

</style>

vue文件引入

只要能正确写文件,将数据正常导入,别名什么都行

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <!-- <h1>我们一起学习vue</h1> -->
<label> <input type="tex" v-model="msg"></label>
 
  </div>
</template>
 
<script>
export default {
  name: 'HelloWorld2',
data(){
  return{
    msg:"我们一起学vue"
  }
}
}
</script>
 
<!--scoped 作用当前组件 -->
<style scoped>
 
</style>

img

img

组件化

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相
同的部分。
例如可能会有相同的头部导航。
但是如果每个页面都自开发,这无疑增加了我们开发的成本。所以我们会把页面
的不同分拆分成立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在vue里,所有的vue实例都是组件

组件其实也是一个vue实例,因此它在定义时也会接收:data、methods、生命周期函等

不同的是组件不会与页面的元素綁定,否则就无法复用了,因此没有el属性。
但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组了
data必须是一个函数,不再是一个对象。

<!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>Document</title>
</head>

<body>

    <div id="app">
        <button v-on:click="count++">我被点击了 {{count}} 次</button>

        <counter></counter>
        <counter></counter>
        <counter></counter>
        <counter></counter>
        <counter></counter>

        <button-counter></button-counter>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>


    <script>
        //1、全局声明注册一个组件
        Vue.component("counter", {
            template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`,
            data() {
                return {
                    count: 1
                }
            }
        });

        //2、局部声明一个组件
        const buttonCounter = {
            template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`,
            data() {
                return {
                    count: 1
                }
            }
        };

        new Vue({
            el: "#app",
            data: {
                count: 1
            },
            components: {
                'button-counter': buttonCounter
            }
        })
    </script>
</body>

</html>

生命周期钩子函数

<!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>Document</title>
</head>

<body>
    <div id="app">
        <span id="num">{{num}}</span>
        <button @click="num++">赞!</button>
        <h2>{{name}},有{{num}}个人点赞</h2>
    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>
    
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                name: "张三",
                num: 100
            },
            methods: {
                show() {
                    return this.name;
                },
                add() {
                    this.num++;
                }
            },
            beforeCreate() {
                console.log("=========beforeCreate=============");
                console.log("数据模型未加载:" + this.name, this.num);
                console.log("方法未加载:" + this.show());
                console.log("html模板未加载:" + document.getElementById("num"));
            },
            created: function () {
                console.log("=========created=============");
                console.log("数据模型已加载:" + this.name, this.num);
                console.log("方法已加载:" + this.show());
                console.log("html模板已加载:" + document.getElementById("num"));
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            beforeMount() {
                console.log("=========beforeMount=============");
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            mounted() {
                console.log("=========mounted=============");
                console.log("html模板已渲染:" + document.getElementById("num").innerText);
            },
            beforeUpdate() {
                console.log("=========beforeUpdate=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板未更新:" + document.getElementById("num").innerText);
            },
            updated() {
                console.log("=========updated=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板已更新:" + document.getElementById("num").innerText);
            }
        });
    </script>
</body>

</html>                                                                                                                                                 

自定义全局指令和局部指令

//注册全局指令

Vue.directive('upper-word',(el,binding)=>{
  el.textContent=binding.value.toUpperCase();
  
});
<p>自定义全局指令</p>

<p v-upper-word='word'></p>
 

 directives:{
       'lower-word'(el,binding){
           el.textContent=binding.value.toLowerCase(); 
       }
   },

<p>========自定义局部指令============</p>
<p v-lower-word='word'></p>

定义全局时间过滤器

<template>
<div>
<h3>格式化时间</h3>
<p>{{time|timeFormat}}</p>
<p>{{time|timeFormat("YYYY")}}</p>

</div>
</template>
<script>

export default{
    name:"foemt",
    data(){
        return {
        time:new Date(),
        }
    },
    mounted(){
        setInterval(()=>{
            this.time=new Date()
        },1000);
    },
}
</script>
<style scoped>
</style>

  注意:要如果没安装插件记得在项目安装插件:npm i moment --save

Vue.filter('timeFormat',(value,format='YYYY-MM-DD HH:mm:ss')=>{
  return moment(value).format(format);
});

由于vue的for循环id并不严谨,提高id严谨性

如果后台没有传入id,我们拿到的数据没有id修改等操作不方便,如何拿到id呢

https://github.com/dylang/shortid 提供唯一id

img

img

img

img

<template>
<div>
 <h3>遍历数组</h3>
<ul>
<li v-for="(person,index) in persons " key="personsKeys[index]">
id: {{personsKeys[index]}}<br/>
 姓名 : {{person.name}},
年龄 : {{person.age}},
性别 : {{person.sex}},
 
 
</li>
 
</ul>
 
</div>
</template>
<script>
import shortId from 'shortid'
export default{
    name:"ifAndShow",
    data(){
        return {
            persons:[
                {name:'张三',age:18,sex:'男'},
                {name:'张三2',age:128,sex:'男'},
                {name:'张三3',age:138,sex:'男'},
                {name:'张三4',age:148,sex:'男'},
                {name:'张三5',age:158,sex:'男'},
                {name:'张三6',age:168,sex:'男'},
                {name:'张三7',age:178,sex:'男'},
 
                 
                ],
 
                personsKeys:[]
        }
    },
    //生命周期方法
    mounted(){
        this.personsKeys=this.persons.map(v=>shortId.generate())
    }
}
</script>
<style scoped>
</style>

使用Vue脚手架进行开发

全局安装webpack
1 npm install webpack -g
全局安装vue脚手架
2 npm install -g @vue/cli-init
3 初始化vue项目
vue init webpack appname:vue脚手架使用webpack模板初始化一个appname项目
4 启动vue项目
项目的package.json中有scripts,代表我们能运行的命令
npm start = npm run dev: 启动项目
npm run build:将项目打包

使用element-ui

推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S

在 main.js 中写入以下内容:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

posted @ 2020-11-02 13:01  三号小玩家  阅读(915)  评论(0编辑  收藏  举报
Title
三号小玩家的 Mail: 17612457115@163.com, 联系QQ: 1359720840 微信: QQ1359720840