vue基础知识

2020-05-14  本文已影响0人  付小影子

vue教程
vue官网
BootCDN
我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入。
或者从CDN上面搜索vue,复制地址引入

每个 Vue 应用都需要通过实例化 Vue 来实现。

语法格式如下:

var vm = new Vue({
  // 选项...
})
    var vue = new Vue({
            //绑定
            el: '#app',
            //实例内自定义局部组件
            components: {
                'runoob': Child
            },
            //也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用
           directives: {
              // 注册一个局部的自定义指令 v-focus
               focus: {
                  // 指令的定义
                   inserted: function (el) {
                  // 聚焦元素
                   el.focus()
                  }
               }
           },
            //数据
            data:  {
            msg: 'hello shadow,hello vue!',
            count: 15,
            message: '<h2>明天你好</h2>',
            use: false,
            url: "http://www.baidu.com",
            filtersData: "hello",
            list1: [1, 2, 3, 4, 5],
            list2: [{ name: 'shadow', age: 18 }, { name: 'tom', age: 88 }],
            object: {
                name: 'shadow',
                url: 'http://www.baidu.com',
                slogan: '吃好喝好玩好!'
            },
            isActive: true,
            hasError: true,
            error: {
                value: true,
                type: 'fatal'
            },
            message3: '',
            message2: '',
            sites: [
                { text: 'Runoob' },
                { text: 'Google' },
                { text: 'Taobao' }
            ],
            total: 0
        },
            //方法
            methods: {
                details() {
                    return "hello world!!!"
                },
                addCount() {
                    this.count++;
                },
                say(meassage) {
                    alert(meassage)
                },
                incrementTotal: function () {
                    this.total += 1
                }
            },
            //筛选
            filters: {
                //取第一个字符,转换大写
                capitalize(value) {
                    if (!value) return ''
                    value = value.toString()
                    return value.charAt(0).toUpperCase() + value.slice(1)
                }
            },
            //监听,只能监听一个数据变量的变化 通过 watch 来响应数据的变化。
            watch: {
                //监听变量msg的变化
                msg(newVlue, oldValue) {
                    console.log("old:" + oldValue + "---new:" + newVlue)
                }
            },
            //计算,可以动态监听构成msg1的所有数据的变化,任意一个变量变化,msg1就会发生变化
            //计算属性在处理一些复杂逻辑时是很有用的
            //可以使用 methods 来替代 computed,效果上两个都是一样的,
            //但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。
            //而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
            //如果你不希望缓存,你可以使用 methods 属性
            computed: {
                msg1() {
                    return this.msg + "---" + this.count
                },
                classObject: function () {
                    return {
                        base: true,
                        active: this.isActive && !this.error.value,
                        'text-danger': false,
                    }
                }

            }
        });

可以看到在 Vue 构造器中有一个el 参数,它是 DOM 元素中的 id。 这意味着我们接下来的改动全部在以上指定的 div 内,div 外部不受影响

data 用于定义属性

methods 用于定义的函数,可以通过 return 来返回函数值。

{{ }} 用于输出对象属性和函数返回值

当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。
当这些属性的值发生改变时,html 视图将也会产生相应的变化。

除了数据属性,Vue 实例还提供了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来

vue.$watch('count', function (nval, oval) {
            alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
        });

======插值=======

数据绑定最常见的形式就是使用 {{...}}(双大括号)的文本插值

======属性=========

HTML 属性中的值应使用 v-bind 指令。
Vue.js 都提供了完全的 JavaScript 表达式支持。

========指令============

指令是带有 v- 前缀的特殊属性。

使用 v-html 指令用于输出 html 代码:

指令用于在表达式的值改变时,将某些行为应用到 DOM 上

v-if 指令

将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素。
可以用 v-else 指令给 v-if 添加一个 "else" 块:
v-else-if 在 2.1.0 新增,顾名思义,用作 v-if 的 else-if 块。可以链式的多次使用
也可以使用 v-show 指令来根据条件展示元素:

<div id="app">
    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    type: 'C'
  }
})
</script>

v-bind 指令被用来响应地更新 HTML 属性

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组
可以为 v-bind:class 设置一个对象,从而动态的切换 class:
<div v-bind:class="{ active: isActive }"></div>

