8.7 VUE

362 阅读7分钟

1. VUE

2.模板语法

  • 插入文本<span>{{ msg }}</span>

1. v-for

    <div id="app">
        <ul>
            <li v-for="item in arr">{{item}}</li>
        </ul>
        <p v-for="(value,key) in list">{{key}}:{{value}}</p>
        <p v-for="item in obj">{{item.name}}:{{item,age}}</p>
    </div>
    
    <script>
        let vm = new Vue({
            el:'#app',
            data:{
                arr:[1,2,3],
                list:{
                    name:'ccc',
                    age:18,
                    height:'180cm'
                },
                obj:[
                    {
                        name: 'ccc',
                        age: 18,
                        height: '180cm'
                    },
                    {
                        name: 'ccc',
                        age: 16,
                        height: '160cm'
                    }
                ]
            }
        })
        vm.arr.push(4)//添加
    </script>

2. v-test

  • 插入文本

3. v-html

  • 插入html代码

4. v-on

  • 绑定事件
    <div id="app">
        <div>{{number}}</div>
        <button v-on:click="add">点我</button>
    </div>
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                number: 0
            },
            methods: {//方法
                add() {
                    this.number++;
                }
            }
        })
    </script>
  • 简写
    <a @click="doSomething">...</a>
  • $event 绑定事件时传参
    v-on:click="handle('ok', $event)"
    
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                number: 0
            },
            methods: {//方法
                add($event) {
                    console.log($event);
                    this.number++;
                }
            }
        })
    </script>

5. v-model

  • 表单输入绑定
  • <input> <textarea> <select> -单选框
    <input type="radio" id="one" value="One" v-model="picked">
    <input type="radio" id="two" value="Two" v-model="picked">
    
    <script>
    new Vue({
        el: '#example-4',
        data: {
            picked: ''
        }
    })
    </script>
  • 复选框
  • 绑定到同一个数组
    <div id='example'>
      <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
      <label for="jack">Jack</label>
      <input type="checkbox" id="john" value="John" v-model="checkedNames">
      <label for="john">John</label>
      <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
      <label for="mike">Mike</label>
      <br>
      <span>Checked names: {{ checkedNames }}</span>
    </div>
    
    <script>
    new Vue({
      el: '#example',
      data: {
        checkedNames: []
      }
    })
    </script>

6. v-bind

  • 绑定属性
    <div v-bind:id="dynamicId"></div>
    <!--简写-->
    <div :id="dynamicId"></div>
  • 判断绑定
  • 三种绑定方式
    <div :class="A">
    <div :class="['A','B']">
    <div :class="['A',isA?'B':'']">
    <div :class="{ classB: isB, classC: isC }">
    <div :class="{ 'list': isA? 'active':''}">//isA==true 绑定active类名
    
    <script>
    new Vue({
      el: '#example',
      data: {
        isA:true,
        isB:false,
        isC:true
      }
    })
    </script>

7. v-if

  • v-if v-else-if v-else必须紧接着写
    <div v-if="Math.random() > 0.5">
        Now you see me
    </div>
    <div v-else>
        Now you don't
    </div>

8. v-show

  • v-show 的元素始终会被渲染并保留在 DOM 中
  • v-if 不满足条件 不生成html解构
  • v-show 改变元素的 CSS 属性 display
    <h1 v-show="ok">Hello!</h1>

3. 方法

1. Vue.set

  • Vue.set( target, propertyName/index, value )
  • 解决:数值更改 页面没有更新
    <script>
        new Vue({
            el:"#app",
            data:{
                he:"点我",
                listData:["a","b","c"]
            },
            methods:{
                changeData () {
                    Vue.set(this.listData,0,'X')
                }
            }
        })
    </script>

4. 事件捕获/冒泡

  • 事件冒泡 .stop
    <button @click.stop="del(index)">删除</button>
  • 事件捕获 .capture.stop
    <button @click.capture.stop="del(index)">删除</button>

5. 数据

1. 计算属性(computed)

  • 计算属性的结果会被缓存,再次调用不会执行,除非依赖的响应式属性变化才会重新计算
    var vm = new Vue({
      data: { a: 1 },
      computed: {
        // 仅读取
        aDouble: function () {
          return this.a * 2
        },
        // 读取和设置
        aPlus: {
          get: function () {
            return this.a + 1
          },
          set: function (v) {
            this.a = v - 1
          }
        }
      }
    })

2. 方法(methods)

  • 可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用
    var vm = new Vue({
      data: { a: 1 },
      methods: {
        plus: function () {
          this.a++
        }
      }
    })
    vm.plus()
    vm.a // 2

