【Vue】Vue入门--双向绑定,Vue的组件,Axios异步通信,计算属性,插值,自定义事件

1.Vue双向绑定

Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会同步变化。这就是Vue.js的精髓之处了。

可以使用v-model指令在表单<input>,<textarea>以及<select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方式来更新元素。

注意:v-model会忽略所有表单元素的value,checked,selected特性的初始值而总是将Vue实例的数据作为数据来源。应该通过js在组件的data选项中生命初始值。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  输入的文本:<input type="text" v-model="message">{{message}}
</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      message: "123"
    },
  });
</script>
</body>
</html>

我们在更新文本框的时候,后面的message也能实现同步的更新,是因为我们实现了双向绑定

单选框

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <input type="radio" name="sex" v-model="checked" value=""><input type="radio" name="sex" v-model="checked" value=""><p>
    选中了:{{checked}}
  </p>
</div>
<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      checked:'女'
    },
  });
</script>

</body>
</html>

下拉框

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <select v-model="selected">
    <option value="" disabled>--请选择--</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>

  <p>
    选中了:{{selected}}
  </p>


</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      selected:''
    },
  });
</script>

</body>
</html>

2.Vue的组件

组件是可复用的Vue实例,就是一组可以重复使用的模板,就跟JSTL的自定义标签,Thymeleaf的th:fragment等框架有着异曲同工之妙。通常一个应用会以一颗嵌套的组件树的形式来组织
在这里插入图片描述

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<div id="app">
<!--  v-for遍历了items中的每一项,取出来了值,然后可以在自定义组件中访问这个值it-->
  <adie v-for="item in items" v-bind:it="item"></adie>
</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>

  Vue.component("adie",{
    //在这里接收了参数it,it和上面的绑定了
    props: ['it'],
    template: '<li>{{it}}</li>'
  });

  var vm=new Vue({
    el: "#app",
    data:{
      items:["java","linux","前端"]
    }
  })

</script>

</body>
</html>

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。为了给博文组件传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样。

当prop被注册后,可以这样把数据作为一个自定义attribute传递进来。

<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>

此外,可能在data中有一个博文的数组

