vue.js

介绍

官网

挂载点/模板/实例

vue只会对它所对应的挂载点(el)内的内容产生作用。

挂载点里的内容称为模版(template),模版可以通过template写在vue中,和写在挂载点下面的作用是一样的。

vue实例(new Vue({}))绑定到挂载点后会自动对模版和数据内容进行处理,生成要最终展示的内容。

        <div id="root"></div>
        
        <script>
            /*vue实例*/
            new Vue({
                el:"#root",   //挂载点(dom)
                template: '<h1>hello {{message}}!</h1>',   //模板
                data:{
                    message:"world"
                }
            })
        </script>

vue实例变量.$属性 可以访问vue实例的属性。

数据展示

{{}}插值表达式

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

v-text/v-html指令显示数据

        <div id="root">
            <div v-text="message"></div> <!--v-text以文本形式显示data中指定数据-->
            <div v-html="content"></div> <!--v-html以html形式解析data中指定数据-->
        </div>
        
        <script>
            /*vue实例*/
            new Vue({
                el:"#root",   //挂载点(dom)
                data:{
                    message:"world",
                    content:"<h1>hello world<h1>"
                }
            })
        </script>

事件

v-on:click事件和方法(@)

v-on:click调用vue的methods中声明的方法,v-on:可以简写成@符号

<div id="root">
    <div v-on:click="this.handleClick">{{content}}</div>  <!--v-on:可以写成 @click="this.handleClick"-->
</div>

<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data:{
            content:"hello",
        },
        methods:{
                handleClick: function(){
                    this.content = 'world';
                }
        }
    })
</script>

修饰符

修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault(),这样只会执行绑定的方法,不会执行事件默认的操作。

<form v-on:submit.prevent="onSubmit"></form>

其他事件修饰符

Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。

Vue.js通过由点(.)表示的指令后缀来调用修饰符。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
<!-- 阻止事件传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件时不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联  -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符,阻止submit事件默认操作 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式,带此关键字会优先执行,然后执行子组件在执行父组件 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>

按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">

属性绑定和双向数据绑定

v-bind:属性绑定(:)

v-bind:属性绑定可以简写为:,属性双引号中的值是js表达式可以用js操作符操作。

v-model双向绑定

双向绑定是指vue实例中的data和挂载点中的dom属性绑定,可以实现属性的值改变vue实例中的数据,不仅仅是vue实例的data数据影响dom。

<div id="root">
    <div v-bind:title="title">{{content}}</div>   <!--v-bind:缩写成:,意思是title属性值绑定为vue实例data中的title的值-->
    <input v-model="content" />
</div>

<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data:{
            content:"hello",
            title:"this is hello world"
        }
    })
</script>

computed计算属性watch监听属性

<div id="root">
    姓:<input v-model="firstName" />
    名:<input v-model="lastName" />
    <div>{{fullName}}</div>
    <div>{{count}}</div>
</div>

<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data:{
            firstName:"",
            lastName:"",
            count:0
        },
        computed:{  //计算属性,通过已有的data数据计算出新的属性,依赖变更时会重新计算
            fullName:function(){
                return this.firstName +' '+this.lastName;
          }
        },
        watch:{  //监听器,监听数据的变化,当数据发生变化时执行
          fullName:function(){  //当fullName属性值变化时
                this.count++;
          }
        }
    })
</script>

过滤器

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

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

v-if、v-show标签 

v-if值为ture,将元素插入dom,false删除dom。

v-show值为ture是显示dom,false时不显示,通过css样式,style="display: none;"。(性能高一点,不用每次新建dom)

<div id="root">
    <div v-if="show">hello</div>
    <div v-show="show">world</div>
    <button @click="handleClick">toggle</button>
</div>

<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data:{
            show:true
        },
        methods:{
            handleClick:function(){
                this.show = !this.show;
            }
        }
    })
</script>

多个v-if

<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-for标签

v-for 指令可以用来遍历数组(val,index)、对象(val,key,index)、整数。

遍历每一个数据

<div id="root">
    <ul>
        <!-- 遍历list中的每一项放入item中,index为下标,:key的作用是用来加速渲染一定要唯一 -->
        <li v-for="(item,index) of list" :key="index">{{item}}</li> 
    </ul>
</div>

<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data:{
            list:['a','b','c']
        }
    })
</script>

动态修改数组

<div id="root">
    <div>
        <input v-model="inputVal"/>
        <button @click="handleSubmit">提交</button>  <!-- 通过提交事件的handleSubmit方法操作vue.$list数据,下面会自动显示list数据.(vue是数据驱动型,操作的是数据不是dom) -->
    </div>
    <ul>
        <!-- 仅仅是显示list中的值,当list中的值变化时这里也会跟着变 -->
        <li v-for="(item,index) of list" :key="index">{{item}}</li>
    </ul>
