Vue学习笔记

Vue学习:模板语法

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>vue练习</title>
    <style>

    </style>
</head>
<body>
    <div id="root">
<!--        准备一个容器-->
<!--        <h1>hello,尚硅谷</h1>-->
<!--        hello是死的,但是想要'尚硅谷是活动的数据,就要借用vue了,就省去了DOM操作'-->
        <h1>hello,{{name}}</h1>
<!--        {{}}是一种对象分隔符-->
        <hr/>
        <h1>指令语法</h1>
        <a v-bind:href="url">点击我</a>
<!--        动态变量,使用v-bind指定变量,会将引号中的变量拿出来当成JS中的使用-->
<!--        v-bind可以简写为:,就是冒号-->
        单项数据绑定:<input type="text" v-bind:value="name">
        双向数据绑定:<input type="text" v-model:value="name">
<!--        单项数据就是只能通过JS传出数据,双向则是输入框也能传数据到JS中-->
<!--        对于v-model只能给表单用,即只能给有value值的用-->
    </div>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止vue在启动时生产提示

    //创建Vue实例
    new Vue({
        el:'#root',
        //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串,比如class用.root
        data:{//创建一个数据对象,数据供el指定的容器所使用
            name:'尚硅谷',
            url:'http://www.baidu.com'
        }
    })
</script>
</body>
</html>

Vue——回顾Object.defineproperty方法

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>回顾Object.defineproperty方法</title>
    <style>

    </style>
</head>
<body>

<script type="text/javascript">
    let num = 18;//再结合下面的age,就能变成动态更改的
    let person = {
        name:'张三',
        sex:'男',
        //age:18
    }

    Object.defineProperty(person,'age',{//这样写可以更方便的更改person对象中的age
      // value:18,
      // enumerable:true,//控制属性是否可以枚举,默认为false
      // writable:true,//控制属性是否可以被修改
      // configurable:true  //控制属性是否可以被删除

      //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
      get:function (){
          return num
      },

      //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
      set(value){
          num = value;
      }
    })
</script>
</body>
</html>

Vue事件处理

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>Vue事件处理</title>
    <style>

    </style>
</head>
<body>
    <div class="root">
        <h2>欢迎来到{{name}}学习</h2>
        <button v-on:click="showInfo">点我显示提示</button>
<!--        对于提示的Vue事件,事件都是v-开头,点击用v-on:click-->
        <button v-on:click="showInfo2(66,$event)">点我显示提示</button>
<!--        这样能够传参66到vue的事件中,$event是关键字,这样写可以防止event丢失-->
    </div>
<script type="text/javascript">
    new Vue({
        el:'.root',
        data:{
            name:'尚硅谷',
        },
        methods:{ //vue绑定的事件写在Vue里面,且用methods方法来存放
            showInfo(){
                alert('同学你好')
            },
            showInfo2(num,a){//a接收event参数
                console.log(num,a);//用num来接收参数
            }
        }
    })
</script>
</body>
</html>

 Vue阻止冒泡等

<div class="root">
        <h2>欢迎来到{{name}}学习</h2>
        <a href="http://www.baidu.com" @click.prevent = "showInfo">点我提示信息</a>
<!--        阻止事件冒泡(常用)-->
        <div class="demo1" @click="showInfo">
            <a href="http://www.baidu.com" @click.stop.prevent="showInfo"></a>
<!--    对于阻止也能连用,先停止冒泡,再阻止默认行为(比如自动跳转什么的)        -->
        </div>
</div>

Vue键盘事件

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>Vue键盘事件</title>
    <style>

    </style>
</head>
<body>
    <div class="root">
        <h2>欢迎来到{{name}}学习</h2>
        <input type="text" placeholder="按下回车提示" @keyup.enter="showInfo">
<!--        对于由两个单词组成的键,比如CapsLock,需要小写,且用分隔符隔开,写成caps-lock -->
<!--    并不是所有键都能被绑定事件,可以看上图的一些常用键-->
<!--        对于tab键盘,比较特殊,必须配合keydown使用-->
    </div>