new Vue({
  el: '#blog-post-demo',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

并想要为每篇博文渲染一个组件:

<blog-post
  v-for="post in posts"
  v-bind:title="post.title"
></blog-post>

我们可以使用 v-bind 来动态传递 prop

3.Axios异步通信

3.1.什么是Axios

Axios是一个开源的可以用在浏览器端和Node JS的异步通信框架, 主要作用就是实现AJAX异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests
  • 从node.js创建http请求
  • 支持Promise API[JS中链式编程]
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)

GitHub:https://github.com/axios/axios
中文文档:http://www.axios-js.com/

3.2.为什么要使用Axios

由于Vue.js是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js并不包含AJAX的通信功能, 为了解决通信问题,作者单独开发了一个名为vue-resource的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery, 因为它操作Dom太频繁。

3.3.第一个Axios应用程序

因为接口大部分都是json格式的数据,所以我们模拟一个json格式的数据用来测试 data.json

{
  "name": "a碟",
  "url": "https://blog.csdn.net/ladiez",
  "page": 1,
  "isNonProfit": true,
  "address": {
    "street": "人民东路",
    "city": "湖南",
    "country": "中国"
  },
  "links": [
    {
      "name": "bilibili",
      "url": "https://blog.csdn.net/ladiez"
    },
    {
      "name": "blog",
      "url": "https://blog.csdn.net/ladiez"
    },
    {
      "name": "百度",
      "url": "https://blog.csdn.net/ladiez"
    }
  ]
}

测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--  v-clock解决闪烁问题-->
  <style>
    [v-clock]{
      display: none;
    }
  </style>

</head>
<body>
<div id="app" v-clock>
  <div>{{info.name}}</div>
  <a v-bind:href="info.url">点击</a>
</div>


<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  var vm=new Vue({
    el: "#app",
    //data 属性:vm
    //方法
    data(){
      // 请求的返回参数格式,必须和json字符串一样
      return{
        info:{
            //里面也可以不写
          name:null,
          address:{
            street:null,
            city:null,
            country:null
          },
          utl:null,
        }
      }
    },

    mounted(){ // 钩子函数  链式编程  ES6新特性
      axios.get('../data.json').then(response=>(this.info=response.data))
    }
  })
</script>
</body>
</html>

说明:

  1. 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定
  2. 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象
  3. 我们在data中的数据结构必须和Ajax响应回来的数据格式匹配

4.Vue的生命周期

https://cn.vuejs.org/v2/guide/instance.html#生命周期图示

​ Vue实例有一个完整的生命周期,也就是从开始创建初始化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
  在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。
在这里插入图片描述

5.计算属性

计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存,节约开销。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<div id="app">
  <p>currentTime1 {{currentTime1()}}</p>
  <p>currentTime2 {{currentTime2}}</p>
</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  var vm = new Vue({
    el:"#app",
    data:{
      message:"hello,adie"
    },
    methods:{
      currentTime1:function () {
        return Date.now();//返回一个时间戳
      },
    },
    computed:{//计算属性:methods和computed方法名不能重名,重名之后只会调用methods的方法
      currentTime2:function () {
        this.message   // 数据存在了缓存中,只有当当前数据发生了改变才会再次调用方法
        return Date.now();//返回一个时间戳
      }
    }
  });
</script>

</body>
</html>

可以看到上述案例,同样是返回一个时间戳的currentTime1和currentTime2。在浏览器中我们并没有发现有什么区别。但是如果我们在控制台中输出vm.message='a碟'.见以下案例
在这里插入图片描述

  • methods:定义方法, 调用方法使用currentTime1(), 需要带括号
  • computed:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
  • 只要方法中的值发生了变化,则缓存就会刷新。可以在控制台使用vm.message=”a碟", 改变下数据的值,可以看到上面的效果

结论:
  调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;

6.插槽

插槽的用法很多,详细的了解可以前往官网查看。

Vue.js中我们使用<slot>元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中。

实例

比如准备制作一个待办事项组件(todo) ,该组件由待办标题(todo-title) 和**待办内容(todo-items)**组成,但这三个组件又是相互独立的,该如何操作呢?

1.定义一个待办事项的组件

我们需要让待办事项的标题和值实现动态绑定,所以在代码中留出来了一个插槽,即slot

因为我们有时需要多个插槽,对于这种情况,<slot>有一个特殊的attribute:name。这个attribute可以用来定义额外的插槽。

一个不带 name<slot> 出口会带有隐含的名字“default”。

Vue.component("todo",{
  template: '<div>\
                  <slot name="a"></slot>\
                  <ul>\
                        <slot name="b"></slot>\
                  </ul>\
              </div>'
});

2.定义一个名为todo-title的待办事项标题和todo-items待办事项内容

Vue.component("todo-title",{
  props: ['title'],
  template: '<div>{{title}}</div>'
})

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

3.实例Vue并初始化内容

var vm = new Vue({
  el:"#app",
  data:{
    Title: "a碟",
    todoItems: [
            'Java',
            'Linux',
            'Python'
    ]
  }
});

4.将这些值通过插槽传入

在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称

现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot<template> 中的内容都会被视为默认插槽的内容。

注意 ** v-slot 只能添加在 <template> 上 ** (只有一种例外情况)

我在官网了解到以上template是最新的使用方法。而我学习时使用的方法好像是废弃的。下面是官网提供的最新的使用方法

<div id="app">
  <todo>

    <template v-slot:a>
      <todo-title v-bind:title="Title"></todo-title>
    </template>
    <template v-slot:b>
      <todo-items v-for="i in todoItems" v-bind:item="i"></todo-items>
    </template>

  </todo>
</div>

学习时的方法

<div id="app">
  <todo>
    <todo-title slot="a" v-bind:title="Title"></todo-title>
    <todo-items slot="b" v-for="i in todoItems" v-bind:item="i"></todo-items>
  </todo>
</div>

以上两种方法都是可以使用的

7.自定义事件

通以上代码不难发现,数据项在Vue的实例中,但删除操作要在组件中完成,那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了,Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题;使用this.$emit('自定义事件名',参数), 操作过程如下:

1.在Vue实例中增加了methods对象并定义了removeItems方法用来删除Vue实例中的数据

var vm = new Vue({
  el:"#app",
  data:{
    Title: "a碟",
    todoItems: [
            'Java',
            'Linux',
            'Python'
    ]
  },
  methods:{
    removeItems:function (index) {
      console.log("删除了"+this.todoItems[index]+"OK")
      this.todoItems.splice(index,1)
    }
  }
});

2.修改todo-items待办内容组件的代码,增加一个删除按钮,并且绑定事件

Vue.component("todo-items",{
  props: ['item','ind'],
  template: '<li>{{item}}<button @click="remove123">删除</button></li>',
  methods: {
    remove123:function (ind) {
      //使用自定义事件,自定义事件绑定了Vue实例的方法
      this.$emit('remove',ind)
    }
  }
})

3.修改todo-items待办内容组件的HTML代码,增加一个自定义事件,可以叫remove,和组件的方法绑定,然后绑定到Vue的方法

<template v-slot:b>
  <todo-items v-for="(i,index) in todoItems"
              v-bind:item="i" :ind="index" v-on:remove="removeItems(index)" ></todo-items>
</template>

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>


<div id="app">
  <todo>

    <template v-slot:a>
      <todo-title v-bind:title="Title"></todo-title>
    </template>
    <template v-slot:b>
      <todo-items v-for="(i,index) in todoItems"
                  v-bind:item="i" :ind="index" v-on:remove="removeItems(index)" ></todo-items>
    </template>

  </todo>
</div>

<!--    1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  Vue.component("todo",{
    template: '<div>\
                    <slot name="a"></slot>\
                    <ul>\
                          <slot name="b"></slot>\
                    </ul>\
                </div>'
  });

  Vue.component("todo-title",{
    props: ['title'],
    template: '<div>{{title}}</div>'
  })

  Vue.component("todo-items",{
    props: ['item','ind'],
    template: '<li>{{item}}<button @click="remove123">删除</button></li>',
    methods: {
      remove123:function (ind) {
        //使用自定义事件,自定义事件绑定了Vue实例的方法
        this.$emit('remove',ind)
      }
    }
  })


  var vm = new Vue({
    el:"#app",
    data:{
      Title: "a碟",
      todoItems: [
              'Java',
              'Linux',
              'Python'
      ]
    },
    methods:{
      removeItems:function (index) {
        console.log("删除了"+this.todoItems[index]+"OK")
        this.todoItems.splice(index,1)
      }
    }
  });

</script>
</body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UZSvO96B-1629646576683)(Vue.assets/image-20210819164834669.png)]