</div>
<script>
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data: {
            inputVal: '',   //input双向绑定的值
            list:[]   //list数组
        },
        methods: {
            handleSubmit: function(){    //按钮绑定的方法
                this.list.push(this.inputVal);
                this.inputVal = ''
            }
        }
    })
</script>

自定义指令

<div id="app">
    <p>页面载入,input 元素自动获取焦点:</p>
    <input v-focus>
</div>

<script>
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>

组件

组件其实也是一个实例,注册一个全局组件语法格式如下:

Vue.component(tagName, options)

简单组件

        <ol id="app">
          <!-- 使用组件,创建一个todo-item组件的实例 -->
          <todo-item></todo-item>
        </ol>
        <!-- 这里的script一定要写在最后写在前面不行 -->
        <script>
            // 定义名为 todo-item 的新组件,tagName为todo-item(html中直接使用)
            Vue.component('todo-item', { 
              template: '<li>这是个待办项</li>'
            });
            
            //声明式渲染不能少
            new Vue({
              el: '#app'
            })
        </script>

父组件传值子组件

v-for遍历多次调用全局组件,动态添加数据。

父组件(vue实例)向子组件传值,通过属性绑定的方式传值,子组件通过props接收属性的值。

父组件 -> 将值绑定(v-bind:)在子组件的挂载点上 -> 子组件通过props获取挂载点上的属性值。

<div id="root">
    <div>
        <input v-model="inputVal"/>
        <button @click="handleSubmit">提交</button>  <!-- 通过提交事件的handleSubmit方法操作vue.$list数据,下面会自动显示list数据.(vue是数据驱动型,操作的是数据不是dom) -->
    </div>
    <ul>
        <!-- vue实例中的值每次改变dom也会跟着变动,这里把item作为参数传给组件了-->
        <todo-item
            v-for="(item,index) of list" :key="index" :param="item">
        <todo-item/>
    </ul>
</div>
<script>
    /*全局组件,相当于一个li标签,中间的内容由父级实例传入,props接收父级实例传过来的数据*/
    Vue.component('todo-item',{
        props: ['param'],   
        template:'<li @click="handleClick">{{param}}</li>',
        methods: {
            handleClick: function(){
                alert('cl');    
            }
        }
    });
    
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data: {
            inputVal: '',   //input双向绑定的值
            list:[]   //list数组
        },
        methods: {
            handleSubmit: function(){    //按钮绑定的方法
                this.list.push(this.inputVal);
                this.inputVal = ''
            }
        }
    })
</script>

子组件向父组件传值

要通过发布订阅的方式实现。

子组件通过this.$emit(事件,参数)方法触发事件 -> 父组件在子组件上通过v-on:方式监听事件 -> 父组件找到事件绑定的方法(带参数)并执行.

<div id="root">
    <div>
        <input v-model="inputVal"/>
        <button @click="handleSubmit">提交</button>  <!-- 通过提交事件的handleSubmit方法操作vue.$list数据,下面会自动显示list数据.(vue是数据驱动型,操作的是数据不是dom) -->
    </div>
    <ul>
        <!-- vue实例中的值每次改变dom也会跟着变动,这里把item作为参数传给组件了;监听组件的delete事件,如果被触发执行vue实例的handleDelete-->
        <todo-item
            v-for="(item,index) of list" :key="index" :param="item" :index="index" @delete="handleDelete">
        <todo-item/>
    </ul>
</div>
<script>
    /*全局组件,相当于一个li标签,中间的内容由参数(遍历的item)传入并展示*/
    Vue.component('todo-item',{
        props: ['param','index'],   
        template:'<li @click="handleClick">{{param}},下标{{index}}</li>',
        methods: {
            handleClick: function(vlue){
                this.$emit('delete',this.index);  //方法触发delete事件并传值
            }
        }
    });
    
    /*vue实例*/
    new Vue({
        el:"#root",   //挂载点(dom)
        data: {
            inputVal: '',   //input双向绑定的值
            list:[]   //list数组
        },
        methods: {
            handleSubmit: function(){    //按钮绑定的方法
                this.list.push(this.inputVal);
                this.inputVal = ''
            },
          handleDelete: function(index){
                  this.list.splice(index,1);
          }
        }
    })
</script>

1、父组件可以使用 props 把数据传给子组件。
2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件
vm.$on( event, fn );//监听event事件后运行fn;

官方示例