也可以在对象中传入更多属性用来动态切换多个 class 。
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>

也可以直接绑定数据里的一个对象:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
</head>
<body>
<div id="app">
  <div v-bind:class="classObject"></div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    classObject: {
      active: true,
      'text-danger': true
    }
  }
})
</script>
</body>

也可以在这里绑定返回对象的计算属性
可以把一个数组传给 v-bind:class
<div v-bind:class="[activeClass, errorClass]"></div>

还可以使用三元表达式来切换列表中的 class :
<div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>

可以在 v-bind:style 直接设置样式:

<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>
也可以直接绑定到一个样式对象

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <div v-bind:style="styleObject">菜鸟教程</div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'green',
      fontSize: '30px'
    }
  }
})
</script>
</body>
</html>

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <div v-bind:style="[baseStyles, overridingStyles]">菜鸟教程</div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    baseStyles: {
      color: 'green',
      fontSize: '30px'
    },
    overridingStyles: {
      'font-weight': 'bold'
    }
  }
})
</script>
</body>
</html>

v-bind 缩写

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

v-on 指令,它用于监听 DOM 事件 <a v-on:click="doSomething">

v-on 缩写

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

v-model 指令来实现双向数据绑定:

v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

vue.js 允许你自定义过滤器,被用作一些常见的文本格式化

<!-- 在两个大括号中 -->
{{ message | capitalize }}

<!-- 在 v-bind 指令中 -->
<div v-bind:id="rawId | formatId"></div>

过滤器函数接受表达式的值作为第一个参数。

<div id="app">
  {{ message | capitalize }}
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'runoob'
  },
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
</script>

循环使用 v-for 指令。

v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。

v-for 可以绑定数据到数组来渲染一个列表

v-for 可以通过一个对象的属性来迭代数据:

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.name }}
    </li>
  </ol>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    sites: [
      { name: 'Runoob' },
      { name: 'Google' },
      { name: 'Taobao' }
    ]
  }
})
</script>

你也可以提供第二个的参数为键名:

<div id="app">
  <ul>
    <li v-for="(value, key) in object">
    {{ key }} : {{ value }}
    </li>
  </ul>
</div>

第三个参数为索引:

<div id="app">
  <ul>
    <li v-for="(value, key, index) in object">
     {{ index }}. {{ key }} : {{ value }}
    </li>
  </ul>
</div>

v-for 迭代整数

<div id="app">
  <ul>
    <li v-for="n in 10">
     {{ n }}
    </li>
  </ul>
</div>

计算属性关键词: computed。

计算属性在处理一些复杂逻辑时是很有用的
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
 
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

Vue.js 监听属性 watch,我们可以通过 watch 来响应数据的变化

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
   <body>
      <div id = "computed_props">
         千米 : <input type = "text" v-model = "kilometers">
         米 : <input type = "text" v-model = "meters">
      </div>
       <p id="info"></p>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#computed_props',
            data: {
               kilometers : 0,
               meters:0
            },
            methods: {
            },
            computed :{
            },
            watch : {
               kilometers:function(val) {
                  this.kilometers = val;
                  this.meters = this.kilometers * 1000
               },
               meters : function (val) {
                  this.kilometers = val/ 1000;
                  this.meters = val;
               }
            }
         });
         // $watch 是一个实例方法
    vm.$watch('kilometers', function (newValue, oldValue) {
    // 这个回调将在 vm.kilometers 改变后调用
    document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
       })
      </script>
   </body>
</html>

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
注册一个全局组件语法格式如下:
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>

全局组件 可以在全局使用

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <runoob></runoob>
</div>

<script>
// 注册
Vue.component('runoob', {
  template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>
</body>
</html>

局部组件 只能在当前vue实例中使用

<div id="app">
    <runoob></runoob>
</div>
 
<script>
var Child = {
  template: '<h1>自定义组件!</h1>'
}
 
// 创建根实例
new Vue({
  el: '#app',
  components: {
    // <runoob> 将只在父模板可用
    'runoob': Child
  }
})
</script>

prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <child message="hello!"></child>
</div>

<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 “this.message” 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>
</body>
</html>

动态 Prop

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:


<div id="app">
    <div>
      <input v-model="parentMsg">
      <br>
      <child v-bind:message="parentMsg"></child>
    </div>
</div>
 
<script>
// 注册
Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 同样也可以在 vm 实例中像 "this.message" 这样使用
  template: '<span>{{ message }}</span>'
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    parentMsg: '父组件内容'
  }
})
</script>