8.Vue入门小结

核心:数据驱动,组件化

优点:借鉴了AngularJS的模块化开发和React的虚拟Dom,虚拟Dom就是把Demo操作放到内存中执行;

常用的属性:

  • v-if
  • v-else-if
  • v-else
  • v-for
  • v-on绑定事件,简写@
  • v-model数据双向绑定
  • v-bind给组件绑定参数,简写

组件化:

  • 组合组件slot插槽
  • 组件内部绑定事件需要使用到this.$emit("事件名",参数);
  • 计算属性的特色,缓存计算数据

遵循SoC关注度分离原则,Vue是纯粹的视图框架,并不包含,比如Ajax之类的通信功能,为了解决通信问题,我们需要使用Axios框架做异步通信;

说明

Vue的开发都是要基于NodeJS,实际开发采用Vue-cli脚手架开发,vue-router路由,vuex做状态管理;Vue UI,界面我们一般使用ElementUI(饿了么出品),或者ICE(阿里巴巴出品)来快速搭建前端项目

官网:

  • https://element.eleme.cn/#/zh-CN
  • https://ice.work/
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在JSONEditor中实现数据双向绑定,你需要监听JSONEditor实例的`change`事件,并在事件处理程序中更新你的Vue组件数据。以下是一个示例: ``` <template> <div> <div ref="editor"></div> <pre>{{jsonData}}</pre> </div> </template> <script> import JSONEditor from 'jsoneditor' export default { data() { return { jsonData: { // 初始数据 name: 'John Doe', age: 30, address: { city: 'New York', state: 'NY' } } } }, mounted() { const container = this.$refs.editor const editor = new JSONEditor(container, { // 指定JSONEditor的模式为tree mode: 'tree', // 设置JSONEditor的初始数据 startval: this.jsonData }) // 监听JSONEditor实例的change事件 editor.on('change', () => { // 更新组件jsonData数据 this.jsonData = editor.get() }) } } </script> ``` 在这个示例中,我们使用Vue数据选项中的`jsonData`属性来存储我们的JSON数据。在mounted钩子函数中,我们创建了一个JSONEditor实例,并将其附加到我们之前创建的div元素上。我们指定JSONEditor的模式为`tree`,并将组件的`jsonData`数据作为JSONEditor的初始数据。 我们还监听了JSONEditor实例的`change`事件,并在事件处理程序中使用`editor.get()`方法获取JSONEditor实例的当前数据,并将其更新到组件的`jsonData`数据中。因为`jsonData`数据Vue响应式数据,所以这将自动更新组件中任何使用`jsonData`的地方。 希望这可以帮助你在JSONEditor中实现数据双向绑定
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a碟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值