<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script>
            window.onload=function (){
                //声明式渲染
                app = new Vue({
                  el: '#app',
                  data: {
                    message: 'Hello Vue!'
                  }
                })
                
                //v-bind:title给标签动态绑定提示
                app2 = new Vue({
                  el: '#app-2',
                  data: {
                    message: '页面加载于 ' + new Date().toLocaleString()
                  }
                })
                
                //v-if条件
                app3 = new Vue({
                  el: '#app-3',
                  data: {
                    seen: true
                  }
                })
                
                //v-for循环
                app4 = new Vue({
                  el: '#app-4',
                  data: {
                    todos: [
                      { text: '学习 JavaScript' },
                      { text: '学习 Vue' },
                      { text: '整个牛项目' }
                    ]
                  }
                })
                
                //v-on:click点击事件
                app5 = new Vue({
                  el: '#app-5',
                  data: {
                    message: 'Hello Vue.js!'
                  },
                  methods: {
                    reverseMessage: function () {
                      this.message = this.message.split('').reverse().join('')
                    }
                  }
                })
                
                //v-model双向绑定
                app6 = new Vue({
                  el: '#app-6',
                  data: {
                    message: 'Hello Vue!'
                  }
                })
                
            }
        </script>
    </head>
    
    <body>
        <!--显示文本-->
        <div id="app">{{ message }}</div>
        
        <!--显示悬浮框-->
        <div id="app-2">
          <span v-bind:title="message">
            鼠标悬停几秒钟查看此处动态绑定的提示信息!
          </span>
        </div>
        
        <!--条件-->
        <div id="app-3">
          <p v-if="seen">现在你看到我了</p>
        </div>
        
        <!--循环-->
        <div id="app-4">
          <ol>
            <li v-for="todo in todos">
              {{ todo.text }}
            </li>
          </ol>
        </div>
        
        <!--点击事件-->
        <div id="app-5">
          <p>{{ message }}</p>
          <button v-on:click="reverseMessage">逆转消息</button>
        </div>
        
        <!--表单输入和文本状态之间的双向绑定-->
        <div id="app-6">
          <p>{{ message }}</p>
          <input v-model="message">
        </div>
        
    </body>
</html>

vue-cli

npm安装及配置

https://www.cnblogs.com/aeolian/p/12457284.html

安装

官网

#安装vue-cli
npm install --global vue-cli
#或者
npm install -g @vue/cli

构建项目

#cli方式(vue-cli3才有的命令),vuecli集成webpack
vue create hello-world
#基于webpack
vue init webpack hello-world

运行

cd hello-world
npm run dev

结构

index.html为首页,main.js为index中挂载点的实例,main.js中导入组件并使用组件。

main.js

import Vue from 'vue'
import TodoList from './TodoList'

/* index.html中挂载点的实例 */
new Vue({
  el: '#app', /* index.html中的根结点 */
  components: { App: TodoList }, /* 以APP标签使用引入的TodoList组件 */
  template: '<App/>'
})

TodoList.vue

<!--父组件-->
<template>
  <div id="app">
    <div>
      <input v-model="inputVal"/>
      <button @click="handleSubmit">提交</button>  <!-- 通过提交事件的handleSubmit方法操作vue.$list数据,下面会自动显示list数据.(vue是数据驱动型,操作的是数据不是dom) -->
      <ul>
        <!--使用子组件,通过:绑定属性传值给子组件,通过@监听事件接收子组件传值-->
        <todo-item v-for="(item,index) of list"
                   :content="item"
                   :index="index"
                   :key="index"
                   @delete="handleDelete">
        </todo-item>
      </ul>
    </div>
  </div>
</template>

<script>
/* 引入子组件TodoItem组件 */
import TodoItem from './components/TodoItem'

export default {
  components: { 'todo-item': TodoItem }, /* 引用导入的组件,声明通过todo-item标签的方式使用TodoItem */
  name: 'App',
  data: function () {
    return {
      inputVal: '',
      list: []
    }
  },
  methods: {
    handleSubmit () {
      this.list.push(this.inputVal)
      this.inputVal = ''
    },
    handleDelete (index) { /* 监听子组件触发的事件方法,并接收参数 */
      this.list.splice(index, 1) /* 从index位置删除1个数据 */
    }
  }
}
</script>

<!--不加scope会变成全局-->
<style scoped>
#app {
  color: #2c3e50;
}
</style>

TodoItem.vue

<!--子组件-->
<template>
  <!--监听li标签的单击事件,执行handleDelete方法-->
  <li @click="handleDelete">{{content}}</li>
</template>

<script>
export default {
  props: ['content', 'index'], /* 通过属性接收父组件的数据 */
  methods: {
    handleDelete () {
      this.$emit('delete', this.index) /* 触发父组件的delete监听事件,并传递参数index */
      // alert(this.index)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>
原文地址:https://www.cnblogs.com/aeolian/p/9227195.html