<script type="text/javascript">
    new Vue({
        el:'.root',
        data:{
            name:'尚硅谷',
        },
        methods:{ //vue绑定的事件写在Vue里面,且用methods方法来存放
            showInfo(e){
                console.log(e.target.value)
            }
        }
    })
</script>
</body>
</html>

姓名案例-计算属性、插入语法实现、method实现

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>姓名案例</title>
    <style>

    </style>
</head>
<body>
<!--插值语法使用-->
    <div class="root">
        姓:<input type="text" v-model:value="firstname"> <br/><br/>
        名:<input type="text" v-model:value="lastname"> <br/><br/>
        姓名:<span>{{fullName}}</span>
    </div>
<script type="text/javascript">
        const vm = new Vue({
            //数据代理,需要查看,可以在控制台中输入vm查看整个,查个个别属性可以输入vm._data.firstname
            el:".root",
            data:{
                firstname:'张',
                lastname:'三',
            },
            computed:{//对于计算属性,用新的配置方法,computed
                fullName:{
                    //get的作用:当有人读取fullName时,get就会被调用,且返回值就会作为fullName的值
                    //get方法负责读取,且会留有缓存,如果想要更改数据,就要使用set()
                    get(){
                        return this.firstname + this.lastname;
                    },
                    set(value){//当fullName被修改时,使用set
                        const arr = value
                        this.firstname = arr[0]
                        this.firstname = arr[1]
                    }
                }
            }//计算属性中的属性不是直接在vm中可以被调到的
        })
</script>
</body>
</html>

天气案例——监视属性

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>天气案例-监视属性</title>
    <style>

    </style>
</head>
<body>
<!--
    监视属性watch:
        1.当被监视的属性变化时,回调函数自动调用,进行相关操作
        2.监视的属性必须存在,才能进行监视!!
        3.监视的两种写法:
            (1)new Vue时传入watch配置
            (2)通过vm.$watch监视
-->
    <div class="root">
        <h2>今天天气很好</h2>
        <button @click="changeWeather">切换天气</button>
    </div>
<script type="text/javascript">
        const vm = new Vue({
            el:".root",
            data:{
                isHot:true
            },
            computed:{
                info()
                {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods:{
                changeWeather(){
                    this.isHot = !this.isHot;
                }
            },
            // watch:{
            //     immediate:true,//初始化时让handler调用一下
            //     isHot: {
            //         //handler什么时候调用?当isHot发生改变时
            //         handler(newValue,oldValue){
            //             console.log(123)
            //         }
            //     }
            // }
        })

        vm.$watch('isHot',{ //保证vm实例对象已经被创建
            isHot: {
                //handler什么时候调用?当isHot发生改变时
                handler(newValue,oldValue){
                    console.log(123)
                }
            }
        })
</script>
</body>
</html>

监视属性扩展——深度监视

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>天气案例-监视属性</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
        <h2>今天天气很好</h2>
        <button @click="changeWeather">切换天气</button>
        <hr/>
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点我给a++</button>
        <h3>b的值是:{{numbers.b}}</h3>
        <button @click="numbers.b++">点我给b++</button>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                isHot:true,
                numbers:{
                    a:1,
                    b:2
                }
            },
            computed:{
                info()
                {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods:{
                changeWeather(){
                    this.isHot = !this.isHot;
                }
            },
            watch:{ //监视isHot的属性
                immediate:true,//初始化时让handler调用一下
                isHot: {
                    handler(){
                        console.log('isHot被改变了')
                    }
                },
                //监视多级结构中某个属性的变化
                //这里就是单独检测numbers中a的变化
                'numbers.a':{
                    handler(){
                        console.log('a被改变了')
                }
            },
                //监视多级结构中所有属性的变化
                numbers:{
                    deep:true,//开启深度默认项
                    handler(){
                        console.log('numbers改变了')
                    }
                }
        }
        })
</script>
</body>
</html>

姓名案例——watch实现(侦听属性)

computed与watch对比

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>天气案例-watch实现</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
        姓:<input type="text" v-model="firstName">
        名:<input type="text" v-model="lastName">
        全名:<span>{{fullName}}</span>

    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                firstName:'张',
                lastName:'三',
                fullName:'张-三'
            },
            computed:{

            },

            //实现watch
            watch: {

                //watch中可以写延时,是因为watch不用返回值实现
                // 对于异步计算,computed计算属性,写延时不能得到返回值,则选择watch

                firstName(newValue){//监视姓
                   //不需要深度监视的时候,就能写成一个函数来简写
                   setTimeout(()=>{//设置一个延时,1s后才会同步显示
                       this.fullName = newValue + '-' + this.lastName
                       //全名=最新的姓 + 原来的名字
                   },1000);
                },
                lastName(newValue){//监视名字
                    //不需要深度监视的时候,就能写成一个函数来简写
                    this.fullName = this.firstName + '-' + newValue
                    //全名=原来的姓 + 最新的名字
                },
            }
        })