3. 监听(watch)

  • 一个对象,键是需要观察的表达式,值是对应回调函数
    var vm = new Vue({
      data: {
        a: 1,
      },
      watch: {
        a: function (newVal, oldVal) {
          console.log('new: %s, old: %s', newVal, oldVal)
        }
    })
    vm.a = 2 // => new: 2, old: 1

6. 生命周期函数(钩子函数)

1. 生命周期

  • 从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期

2. 创建期间的生命周期函数

1. beforeCreat
  • 实例刚在内存中被创建出来,此时,还没有初始化好 el data methods 属性(undefind)
2. created
  • 实例已经在内存中创建,此时 data 和 methods 已经创建好,el(undefind),此时还没有开始 编译模板
3. beforeMount
  • 此时已经完成了模板的编译,元素已经挂载上,但是内容还没有填充进去
4. mounted
  • 此时,已经将编译好的模板,挂载到了页面指定的容器中显示

3. 运行期间的生命周期函数

1. beforeUpdate
  • 状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点,虚拟dom更新,真实dom不更新
2. updated
  • 实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
3. beforeDestroy
  • 实例销毁之前调用。在这一步,实例仍然完全可用
4. destroyed
  • Vue 实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
  • 生命周期

9. 模板template

  • 字符串模板 将会替换挂载的元素(不会渲染到页面)
  • 如果 Vue 选项中包含渲染函数,该模板将被忽略。
  • 内部元素需要一个元素包裹
    <template v-for="item in list">
        <p>{{item}}</p>
        <h1>{{item}}</h1>
    </template>

10. 组件components

  • 三种组件定义方式

1. Vue.component( id, [definition] )

  • 全局组件
  • 第一个参是string(组件名称)
  • 第二个参object(组件模板内容)
  • 可以写在任何实例对象中
    <div id="example">
        <mpl></mpl>
    </div>
    Vue.component('mpl', {      //组件名
        template: '<div>A custom component!</div>'      //组件内容
    })

2. 第二种方法

  • 局部组件
    <div id="app">
        <mydialg :aa='msg'></mydialg>
    </div>
    new Vue({
      el: '#app',       //挂载元素
      data:{
        msg:'hello'
      },
      components: { // 局部组件
        'mydialg': {        //组件名
          template: '<p>明天放假~</p>',        //组件内容
          props: ['aa']     //传值
        }
      }
    });

3. 第三种方法

    <div id="app">
        <tempp></tempp>
    </div>
    let temp = {
        template: '<h1>1234</h1>'
    }
    new Vue({
      el: '#app',
      components: { // 局部组件
        tempp:temp
    })

4. 父组件子组件

  • 子组件可以使用 $emit 触发父组件的自定义事件。
  • 方法一
    <div id="app">
        <popcommon :title="logtitle" v-show="loginStatus" @hide="close"></popcommon>//父组件绑定close方法
    </div>
    
    <template id="common">
        <div id="content">
            <span @click="$emit('hide')">X</span>//触发父组件的自定义
        </div>
    </template>
    
    <script>
        new Vue({
            el: '#app',
            components:{
              'popcommon':{
                template:'#common',
                props:['title']
              }
            },
            methods:{
              close(){
                this.reinStatus = false,
                this.loginStatus = false
              }
            }
        })
    </script>
  • 方法二
    <div id="app">
        <popcommon :title="logtitle" v-show="loginStatus" :closefun="close"></popcommon>
        <!--父组件绑定属性-->
    </div>
    
    <template id="common">
        <div id="content">
            <button @click="closefun()">{{title}}</button>
            <!--子组件绑定事件-->
        </div>
    </template>

  <script>
    new Vue({
        el: '#app',
        components:{
            'popcommon':{
                template:'#common',
                props:['title','closefun']//父组件接收
            }
        },
        methods:{
            close(){
                this.reinStatus = false,
                this.loginStatus = false
            }
        }
    })
  • 父组件可以使用 props 把数据传给子组件。
    //父级
    new Vue({
        el:"#app",
        data:{
            aaa:111,
            bbb:222
        },
        methods:{
            dosometing:function(msg){
                console.log(msg)
            }
        }
    })
    //组件:
    Vue.component('child',{
            props:['aaa'],
            template:'<input type='text'>',
             childfun:function(){
                    this.change1(1111)
        }
        });
    //调用子组件
    <child :change="dosometing" :aaa='111' :bbb='222'></child>

11. 插槽

  • 不同插槽可以有自己的name
  • 父组件slot属性 对应着 子组件里的slot的name
    <div id="app">
        <tpl>
        <!-- 父组件slot属性 对应着 子组件里的slot的name -->
            <div>
                <span>jajaja</span>
                <button>0000</button>
            </div>
            <!--指定slot2插入在此-->
            <button slot="slot2">aaa</button>
        </tpl>
    </div>
    
    <template id="temp">
        <div>
            <slot></slot>
            <br>
            名字: <input type="text">
            <br>
            <slot name="slot2"></slot>
        </div>
    </template>
    
    
    <script>
    new Vue({
        el: '#app',
        data: {
        },
        components: {
            'tpl': {
                template: '#temp'
            }
        }
    })
    </script>

12. 自定义指令

  • 一个指令定义对象可以提供如下几个钩子函数 (均为可选)
  • bind只调用一次,指令第一次绑定到元素时调用
  • inserted被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
  • update元素所在模板更新时调用
  • componentUpdated指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind只调用一次,指令与元素解绑时调用。
    <p v-bgc="'#ff0036'">123456789</p>

    <script>
        Vue.directive('bgc', {//指令名称
            bind: function (el,binding,vnode) {
                el.style.color = binding.value
            }
        }
    </script>