Vue学习笔记(入门)

Vue 2.0 初级教程

    • cdn 引入Vue.js文件
    • 插值语法
    • 过滤器
    • 计算属性
    • Class 与 Style 绑定
      • Class 绑定
      • Style绑定
    • 条件渲染
    • 表单控件绑定
    • 组件
      • 组件中间的通信
        • Props 父组件传递数据给子组件
        • 自定义事件实现子组件传递数据给父组件
        • 非父子通信
      • slot 标签的使用
      • 动态组件
      • keep-alive
      • 子组件索引

cdn 引入Vue.js文件

引入开发版本,包含命令行的警告
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

插值语法

  1. 文本插值
<span>Message: {
     {
      msg }}</span>

数据只会跟新一次,渲染一次后不会再改变

<!-- 只显示一次,数据刷新不管他的事情 -->
<span v-once>This will never change: {
     {
      msg }}</span>
  1. 纯html插值
<div v-html="rawHtml"></div>
new Vue({
     
    el:"#app",
    data:{
     
    rawHtml:"

你好

"
})

过滤器

我自己的认识就是:过滤器就是当你要引用一个数据时先对其进行一段处理,比如截取字符串等等操作,然后再返回数据渲染页面!

  1. 一般过滤器都是一个函数,在filters中定义
<div id="app">
        <h1>{
     {
     msg | capitalize}}</h1>
        <input type="text" v-model="msg">
    </div>
    <script>
        new Vue({
     
            el: "#app",
            data: {
     
                msg: "",
            },
            filters: {
     
                capitalize(value) {
     
                    if (!value) return ''
                    value = value.toString()
                    return value.charAt(0).toUpperCase() + value.slice(1)
                }
            }
        })
    </script>

代码意思就是:msg绑定过滤器capitalize这个函数,当这个msg有值传入时调用过滤器,对msg处理,代码中是对其进行首字母大写处理。

  1. 多个过滤器
<h1>{
     {
      msg | f1 | f2 }}</h1>

// 过滤器
filters: {
     
         f1() {
     
              return 10;
          },
          f2(value) {
     
               console.log("数据: " + value)
            }
     }
console: 
数据: 10
  1. 一个过滤器多个参数
{
     {
      message | filterA('arg1', arg2) }}
  1.  这里,字符串 'arg1' 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。
<h1>{
     {
      msg | capitalize('我是第一个参数', "我是第二个参数") }}
 filters: {
     
                capitalize(value, value1, value2) {
     
                    if (!value) return ''
                    value = value.toString()
                    console.log({
     
                        value1,
                        value2
                    })
                    return value.charAt(0).toUpperCase() + value.slice(1)
                }
            }
</h1>
console:
{
     value1: "我是第一个参数", value2: "我是第二个参数"}

计算属性

自我感觉就是简化了操作,原本是在模板中对数据进行处理,现在直接可以简化出来,在computed中定义函数进行处理。

  1. 原本的形式
<div id="example">
  {
     {
      message.split('').reverse().join('') }}
</div>
  1. computed简化
<div id="example">
  {
     {
      message.split('').reverse().join('') }}
</div>
var vm = new Vue({
     
  el: '#example',
  data: {
     
    message: 'Hello'
  },
  computed: {
     
    // a computed getter
    reversedMessage: function () {
     
      // `this` points to the vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

Class 与 Style 绑定

介绍基本的对象绑定和数组绑定两种方式

Class 绑定

  1. 对象形式
// 此例子中isActive 为 true 时 class绑定 active
<div v-bind:class="{ active: isActive }"></div>
data:{
     
	isActive:true,
}
// 这个例子中 div 盒子绑定 active 这个类
<div v-bind:class="classObject"></div>
data: {
     
  classObject: {
     
    active: true,
    'text-danger': false
  }
}

进阶的使用,结合计算属性

<div v-bind:class="classObject"></div>
data: {
     
  isActive: true,
  error: null
},
computed: {
     
  classObject: function () {
     
    return {
     
      active: this.isActive && !this.error, // true
      'text-danger': this.error && this.error.type === 'fatal',
    }
  }
}
// 结果是绑定 active 这个类。
  1. 数组形式的绑定.

我认为对象形式的绑定是绑定了这个对象,数组形式的绑定是绑定了数组的这一个数值。

<div v-bind:class="[activeClass, errorClass]">
data: {
     
  activeClass: 'active',
  errorClass: 'text-danger'
}

结果:

div class="active text-danger"></div>

常用的形式,三元表达式

// 此案例中是否绑定active这个类取决于isActive这个数值
<div v-bind:class="[isActive ? activeClass : '', errorClass]">

Style绑定

这里只介绍一种

<div v-bind:style="styleObject"></div>
data: {
     
  styleObject: {
     
    color: 'red',
    fontSize: '13px'
  }
}

条件渲染

条件渲染有 v-if , v-else, v-else-if, v-show

v-if 与v-show 的区别:

  1. 这两个条件语句都是控制语句的显示与隐藏,但是v-if是控制元素的dom树来达到目的,如果v-if=true,表示在dom树上插入元素,否则删除元素节点。比如
<p v-if="true"></p>
  1. v-show 则是控制css属性display:none | block 来达到控制元素的显示与隐藏效果。

表单控件绑定

用 v-model 指令在表单控件元素上创建双向数据绑定
自我认识就是v-model绑定就是把输入款input的value的值绑定了,value值为多少,v-model的值就是多少。

<input
  type="checkbox"
  v-model="toggle"
  v-bind:true-value="a"
  v-bind:false-value="b"
>
// 选中时 值为a, 没有选中时值为b.

组件

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码.

Vue.component('my-component', {
     
  // 选项
})

对于自定义标签名,Vue.js 不强制要求遵循 W3C规则 (小写,并且包含一个短杠),尽管遵循这个规则比较好。

  1. 完整的实例(全局注册)
<div id="example">
  <my-component></my-component>
</div>

// javascript 代码
// 注册
Vue.component('my-component', {
     
  template: '
A custom component!
'
, data(){ return value; // 组件开发中data必须是函数 } }) // 创建根实例 new Vue({ el: '#example' })

渲染结果

<div id="example">
  <div>A custom component!</div>
</div>
  1. 局部注册
 <!-- 局部注册 -->
    <div id="app">
        <my-components></my-components>
    </div>
    <script>
        var child = Vue.extend({
     
            template: '

局部注册的组件

'
}) new Vue({ el: "#app", data: { }, components: { "my-components": child } }) </script>

组件中间的通信

通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。

在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。

Vue学习笔记(入门)_第1张图片

组件实例的作用域是孤立的。

Props 父组件传递数据给子组件

prop 是父组件用来传递数据的一个自定义属性
注意问题一定要先注册,然后再实例化,否则会出现

Unknown custom element: <child> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
// 未知的自定义元素:-您是否正确注册了组件?对于递归组件,请确保提供“名称”选项。

Props 是单向数据流,也就是说Props绑定的数据是单向绑定的,父元素的数据改变会带动子元素的数据同时发生改变,但是子元素的数据改变不会传导给父元素

目的是防止子元素无意篡改了父组件的状态

下面给几个栗子展示props的传值

    <div id="app">
        <input type="text" v-model="msg">
        <!-- 下面这个msg不是Js环境,msg是模板中的插值 -->
        <child msg="dajiahao1"></child>
    </div>
    <script>
        //先注册
        Vue.component('child', {
     
            // 声明 props
            props: ["msg"],
            template: '{
     {msg}}'
        });
        // 再实例化
        new Vue({
     
            el: "#app",
            data: {
     
                msg: "父组件的值",
            },
        })
    </script>
  1. 运用结果:
    在这里插入图片描述
 <div id="app">
        <input type="text" v-model="msg">
        <!-- js环境下mymsg是下面的插值,传入的是父盒子的data中变量msg -->
        <child :mymsg="msg"></child>
    </div>
    <script>
        //先注册
        Vue.component('child', {
     
            // 声明 props
            props: ["mymsg"],
            template: '{
     {mymsg}}'
        });
        // 再实例化
        new Vue({
     
            el: "#app",
            data: {
     
                msg: "父组件的值",
            },
        })
    </script>
  1. 运行结果
    在这里插入图片描述

自定义事件实现子组件传递数据给父组件

 <div id="counter-event-example">
        <p>{
     {
      total }}</p>
        <!-- 父组件通过v-on 订阅消息,这里监听子组件方法,increment方法每执行一次,父组件中方法incrementTotal就执行一次 -->
        <button-counter v-on:increment="incrementTotal"></button-counter>
        <button-counter v-on:increment="incrementTotal"></button-counter>
    </div>
    <script>
        Vue.component('button-counter', {
     
            // 子组件绑定increment方法
            template: '',
            data: function() {
     
                return {
     
                    counter: 0
                }
            },
            methods: {
     
                increment: function() {
     
                    this.counter += 1
                    // 在子组件中用$emit发布消息
                    this.$emit('increment')
                }
            },
        })
        new Vue({
     
            el: '#counter-event-example',
            data: {
     
                total: 0
            },
            methods: {
     
                incrementTotal: function() {
     
                    this.total += 1
                }
            }
        })
    </script>

源码解析
1. 首先是在子组件中绑定了 increment 方法给子组件。
2. 在父组件中通过 v-on 订阅了消息事件 increment ( 也可以说是监听了子组件的 increment 方法 ) v-on:increment="incrementTotal ", 子组件的 increment 方法每执行一次,父组件的 incrementTotal 方法就执行一次 .
3. 在子组件的方法中发布消息 this.$emit('increment'), 发布的消息就是之前你订阅的消息,名称要一致!

非父子通信

<div id="app_first">
    <button @click="add">add</button>
</div>
<div id="app_second">{
     {
     msg}}</div>
<body>
    <script>
        // 创建一个空的Vue实例
        const bus = new Vue();
        const first = new Vue({
     
            el: "#app_first",
            data: {
     
                text: "我是first实例的值"
            },
            methods: {
     
                add() {
     
                    bus.$emit('id-selected', {
     
                        msg: this.text,
                        err: 0
                    })
                }
            },
            created() {
     

            }
        });
        const second = new Vue({
     
            el: "#app_second",
            data: {
     
                msg: ""
            },
            created() {
     
                bus.$on('id-selected', function(obj) {
     
                    // ...
                    console.log("输出函数内置的对象arguments:", arguments)
                    console.log("输出传过来的值", obj)
                    console.log(obj)
                        // console.log(this)  此时的this指向空的bus实例对象
                    second.msg = obj.msg
                    return obj;
                })
            }
        })
    </script>
    // 就是先定义一个空的全局vue实例
    const bus = new Vue()
   //  在一个组件中发布消息
   bus.$emit("xiaoxi-mingcheng",{
     
       msg:"你要传送的数据"
      })
    // 在另一个组件中订阅消息
    bus.$on("xiaoxo-mingcheng",function(obj){
     
		// 这里书写你要进行的操作,obj就是传送过来的数据对象
		}
    )

slot 标签的使用

在我的理解就是留空位,插值进去

分为三种情况

  1. name 属性的 slot
  <div id="father">
        <h1>我是父亲</h1>
        <children>
            <h3>我是插入的元素</h3>
        </children>
    </div>
    <script>
        // 我这里就用局部注册组件
        var children = Vue.extend({
     
            template: `

我是儿子上面

我是儿子下面

`
}) new Vue({ el: "#father", components: { children } }) </script>

运行结果

Vue学习笔记(入门)_第2张图片
2. 具名 slot

    <!-- 局部注册 -->
    <div id="app">
        <my-components>
            <h1 slot="header">
                我是头部
            </h1>
            <h2 slot="footer">
                我是底部
            </h2>
        </my-components>
    </div>
    <script>
        var myComponents = {
     
            template: `
            
我是主体内容
`
} new Vue({ el: "#app", data: { }, components: { "my-components": myComponents, } }) </script>

运行结果

Vue学习笔记(入门)_第3张图片

第三种情况

就是如果含有name属性的slot与不含与name属性的slot交叉在一起,那么有name属性的会渲染到相映的slot上,其余的如果没有设置name的slot会渲染所以的插入节点,(最后剩下插入的节点要保证是没有设置slot属性的)

一个 slot 对应一个 name

动态组件

简单的说就是在 JS 的环境下 控制组件间的切换,在后面可以通过路由实现组件间的切换,这里是通过 is 属性来控制

   // 这样组件切换前提是你要注册多个组件在在同一个挂载点
   <component v-bind:is="currentView">
	<!-- 组件在 vm.currentview 变化时改变! -->
   </component>
var vm = new Vue({
     
  el: '#example',
  data: {
     
    currentView: 'home'
  },
  components: {
     
    home: {
      /* ... */ },
    posts: {
      /* ... */ },
    archive: {
      /* ... */ }
  }
})

keep-alive

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:

<keep-alive>
  <component :is="currentView">
    <!-- 非活动组件将被缓存! -->
  </component>
</keep-alive>

子组件索引

使用 ref 为子组件指定一个索引 ID

   <div id="parent">
       <user-profile ref="profile"></user-profile>
   </div>
   var parent = new Vue({
      el: '#parent' })
   // 访问子组件
   var child = parent.$refs.profile

$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 $refs 。

注:此教程是个人对 Vue 官方文档的学习笔记,欢迎大家一起交流讨论学习,如发现有错误请在评论区发言讨论!

你可能感兴趣的:(Vue学习,vue,前端,npm)