</script>
</body>
</html>

使用Vue绑定class样式

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>绑定样式</title>
    <style>
        .basic {
            width: 400px;
            height: 100px;
            border: 1px solid black;
        }

        .happy {
            background-color: #da5555;
        }

        .normal {
            background-color: #1ba1e6;
        }

        .sad {
            background-color: #666666;
        }

        .atguigu1 {
            background-color: #40b83f;
        }

        .atguigu2 {
            color: #b1191a;
        }

        .atguigu3 {
            font-size: 18px;
        }
    </style>
</head>
<body>
<!--

-->
<!--    使用Vue实现样式替换的效果-->
    <div class="root">
<!--    这是正常情况下写的样式绑定<div class="basic normal" @click="changeMood">-->
        <div class="basic" :class="mood" @click="changeMood">
<!--    使用Vue写绑定的样式,需要绑定的写为 :class="xxx"        -->
<!--    这种方式适用于,样式的类名不确定,需要动态指定的情况        -->
            {{name}}
        </div>

<!--    另外一种写法    -->
<!--    绑定class样式,数组写法,适用于:要绑定的样式个数不确定,名字也不确定的情况下-->
        <div class="basic" :class="arr" @click="changeMood">
            {{name}}
        </div>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                name:'嗨喽',
                mood:'normal',
                arr:['atguigu1','atguigu2','atguigu3']
            },
            methods:{
                changeMood(){
                    //改变样式,有三个样式,可以写为数组
                    const arr = ['happy','sad','normal']
                    //设定随机生成0,1,2三个数组中的一个
                    const index = Math.floor(Math.random()*3)
                    //随机数函数,随机数的取值是从0到无限接近于1
                    //让随机数乘以3后,向下取整,就变成0到无限接近于3
                    this.mood = arr[index]
                }
            }
        })
</script>
</body>
</html>

条件渲染

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>条件渲染</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
<!--    这是正常情况下写的样式绑定<div class="basic normal" @click="changeMood">-->
<!--    使用v-show做条件渲染,页面不显示,但是结构框架还在    -->
<!--            <h2 v-show="false">欢迎来到{{name}}</h2>-->
<!--            <h2 v-show="1 === 1">欢迎来到{{name}}</h2>-->

<!--    使用v-if做条件渲染,结构框架也会被消掉        -->
<!--    在使用v-if时,几个标签要紧挨一起,不能在中间被其他不是if的标签打断-->
<!--    template只能与v-if配合使用,不能与show用    -->
<!--            <h2 v-if="false">欢迎来到1{{name}}</h2>-->
<!--            <h2 v-else-if="1 === 1">欢迎来到2{{name}}</h2>-->
<!--            <h2 v-else>欢迎来到3{{name}}</h2>&ndash;&gt;-->

        <h2>当前n的值是:{{n}}</h2>
        <button @click="n++">点我n+1</button>
<!--        根据n值来判断当前应该显示什么-->
        <div v-show="n === 1">a</div>
        <div v-show="n === 2">b</div>
        <div v-show="n === 3">c</div>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                name:'嗨喽',
                n:0
            },
        })
</script>
</body>
</html>

列表渲染

基本列表

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>列表渲染——基本列表</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
<!--        v-for进行循环渲染
            在不确定的情况下,可以先不写出key,先写v-for="(a,b) of car"
            当运行后得到a与b是对应什么数据了,再将key写出