例子

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
</head>
<style>
    .class1 {
        background: #444;
        color: #eee;
    }

    .class2 {
        color: red;
    }

    .active {
        width: 100px;
        height: 100px;
        background: green;
    }

    .text-danger {
        background: red;
    }
</style>

<body>
    <div id="app">
        <h1>{{msg}}</h1>
        <h1>{{count + 1}}</h1>
        <!-- 调用方法 -->
        <h1>{{details()}}</h1>
        <div>
            <label for="r1">修改颜色</label>
            <!-- v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。 -->
            <!-- v-model 指令在表单控件元素上创建双向数据绑定。 -->
            <input type="checkbox" v-model="use" id="r1">
            <br><br>
            <!-- v-bind 动态指定class -->
            <div v-html="message" v-bind:class="{'class1':use}"></div>
            <div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
            <!-- 绑定计算属性 -->
            <div v-bind:class="classObject"></div>
        </div>
        <p>输入框 input 元素:</p>
        <input v-model="message3" placeholder="编辑我……">
        <p>消息是: {{ message3 }}</p>

        <p>textarea 元素:</p>
        <textarea v-model="message2" placeholder="多行文本输入……"></textarea>
        <p style="white-space: pre">{{ message2 }}</p>

        <!-- 数据计算 -->
        <h1>{{message.split('').reverse().join('')}}</h1>
        <h1>{{use ?"hello shadow":"hello tomorrow"}}</h1>
        <h1 v-if="use">你能不能看到我啊</h1>
        <!-- v-bind -->
        <pre><a v-bind:href="url">动态绑定URL</a></pre>
        <!-- v-on -->
        <button v-on:click="addCount">动态加数</button>
        <button @click='say("hi")'>Say hi</button>
        <!-- 筛选 -->
        <h1>{{filtersData |capitalize }}</h1>
        <!-- 计算 -->
        <h1>{{msg1}}</h1>
        <!-- v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。-->
        <div v-for="item in list1">
            <span :class="{'class2':item > 2 && item < 5}">{{item}}</span>
        </div>
        <!-- v-for 可以通过一个对象的属性来迭代数据: -->
        <div class="class2" v-for="value in object">{{value}}</div>

        <!-- v-for 可以通过一个对象的属性来迭代数据: -->
        <div class="class1" v-for="(value,key) in object">{{key}}:{{value}}</div>
        <!-- v-for 遍历对象 -->
        <span v-for='item in list2'>
            {{item.name}}
        </span>
        <!-- v-for 迭代整数 -->
        <div>
            <ul>
                <li v-for='n in 10'>
                    {{n}}
                </li>
            </ul>
        </div>
        <!-- v-if -->
        <div>
            <h4 v-if="count > 10">判断1 count > 10 : {{count}}</h4>
            <h4 v-else-if="count == 5">判断2 count == 5 {{count}}</h4>
            <h4 v-else>判断3 {{count}}</h4>
            <h4 v-show='count == 5'>hello v-show</h4>
        </div>
        <!-- 自定义组件 -->
        <!-- 也可以用 v-bind 动态绑定 props 的值到父组件的数据中。
            每当父组件的数据变化时,该变化也会传导给子组件 -->
        <!-- prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。 -->
        <shadow-text v-bind:message="msg"></shadow-text>
        <shadow-text message="传递参数"></shadow-text>
        <runoob></runoob>
        <!-- 传递数组数据 -->
        <ol>
            <todo-item v-for="item in sites" v-bind:todo="item"></todo-item>
        </ol>

        <!-- 自定义组件 自定义事件 -->
        <p>{{ total }}</p>
        <button-counter v-on:increment="incrementTotal"></button-counter>
        <button-counter v-on:increment="incrementTotal"></button-counter>

        <!-- 自定义指令 -->
        <p>页面载入时,input 元素自动获取焦点:</p>
        <input v-focus>

    </div>
    <script>
        //除了数据属性,Vue 实例还提供了一些有用的实例属性与方法。
        //它们都有前缀 $,以便与用户定义的属性区分开来。
        var data = {
            msg: 'hello shadow,hello vue!',
            count: 15,
            message: '<h2>明天你好</h2>',
            use: false,
            url: "http://www.baidu.com",
            filtersData: "hello",
            list1: [1, 2, 3, 4, 5],
            list2: [{ name: 'shadow', age: 18 }, { name: 'tom', age: 88 }],
            object: {
                name: 'shadow',
                url: 'http://www.baidu.com',
                slogan: '吃好喝好玩好!'
            },
            isActive: true,
            hasError: true,
            error: {
                value: true,
                type: 'fatal'
            },
            message3: '',
            message2: '',
            sites: [
                { text: 'Runoob' },
                { text: 'Google' },
                { text: 'Taobao' }
            ],
            total: 0
        }
        // 所有实例都能用全局组件。 tagName 为组件名,options 为配置选项
        //prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。
        //父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop":
        Vue.component('shadow-text', {
            // 声明 props
            props: ['message'],
            template: "<h1>vue 自定义组件 {{message}}</h1>"
        })

        Vue.component('todo-item', {
            props: ['todo'],
            template: '<li>{{ todo.text }}</li>'
        })

        // 自定义事件
        //父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
        //我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
        //使用 $on(eventName) 监听事件
        //使用 $emit(eventName) 触发事件
        //另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
        //以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。
        Vue.component('button-counter', {
            template: '<button v-on:click="incrementHandler">{{ counter }}</button>',
            data: function () {
                return {
                    counter: 0
                }
            },
            methods: {
                incrementHandler: function () {
                    this.counter += 1
                    this.$emit('increment')
                }
            },
        })

        var Child = {
            template: '<h1> 实例内 局部自定义组件!</h1>'
        }

        // 注册一个全局自定义指令 v-focus
        Vue.directive('focus', {
            // 当绑定元素插入到 DOM 中。
            inserted: function (el) {
                // 聚焦元素
                el.focus()
            }
        })
        var vue = new Vue({
            //绑定
            el: '#app',
            //实例内自定义局部组件
            components: {
                'runoob': Child
            },
            //也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用
            // directives: {
            //     // 注册一个局部的自定义指令 v-focus
            //     focus: {
            //         // 指令的定义
            //         inserted: function (el) {
            //             // 聚焦元素
            //             el.focus()
            //         }
            //     }
            // },
            //数据
            data: data,
            //方法
            methods: {
                details() {
                    return "hello world!!!"
                },
                addCount() {
                    this.count++;
                },
                say(meassage) {
                    alert(meassage)
                },
                incrementTotal: function () {
                    this.total += 1
                }
            },
            //筛选
            filters: {
                //取第一个字符,转换大写
                capitalize(value) {
                    if (!value) return ''
                    value = value.toString()
                    return value.charAt(0).toUpperCase() + value.slice(1)
                }
            },
            //监听,只能监听一个数据变量的变化 通过 watch 来响应数据的变化。
            watch: {
                //监听变量msg的变化
                msg(newVlue, oldValue) {
                    console.log("old:" + oldValue + "---new:" + newVlue)
                }
            },
            //计算,可以动态监听构成msg1的所有数据的变化,任意一个变量变化,msg1就会发生变化
            //计算属性在处理一些复杂逻辑时是很有用的
            //可以使用 methods 来替代 computed,效果上两个都是一样的,
            //但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。
            //而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
            //如果你不希望缓存,你可以使用 methods 属性
            computed: {
                msg1() {
                    return this.msg + "---" + this.count
                },
                classObject: function () {
                    return {
                        base: true,
                        active: this.isActive && !this.error.value,
                        'text-danger': false,
                    }
                }

            }
        });
        vue.$watch('count', function (nval, oval) {
            alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
        });
        document.write(vm.$data === data) // true
        document.write("<br>") 
    </script>

</body>

</html>
上一篇下一篇

猜你喜欢

热点阅读