-->
<!--        p是一个形参,可以直接在li中使用,插值语法{{p}}可以得到persons中的所有值-->
<!--        {{p.name}}得到姓名,其他亦是如此-->
        <h2>人员信息</h2>
        <li v-for="p in persons" :key="p.id">
            {{p.name}}-{{p.age}}
        </li>

<!--        v-for还能遍历对象,写法如下-->
        <h2>汽车信息</h2>
        <li v-for="(value,k) of car" :key="k">
            {{k}}-{{value}}
<!--        页面中将会得到:
            name-奥迪
            price-70万
            color-黑色
            则key所对应为car中的声明,也可以对应id
 -->
        </li>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                persons:[
                    {id:'001',name:'张三',age:18},
                    {id:'002',name:'李四',age:19},
                    {id:'003',name:'王五',age:20},
                ],
                car:{
                    name:'奥迪',
                    price:'70万',
                    color:'黑色'
                }
            },
        })
</script>
</body>
</html>

key的原理

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>列表渲染——key的原理</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
        <h2>人员信息(遍历数组)</h2>
        <button @click.once="add">添加一个老刘</button>
        <li v-for="(p,index) in persons" :key="p.id">
<!--     在此处,因为将新生成的数据放到最上面,所以key中写index会影响效率,输入的缓存会导致错乱
         使用p.id则不会-->
            {{p.name}}-{{p.age}}
            <input type="text">
        </li>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el:".root",
            data:{
                persons:[
                    {id:'001',name:'张三',age:18},
                    {id:'002',name:'李四',age:19},
                    {id:'003',name:'王五',age:20},
                ],
            },
            methods:{
                add(){
                    const p ={id:'004',name:'老刘',age:40}
                    this.persons.unshift(p)
                }
            }
        })
</script>
</body>
</html>

对于第3点的详细解释,当逆序添加时,使用index,会导致顺序错乱。

如下图 ,新添加的老刘的key为0,会和初始的数据中key为0的对比后,复合到一起。

而使用id的话,key值就会是一一对应的,新生成的老刘key为4,在初始数据中并没有key为4的,则不需要对比,直接生成新的空白输入框

列表过滤

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>列表渲染——列表过滤</title>
    <style>

    </style>
</head>
<body>
<!--
    类似于模糊搜索
-->
    <div class="root">
        <h2>人员信息</h2>
        <input type="text" placeholder="请输入要查找的关键字" v-model="keyWord">
        <ul>
        <li v-for="(p,index) in filPersons" :key="index">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
        </ul>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false
        //用watch监视来实现
        // const vm = new Vue({
        //     el: ".root",
        //     data: {
        //         keyWord: '',
        //         persons: [//原数组
        //             {id: '001', name: '马冬梅', age: 18, sex: '女'},
        //             {id: '002', name: '周冬雨', age: 19, sex: '女'},
        //             {id: '003', name: '周杰伦', age: 20, sex: '男'},
        //             {id: '003', name: '温兆伦', age: 22, sex: '男'},
        //         ],
        //         //定义一个新数组,可以用来保存过滤的数组
        //         filPersons: []
        //     },
        //     // watch监视
        //     watch: {
        //         keyWord:{
        //             immediate:true,
        //             handler(val){
        //                 //将所有名字中包含val的过滤出来显示
        //                 this.filPersons = this.persons.filter((p) => {
        //                     //filter会过滤掉不需要的,然后生成一个新的数组,不要用新的覆盖原数组,会导致原数组消失
        //                     return p.name.indexOf(val) !== -1
        //                     //indexOf包含会返回-1,不包含会返回0
        //                 })
        //             }
        //         }
        //     }
        // })

        //用computed实现
        new Vue({
            el: ".root",
            data: {
                keyWord: '',
                persons: [//原数组
                    {id: '001', name: '马冬梅', age: 18, sex: '女'},
                    {id: '002', name: '周冬雨', age: 19, sex: '女'},
                    {id: '003', name: '周杰伦', age: 20, sex: '男'},
                    {id: '003', name: '温兆伦', age: 22, sex: '男'},
                ],
            },
            computed:{//计算属性
                filPersons(){
                    return this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord) !== -1
                    })
                }
            }
        })
</script>
</body>
</html>

列表排序

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>列表渲染——排序</title>
    <style>

    </style>
</head>
<body>
<!--
    类似于模糊搜索
-->
    <div class="root">
        <h2>人员信息</h2>
        <input type="text" placeholder="请输入要查找的关键字" v-model="keyWord">
        <button @click="sortType = 2">年龄升序</button>
        <button @click="sortType = 1">年龄降序</button>
        <button @click="sortType = 0">原顺序</button>
        <ul>
            <li v-for="(p,index) in filPersons" :key="index">
                {{p.name}}-{{p.age}}-{{p.sex}}
            </li>
        </ul>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        new Vue({
            el: ".root",
            data: {
                keyWord: '',
                sortType:0,//0代表原顺序,1降序,2升序
                persons: [//原数组
                    {id: '001', name: '马冬梅', age: 18, sex: '女'},
                    {id: '002', name: '周冬雨', age: 23, sex: '女'},
                    {id: '003', name: '周杰伦', age: 19, sex: '男'},
                    {id: '003', name: '温兆伦', age: 22, sex: '男'},
                ],
            },
            computed:{
                //过滤与排序不分家
                //这里改动了filPersons,原数组persons未被改动,所以能够回到原顺序
                filPersons(){
                    const arr = this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord) !== -1
                    })
                    //判断是否需要排序
                    if(this.sortType !==0 ){
                        arr.sort((p1,p2)=>{///拿过滤完的数组的进行排序
                            return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
                        })
                    }
                    return arr
                }
            }
        })
</script>
</body>
</html>

Vue.set()方法添加响应式属性

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>Vue.set()方法</title>
    <style>

    </style>
</head>
<body>
<!--
    类似于模糊搜索
-->
    <div class="root">
        <h1>学校信息</h1>
        <h2>学校名称:{{name}}</h2>
        <h2>学校地址:{{address}}</h2>
        <hr/>
        <h1>学生</h1>
        <button @click="addSex">添加一个性别属性,默认为男</button>
        <h2>姓名:{{student.name}}</h2>
        <h2>性别:</h2>
<!--    要动态添加,通过Vue后台添加性别属性,可以使用Vue.set()方法    -->
<!--        具体使用是,在控制台输入Vue.set(targer,key,val)-->
<!--        此处则输入是Vue.set(vm._data.student,'sex','男'),这样插入的值就是响应式的数据,会自动生成set和get-->
<!--        还能通过控制台添加,即vm.$set(vm._data.student,'sex','女')-->
<!--        在数据代理中,vm._data.student === vm.student-->
        <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
        <h2>朋友们</h2>
        <ul>
            <li v-for="(f,index) in student.friends" :key="index">
                {{f.name}}--{{f.name}}
            </li>
        </ul>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el: ".root",
            data: {
                name:'尚硅谷',
                address:'北京',
                student:{
                    //set添加响应式数据,不能直接给data中添加,只能给data中的某个对象中添加
                    //比如这里只能给student或者age,friedns中添加,不能添加与name,address同级的
                    name: 'tom',
                    age:{
                        rAge:40,
                        sAge:29,
                    },
                    friends:[
                        {name:'jerry',age:35},
                        {name:'tony',age:36}
                    ]
                }
            },
            methods:{
                // methods中的方法中的属性,this就等于vm,在正常写情况下
                addSex(){
                    Vue.set(this.student,'sex','男')
                    // this.$set(this.student,'sex','男')
                    //两种都可以
                }
            }
        })
</script>
</body>
</html>

 收集表单数据

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>收集表单数据</title>
    <style>

    </style>
</head>
<body>
<!--
      v-model.number是让收集到的信息为数字
      v-model.lazy让数据不是实时收集,当用户点击输入下一条框时,才收集当前条
      v-model.trim收集时,自动去掉前后的空格
-->
    <div class="root">
        <form @submit.prevent="demo">
<!--            阻止表单提交默认跳转页面行为,也就是阻止刷新-->
            账号:<input type="text" v-model="account"> <br/><br/>
            密码:<input type="password" v-model="password"> <br/><br/>
            年龄:<input type="number" v-model.number="age"> <br/><br/>
<!--            年龄中type="number"是原生控制不能让输入框输入不是年龄的-->
<!--            v-model.number="age"能够让接收到的信息是数字-->
            性别:
            男<input type="radio" name="sex" v-model="sex" value="male">
<!--            在性别中添加value,就能让选上的值传入Vue中,传入的是male或female-->
            女<input type="radio" name="sex" v-model="sex" value="female"> <br/><br/>
            爱好:
            学习<input type="checkbox" v-model="hobby" value="study">
<!--            不配置value值,就会默认传入全部的值checked-->
            打游戏<input type="checkbox" v-model="hobby" value="game">
            睡觉<input type="checkbox" v-model="hobby" value="sleep"> <br/><br/>
            所属校区
            <select v-model="city">
                <option value="">请选择校区</option>
                <option value="beijing" >北京</option>
                <option value="shanghai" >上海</option>
                <option value="shenzhen" >深圳</option>
            </select>
            <br/><br/>
            其他信息:
            <textarea v-model="other"></textarea>
            <br/><br/>
            <input type="checkbox" v-model="agree">阅读并接受<a href="#">《阅读协议》</a>
            <br/><br/>
            <button>提交</button>
        </form>
    </div>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el: ".root",
            data: {
                // userInfo:{
                    account:'',
                    password:'',
                    sex:'male',//这样可以一打开就有默认选好的
                    hobby:[],//hobby的初始值会影响传入数据
                    //如果多组勾选框,应该使用数组形式
                    city:'',
                    other:'',
                    agree:'',
                    age:''
                // }
            },
            methods:{
                demo(){
                    // console.log(JSON.stringify(this.userInfo))
                    //此方法需要在上方代码的v-model前添加userInfo,变成userInfo.v-model
                    //使用以下方法可以不需要添加,但一般不会直接写data
                    console.log(JSON.stringify(this._data))
                }
            }
        })
</script>
</body>
</html>

内置指令

对于v-text,它会解析Vue的data中传来的所有,包括标签,都会解析为字符串,同时在里面再写你好之类的,都不会显示, 会被吞掉

 

  

自定义指令

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>自定义指令</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
        <h2>当前的n值是:<span v-text="n"></span> </h2>
        <h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
        <button @click="n++">点我n+1</button>
        <hr/>
        <input type="text" v-fbind:value="n">
<!--        此处的fbind为自定义指令,获取焦点,即光标一进来就在输入框,或者输入框中就有值-->
    </div>
</body>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el: ".root",
            data: {
                n:1
            },
            directives:{
                //big函数被调用条件,1.指令与元素成功绑定时2.指令所在的模板被重新解析时
                big:function (element,binding){
                    element.innerHTML = binding.value*10
                },
                fbind:{//将fbind写成一个对象
                    //按照该顺序来调用
                    bind(element,binding){//指令与元素成功绑定时调用
                        element.value = binding.value
                    },
                    inserted(element,binding){//指令所在元素被插入页面时
                        element.focus()//获取焦点
                    },
                    update(element,binding){//指令所在的模板被重新解析时
                        element.value = binding.value
                    }
                }
            }
        })
</script>
</html>

 生命周期

 引出生命周期,认识什么是生命周期函数

像钩子一样,需要用什么函数的时候,就用钩子钩出什么函数

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>引出生命周期</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
        <h2 :style="{opacity}">欢迎</h2>
<!--        透明度样式-->
    </div>
</body>
<script type="text/javascript">
        Vue.config.productionTip = false

        const vm = new Vue({
            el: ".root",
            data: {
                opacity:1
            },
            methods:{

            },
            //认识生命周期函数,如下mounted就是,在特殊时间点被调用的函数
            //Vue完成模板的解析并把真实的DOM元素放入页面后(完成挂载)调用mounted
            //挂载,是第一次就在页面显示的,后面才出现的是更新
            mounted(){
                setInterval(()=>{//定时器
                    this.opacity-=0.01
                    if(this.opacity<=0)this.opacity=1
                },16)
            }
        })


</script>
</html>

组件化编程

非单文件组件 

基本使用

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width" ,initial-scale="1.0">
    <script type="text/javascript" src="js/vue.js"></script>
    <title>非单文件组件_基本使用</title>
    <style>

    </style>
</head>
<body>
<!--

-->
    <div class="root">
<!--        第三步,编写组件标签-->
<!--        这样写,组件可以复用,很方便-->
        <xuexiao></xuexiao>
        <hr/>
        <xuesheng></xuesheng>
    </div>
</body>
<script type="text/javascript">
        Vue.config.productionTip = false

        //第一步,组件创建
        //创建school组件,这里的school只是一个中转的变量,也可以定义为a、b啥的
        const school = Vue.extend({
            //el: ".root",组件定义时,不要写el,data会对应给school组件
            template:`
              <div>
                <h2>学校名称:{{schoolName}}</h2>
                <h2>学校地址:{{address}}</h2>
              </div>
            `,
            data(){
                return {
                    schoolName:'尚硅谷',
                    address:'北京'
                }
            },
        })

        //创建student组件
        const student = Vue.extend({
            //el: ".root",组件定义时,不要写el,data会对应给school组件
            template:`
              <div>
                <h2>学生姓名:{{studentName}}</h2>
                <h2>学生年龄:{{age}}</h2>
              </div>
            `,
            data(){
                return {
                    studentName:'小红',
                    age:18
                }
            },
        })

        //创建vm
        new Vue({
            el:'.root',
            //第二部,注册组件
            //局部注册
            components:{
                //这里的xuexiao这些才是组件名称
                xuexiao:school,
                xuesheng:student
            }
        })
</script>
</html>

在写子组件的时候,需要将子组件放在父组件上面

 1.实例的隐式对象属性,永远指向实例缔造者的原型对象

 2.vc是这里自己取的名字,它其实是一个相对于vm差一点的小型实例对象

单文件组件

需要在脚手架中运行,才能得到支持

创建文件为:

1.index.html  主要的框架文件,必须有

2.main.js   让vue组件文件与html相连接交互的文件,必须有

3.App.vue  汇总所有组件的文件,必须要有

4.school.vue 组件文件,要继续写更多,就改名,比如student.vue等

2.main.js 

import App from "./App.vue";

new Vue({
    el:'.root',
    components:{App},
})

//还需要一个最终的容器文件,html
//在html中的最下方写,<script type="text/javascript" src="./main.js"></script>来引入文件
//然后在html的div class=root中写<App><App/>

3.App.vue 

<!--在这里,需要引入别处的vue组件文件-->
<!--app.vue的作用是汇总组件-->
<!--还需要创建对应的js文件,可以命名为main.js,或者index.js-->

<template>
  <div>
    <school></school>
  </div>
</template>

<script>
//引入组件
import school from "./school.vue";
import School from "./school.vue";
export default {//默认导出
  name:'App',
  components: {School},
  computeds:{//注册
    school
  }
}
</script>

<style>

</style>

4.school.vue 

<!--单文件组件-->
<!--写单文件组件时,创建完所需的xxx.vue文件后,必须要有一个文件,app.vue-->

<template>
<!--  组件的结构-->
<!--  这里按照原来的html写-->
</template>

<script>
  //组件交互相关的代码(数据、方法等)
  //在这里,其他地方,数据,方法是一样的写,但是开头需要有export引入(暴露)
  export default {//默认导出
    name:'school',
    data(){
      return {
        name:'尚硅谷',
        address:'北京'
      }
    },
    methods:{
      show(){
        alert(this.name)
      }
    }
  }
</script>

<style>
  /*组件的样式*/
/*  此处样式也是按照原来的html写*/
</style>

<!-- .vue文件中仅支持这些标签 -->

脚手架 

首先需要安装nodejs,然后将npm路径改成淘宝镜像

再安装脚手架,即vue官网中的vue CIL,文档说明中有写输入什么进行安装

在cmd中选一个文件夹路径,桌面也可以,然后输入vue create xxx(这里的xxx是项目的名称)

选择版本,创建完成后,然后在cmd的文件夹中输入npm run serve来运行

之后会显示两个地址,可以将地址给其他人一起用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值