V u e

Vue

1、介绍

仅学皮毛,能看懂即可

实现前后端分离

Hello World

进入网页 https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js ,Ctrl+S 下载 vue.js

创建一个 static web 工程

    <script src="../../vue/vue.js"></script>
</head>
<body>

<!--html页面模板-->
<div id="app">
    <!-- {{}} vue的内容取值,填充data中定义的message属性 -->
    {{ message }}
</div>
<script>
    //vue实例,用于渲染模板跟家在数据用
    var app = new Vue({    //这个Vue对象用来控制某一个标签里面的数据
        el: '#app',   //指定 vue 渲染模板位置
        data: {
            message: 'Hello Vue!'   //定义一个数据,在id为app的标签内部去使用
        }
    })
</script>

</body>

上面的代码做了什么事情?

创建Vue对象的时候,传入了一个对象:{}

  1. {}中的 el 属性:该属性决定了这个Vue对象挂载到哪一个元素上这里挂载到了 id为app 的元素上
  2. {}中的 data 属性:该属性中通常会存储一些数据,好像上面例子中的 message 就是直接定义出来的数据

2、常见指令

指令带有前缀 v- ,以表示它们是 vue 提供的特殊 attribute

{{属性}}

{{属性}} 只能在标签之间使用,不可用于标签属性位置使用

里面可以使用表达式

<div id="test">
    <ul>
        <li v-for="item in arr">
            {{item == 1?"可以":"不可以"}}
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            arr:[1,2,1,1,2,2]
        }
    });
</script>

<!--html页面模板-->
<div id="app">
    <!-- {{}} vue的内容取值,填充data中定义的message属性 -->
    {{ message }}
</div>
<script>
    //vue实例,用于渲染模板跟家在数据用
    var app = new Vue({    //这个Vue对象用来控制某一个标签里面的数据
        el: '#app',   //指定 vue 渲染模板位置
        data: {
            message: 'Hello Vue!'   //定义一个数据,在id为app的标签内部去使用
        }
    })
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yy92PUWu-1649927485060)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220301135200142.png)]

可在浏览器动态更改信息

显示数据(v-bind)

v-bind 表示通知vue在渲染标签时,将 bind 绑定的属性和 vue 实例 data 中同名属性值保持一致

v-bind: 属性绑定指令,用于标签属性位置
绑定图片: v-bind:src 或者 :src
绑定样式: v-bind:class 或者 :class
绑定链接: v-bind:href 或者 :href

    <script src="../../vue/vue.js"></script>
</head>
<body>
<!-- {{}} 只能在标签开始与结束之间位置是一个-->
<!-- 
	v-bind: 属性绑定指令,用于标签属性位置
	绑定图片: v-bind:src    或者   :src
	绑定样式: v-bind:class  或者   :class
	绑定链接: v-bind:href   或者   :href
-->
<div id="app">
    <span v-bind:title="title">{{msg}}</span>
    <br/>
    <!--简写方式-->
    <span :title="title">{{msg}}</span>
</div>
<script>
    var d = new Vue({
        el:"#app",
        data:{
            msg:"动态信息",
            title:"哈哈"
        }
    });
</script>
</body>

数据双向绑定数据(v-model)

与 v-bind 类似,不过数据可以同步改动

v-model 可以动态修改 vue 示例 data 数据

<div id="app">
    <!-- v-bind 单向属性绑定指令,属性数据改动不会影响vue实例data数据-->
    用户名:<input type="text" v-bind:value="defaultValue">
    <br/>
    <!-- v-model 双向属性绑定指令,属性数据改动会影响vue实例data数据
        出现defaultValue的位置全部都改
        一般用于表单标签操作使用
    -->
    用户名:<input type="text" v-model:value="defaultValue">
    <br/>
    {{defaultValue}}
</div>
<script>
    var d = new Vue({
        el:"#app",
        data:{
            defaultValue:"动态信息",
        }
    });
</script>

显示数据(v-html)

<!-- v-html 将数据解析成html格式并输出-->
<div id="app" v-html="msg">
    <!-- {{}} 会将数据原样输出-->
    <!-- 输出:<span style='color: red;'>字符串</span> -->
    {{msg}}
    此标签会被覆盖,这里内容不会显示
</div>
<script>
    var d = new Vue({
        el:"#app",
        data:{
            msg:"<span style='color: red;'>字符串</span>",
        }
    });
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q71TLfR8-1649927485062)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220301150809823.png)]

判断(v-if)

		<script src="../../vue/vue.js"></script>
</head>
<body>
    
<!-- v-html 将数据解析成html格式并输出-->
<!-- 需求:data中有age属性,根据age属性显示不同内容
    age > 18 :欢迎光临
    age < 18 :禁止
    age == 18 :考虑一下
-->
<div id="app">
    <span v-if="age>18">欢迎光临</span>
    <span v-else-if="age<18">禁止</span>
    <span v-else>考虑一下</span>
</div>
    
<script>
    var d = new Vue({
        el:"#app",
        data:{
            age:0,   //这里需要设置值,相当于默认值赋值,否则空指针
        }
    });
</script>
    
</body>

循环指令(v-for)

		<script src="../../vue/vue.js"></script>

<div id="app">
    <ul>
        <!--类似于for(String i:arrs),item是自定义变量名-->
        <li v-for="item in arrs">{{item}}</li>
    </ul>
    <ul>
        <!-- 加上索引值:(左边是元素,右边是索引) -->
        <li v-for="(item,index) in arrs">{{item}}====>{{index}}</li>
    </ul>
    <ul>
        <!-- 遍历对象集合 -->
        <li v-for="(u,index) in user">
            {{u.id}}、 {{u.name}}、 {{u.age}}====>{{index}}
        </li>
    </ul>
</div>

<script>
    var d = new Vue({
        el:"#app",
        data:{
            arrs:[18,12,88,"a"],
            user:[
                {id:1, name:"xcm1", age:111},
                {id:2, name:"xcm2", age:222},
                {id:3, name:"xcm3", age:333},
                {id:4, name:"xcm4", age:444},
            ]
        }
    });
</script>

绑定事件(v-on)

可缩写成 @

比如: v-on:click 绑定单击事件,缩写成 @click

		<script src="../../vue/vue.js"></script>
		<script src="../../vue/jquery-1.7.2.js"></script>

<div id="app">
    <!-- 原生html -->
    <button onclick="clickMe()">点我</button>
    <!-- 当使用 vue 方式处理事件时,必须将事件函数定义在 vue 实例中-->
    <button v-on:click="clickMe()">vue点我</button>
</div>

<script>
    //事件函数
    function clickMe() {
        alert("被点了")
    }
    var d = new Vue({
        el:"#app",
        data:{
            arrs:[18,12,88,"a"],
        },
        methods:{   //vue定义方法的位置,业务处理方法定义
            clickMe:function () {
                alert("vue被点了")
            }
        }
    });
</script>

3、Vue 事件

事件函数

v-on 可缩写成 @

比如: v-on:click 绑定单击事件,缩写成 @click

事件对象

事件对象:系统封装整个事件信息的一个对象

在事件函数的方法内使用 $even

		<script src="../../vue/vue.js"></script>
		<script src="../../vue/jquery-1.7.2.js"></script>

<div id="app">
    <!-- $event:vue封装的事件对象
            当事件触发时系统自动创建此对象并赋值给全局变量 $even,变量名是固定的
    -->
    <button v-on:click="clickMe($event)">vue点我</button>
</div>

<script>
    var d = new Vue({
        el:"#app",
        data:{
            arrs:[18,12,88,"a"]
        },
        methods:{   //vue定义方法的位置,业务处理方法定义
            clickMe:function (e) {
                console.log(e);   //快捷键 e.log
                alert("vue被点了")
            }
        }
    });
</script>

获取事件源

事件源:触发事件的标签

在vue实例中使用 e.currentTarget

<div id="app">
    <!-- $event:vue封装的事件对象
            当事件触发时系统自动创建此对象并赋值给全局变量 $even,变量名是固定的
    -->
    <button v-on:click="clickMe($event)">vue点我</button>
</div>

<script>
    var d = new Vue({
        el:"#app",
        data:{
            arrs:[18,12,88,"a"]
        },
        methods:{   //vue定义方法的位置,业务处理方法定义
            clickMe:function (e) {
                console.log(e);   //快捷键 e.log
                
                //以前获取事件源:console.log(this);
                //在 vue 事件函数中,this等价于vue的实例变量 d,this==d
                
                //vue中获取事件源
                console.log(e.currentTarget);
                alert("vue被点了")
            }
        }
    });
</script>

事件传参

<div id="app">
    <ul>
        <!-- $event:vue封装的事件对象
            当事件触发时系统自动创建此对象并赋值给全局变量 $even,变量名是固定的

            函数需要获取页面参数时,只需将其作为事件函数的参数传入即可
                    还可以传入对象
        -->
        <li v-for="(u,index) in user" v-on:click="clickMe($event, u.id,u.name, u)">
            {{u.id}}、 {{u.name}}、 {{u.age}}====>{{index}}
        </li>
    </ul>
</div>

<script>
    //事件函数
    function clickMe() {
        alert("被点了")
    }
    var d = new Vue({
        el:"#app",
        data:{
            arrs:[18,12,88,"a"],
            user:[
                {id:1, name:"xcm1", age:111},
                {id:2, name:"xcm2", age:222},
                {id:3, name:"xcm3", age:333},
                {id:4, name:"xcm4", age:444},
            ]
        },
        methods:{   //vue定义方法的位置,业务处理方法定义
            clickMe:function (e,id,name, u) {
                alert(id +","+ name +"==="+ u.age +","+ u.id )
            }
        }
    });
</script>

4、Vue的属性

el

用来指示 vue 编辑器什么地方开始解析

<div id="test"/>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
        }
    });
</script>

data

vue渲染过程中需要用到的数据

<div id="test"/>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            arr:[1,2,3]
        }
    });
</script>

methods

放置页面中的业务逻辑,js 函数一般都放置在 methods 中

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            arr:[1,2,3]
        },
        methods:{
            fun1:function () {
            }
            fun2:function () {
            }
        }
    });
</script>

filters

vue 过滤器集合

<div id="test">
    <ul>
        <li v-for="item in arr">
            {{item == 1?"可以":"不可以"}}
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            arr:[1,2,1,1,2,2]
        }
    });
</script>

<div id="test">
    <ul>
        <!--  | 是管道操作符,左边数据作为右边函数的参数值-->
        <li v-for="(u, index) in users" >
            {{u.sex | sexFilter}}
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            users:[
                {id:1,name:"aa",sex:"0"},
                {id:2,name:"bb",sex:"1"},
                {id:3,name:"cc",sex:"1"},
                {id:4,name:"dd",sex:"0"}
            ]
        },
        filters:{   //一般用于数据格式化、数据加工
            sexFilter:function (value) {
                return value == 1 ? "男" : "女";
            }
        }
    });
</script>

mounted

需要用Ajax,就需要导入 jQuery 文件

之前 data 里面的数据都是固定的,但是平时使用的数据都是来自于数据库,此时就用到mounted

mounted 是一个函数,在 vue 实例创建完成之后立即调用(html加载完成后立即执行)

一般用于初始化data中的数据

    <script src="../../vue/vue.js"></script>
    <script src="../../vue/jquery-1.7.2.js"></script>


<div id="test">
    <ul>
        <!--  | 是管道操作符,左边数据作为右边函数的参数值-->
        <li v-for="(u, index) in datauu" >
            {{u.sex | sexFilter}}
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            datauu:[]
        },
        filters:{   //一般用于数据格式化、数据加工
            sexFilter:function (value) {
                return value == 1 ? "男" : "女";
            }
        },
        mounted:function () {
            //mounted是一个函数,html加载完毕、vue准备渲染数据时调用
            //一般用于初始化data中的数据
            //异步请求拿数据
            $.get("/vuetest/views/users.json",{},function (dd) {
                vv.datauu = dd;
            })
        }
    });
</script>

拓展

created

computed

template

render

watch

5、Vue生命周期

Vue 实例生命周期

综合案例

mongdb项目

依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

实体类

@AllArgsConstructor
@NoArgsConstructor
@Data
@Document("users") //设置文档所在的集合
public class User {
    //文档的id建议使用 String 类型,一般使用ObjectId类型来封装,并且贴上@Id注解
    // 自动映射为 _id 自动封装ObjectId
    @Id
    private String id;
    private String name;
    private Integer age;
    //数组推荐使用 ArrayList
    private List<String> hobby = new ArrayList<>();
}

实现类

package com;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author shkstart
 * @create 2022/3/1-17:16
 */
// spring封装操作模板,MongodbTemplate 类,直接使用即可
@Service
public class UserServiceImpl implements IUserService{
    //直接使用,容器已经创建好了
    @Autowired
    private MongoTemplate template;

    @Override
    public void save(User user) {
        template.save(user);
    }
    @Override
    public void delete(String id) {
        template.remove(id);
    }
    @Override
    public void update(User user) {
        template.save(user);
    }
    @Override
    public User get(String id) {
        return template.findById(id, User.class);
    }
    @Override
    public List<User> list() {
        return template.findAll(User.class);
    }
}

后端控制器

@RestController
public class MyController {
    @Autowired
    private IUserService service;

    //注意:项目开发中,一般不会用标准的 RESTful 风格定义路径
    @GetMapping("/list")
    public Object list(){
        return service.list();
    }
}

正常访问:

请求跨域

两个项目相互发起请求,如果项目对应请求的协议、ip、端口 三者存在一个不一样,称之为跨域请求

项目间相互访问需要考虑安全性,所以服务端定义的准入规定:跨域协议(CROS policy),用于规范访问

默认情况下,所有跨域请求不允许访问

解决:

在启动类里添加如下代码:

//跨域访问
@Bean
public WebMvcConfigurer corsConfigurer(){
    return new WebMvcConfigurer(){
        //重写父类提供的跨域请求处理的接口
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            //添加映射路径
            registry.addMapping("/**")
                    //放行哪些原始域
                    .allowedOriginPatterns("*")
                    //是否发送Cookie信息
                    .allowCredentials(true)
                    //放行哪些原始域(请求方式)
                    .allowedMethods("GET","POST","DELETE","OPTIONS")
                    //放行哪些原始域(头部信息)
                    .allowedHeaders("*")
                    //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                    .exposedHeaders("Header1","Header2");
        }
    };
}

展示所有用户

<div id="test">
    <ul>
        <!--  | 是管道操作符,左边数据作为右边函数的参数值-->
        <li v-for="u in users" >
            {{u.id}}--{{u.name}}--{{u.age}}--{{u.hobby}}
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            users:[]
        },
        mounted:function () {
            //Ajax异步获取用户列表数据
            $.get("http://localhost:8888/list",{},function (dd) {
                vv.users = dd;
            })
        }
    });
</script>

用户添加

后端

定义一 个类,用于接收结果

@NoArgsConstructor
@AllArgsConstructor
@Data
public class JsonResult {
    private boolean success = true;
    private String msg;
}

后端控制器

@RestController
public class MyController {
    @Autowired
    private IUserService service;

    @PostMapping("/update")
    public Object update(User user){
        //id 是String类型,判空使用StringUtils.hasLength()
        if (StringUtils.hasLength(user.getId())){
            service.update(user);
        }else {
            service.save(user);
        }
        return new JsonResult();
    }
}
前端

前端表单提交需要是异步提交

异步提交表单需要使用 jQuery.form.js 静态资源,使用 ajaxForm、ajaxSubmit

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJrWMS9Z-1649927485064)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220301184547188.png)]

原页面

注意 页面跳转 要有 工程路径

<a href="/vuetest/views/_01hello/input.html">添加<a/>

新增页面

注意表单异步提交需要引入 jquery.form.js

注意不可以有id的输入框,输入框会给id赋值""空字符串,会将MongoDB自动生成的id覆盖

	<script src="../../vue/vue.js"></script>
    <script src="../../vue/jquery-1.7.2.js"></script>
    <script src="../../vue/jquery.form.js"></script>

<div id="app">
    <form id="formId">
        注意不可以有id的输入框,输入框会给id赋值""空字符串,会将MongoDB自动生成的id覆盖
        <!-- <input type="hidden" name="id">  --> 
        名称:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        爱好:
        <input type="checkbox" name="hobby" value="c">c
        <input type="checkbox" name="hobby" value="java">java<br/>
        <!-- 添加更新操作,后端返回的都是 JSON 格式
            要想跳转去list页面,必须根据返回的结果来决定
            所以提交操作不能是同步提交,必须是异步提交
        -->
        <input type="button" id="btn" @click="submitF" value="提交">
    </form>
</div>

<script>
    var vv = new Vue({
        el:"#app",
        methods:{
            submitF:function () {
                //表单异步提交
                //ajaxForm     将表单转换为异步表单,不提交
                //ajaxSubmit  将表单转换为异步表单,并提交
                $("#formId").ajaxSubmit({
                    url:"http://localhost:8888/update",
                    type:"POST",
                    success:function (data) {
                        if (data.success){
                            window.location.href="/vuetest/views/_01hello/hello.html";
                        }
                    }
                });
            }
        }
    });
</script>
注意

注意,注意不可以有id的输入框,输入框会给id赋值""空字符串,会将MongoDB自动生成的id覆盖

然后抛出异常:

com.mongodb.MongoWriteException: 
Write operation error on server localhost:27017. 
Write error: 
WriteError{code=11000, message='E11000 duplicate key error collection: mongodemo.users index: _id_ dup key: { _id: "" }', details={}}.

出现原因:

是重写了 MongoDb 生成_id的策略,这种情况在$group中很常见的错误

用户编辑

用户编辑

仅仅通过前端页面之间的跳转,实现跳转时用户信息显示在输入框中

步骤:

  1. 添加编辑链接,直接跳转到编辑页面,不通过后端,跳转时需要带上当前编辑的用户 id

  2. 为了能在编辑的页面上显示用户的信息,页面上需要拿到地址栏中的参数 id

    因为没有经过后端控制器,直接在页面间跳转,需要用到下面获取页面参数的代码

  3. 通过 id 查询并返回用户对象数据

  4. 将用户数据回显在页面上

在展示页面上添加编辑链接 (注意写法)

因为要带上 vue 对象中 mounted 属性获取的数据,需要使用 v-bind:href 绑定链接

<li v-for="u in users" >
    {{u.id}}--{{u.name}}--{{u.age}}--{{u.hobby}}   
    <a v-bind:href="'/vuetest/views/_01hello/input.html?uid=' + u.id">编辑</a>
</li>

跳转页面之后,在 input.html 页面需要获取到地址栏上的 uid

需要添加以下函数

获取页面参数
//获取 url 上的请求参数
function getParam() {
    //获取问号及问号后面的内容
    var url = window.location.search;
    //定义一个空对象变量,接收参数内容
    var params = new Object();
    //判断地址栏上是否有参数
    //indexOf:如果查询到返回索引,反之返回-1
    if (url.indexOf("?") != -1){
        //截取问号后面的内容,再使用 & 分割多个属性
        //substr(1):从第二位开始截取到最后
        //"a|b|c|d|e|f".split('|'):会得到  a,b,c,d,e,f
        //[uid=12312,name=shili]
        var arr = url.substr(1).split("&");
        for (var i = 0;i < arr.length;i ++){
            //使用=分割参数键值对的key、value
            //[uid,12312]
            var keyValue = arr[i].split("=");
            // params[uid] = 12312
            // params.uid = 12312
            params[keyValue[0]] = keyValue[1];
        }
    }
    return params;
}

//打印得到  {uid: '621c8fe6fb279b933fd47625'}
console.log(getParam());

后端控制器

@GetMapping("/get")
public Object get(String uid){
    return service.get(uid);
}

因为需要点击编辑,跳转进 input 页面立即就回显用户数据,所以这个异步提交查询的操作应该是在 mounted 里

同时注意,因为此时添加操作和编辑操作在同一个页面,当编辑操作时才会发起请求,回显用户数据

<script>
    //获取 url 上的请求参数
    function getParam() {
        //获取问号及问号后面的内容
        var url = window.location.search;
        //定义一个空对象变量,接收参数内容
        var params = new Object();
        //判断地址栏上是否有参数
        //indexOf:如果查询到返回索引,反之返回-1
        if (url.indexOf("?") != -1){
            //截取问号后面的内容,再使用 & 分割多个属性
            //substr(1):从第二位开始截取到最后
            //"a|b|c|d|e|f".split('|'):会得到  a,b,c,d,e,f
            //[uid=12312,name=shili]
            var arr = url.substr(1).split("&");
            for (var i = 0;i < arr.length;i ++){
                //使用=分割参数键值对的key、value
                //[uid,12312]
                var keyValue = arr[i].split("=");
                // params[uid] = 12312
                // params.uid = 12312
                params[keyValue[0]] = keyValue[1];
            }
        }
        return params;
    }

    var vv = new Vue({
        el:"#app",
        data:{
            users:{
                hobby:[]
            }
        },
        methods:{
            submitF:function () {
                //表单异步提交
                //ajaxForm     将表单转换为异步表单,不提交
                //ajaxSubmit  将表单转换为异步表单,并提交
                $("#formId").ajaxSubmit({
                    url:"http://localhost:8888/update",
                    type:"POST",
                    success:function (data) {
                        if (data.success){
                           window.location.href="/vuetest/views/_01hello/hello.html";
                        }
                    }
                });
            }
        },
        mounted:function () {
            if (getParam().uid){   //编辑操作才发请求,添加操作时id为null,接口会报错
                //异步请求获取参数,用于初始化
          		$.get("http://localhost:8888/get",
                      {userId:getParam().uid},function(data){
                    vv.users = data;
                })
            }
        }
    });
</script>

需要将数据会显在输入框中

注意,这里必须是 v-model ,而不是 v-bind ,需要实现双向绑定数据

<div id="app">
    <form id="formId">
        名称:<input type="text" name="name" v-model="users.name"><br/>
        年龄:<input type="text" name="age" v-model="users.age"><br/>
        爱好:
        <input type="checkbox" name="hobby" value="c" v-model="users.hobby">c
        <input type="checkbox" name="hobby" value="java" v-model="users.hobby">java
        <br/>
        
        <input type="button" id="btn" @click="submitF" value="提交">
    </form>
</div>
注意

1、在编辑操作中,初始化回显数据时,需要判断是否是编辑操作(即id是否为null),如果是添加操作,id就是null

mounted:function () {
    if (getParam().uid){   //编辑操作才发请求,添加操作时id为null,接口会报错
        //异步请求获取参数,用于初始化
        $.get("http://localhost:8888/get",{userId:getParam().uid},function (data) {
            vv.users = data;
        })
    }
}

2、在编辑操作时,初始化了data属性,如下:

data:{
	users:[]
}

如果是添加操作,那么这里的 users 就不会有数据(id 为 null,不执行初始化回显数据操作)

这样会导致 users 中的 hobby 字段默认赋值为 true ,就导致复选框要么全部被选中,页面全部不选中,无法单个选择

此时就需要在初始化data里面指定 hobby 字段是一个数组类型

data:{
    users:{
        hobby:[]
    }
}

案例完整代码

目录结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFBJIL4Z-1649927485065)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220302132700760.png)]

hello.html

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"
      xmlns:v-html="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../vue/vue.js"></script>
    <script src="../../vue/jquery-1.7.2.js"></script>

</head>
<body>

<a href="/vuetest/views/_01hello/input.html">添加</a>
<div id="test">
    <ul>
        <li v-for="u in users" >
            {{u.id}}--{{u.name}}--{{u.age}}--{{u.hobby}}   <a v-bind:href="'/vuetest/views/_01hello/input.html?uid=' + u.id">编辑</a>
        </li>
    </ul>
</div>

<script>
    var vv = new Vue({
        el:"#test",
        data:{
            users:[]
        },
        mounted:function () {
            //Ajax异步获取用户列表数据
            $.get("http://localhost:8888/list",{},function (dd) {
                vv.users = dd;
            })
        }
    });
</script>

</body>
</html>

input.html

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-model="http://www.w3.org/1999/xhtml"
      xmlns:v-html="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../../vue/vue.js"></script>
    <script src="../../vue/jquery-1.7.2.js"></script>
    <script src="../../vue/jquery.form.js"></script>

</head>
<body>

<div id="app">
    <form id="formId">
        名称:<input type="text" name="name" v-model="users.name"><br/>
        年龄:<input type="text" name="age" v-model="users.age"><br/>
        爱好:
        <input type="checkbox" name="hobby" value="c" v-model="users.hobby">c
        <input type="checkbox" name="hobby" value="java" v-model="users.hobby">java<br/>
        <!-- 添加更新操作,后端返回的都是 JSON 格式
            要想跳转去list页面,必须根据返回的结果来决定
            所以提交操作不能是同步提交,必须是异步提交
        -->
        <input type="button" id="btn" @click="submitF" value="提交">
    </form>
</div>

<script>
    //获取 url 上的请求参数
    function getParam() {
        //获取问号及问号后面的内容
        var url = window.location.search;
        //定义一个空对象变量,接收参数内容
        var params = new Object();
        //判断地址栏上是否有参数
        //indexOf:如果查询到返回索引,反之返回-1
        if (url.indexOf("?") != -1){
            //截取问号后面的内容,再使用 & 分割多个属性
            //substr(1):从第二位开始截取到最后
            //"a|b|c|d|e|f".split('|'):会得到  a,b,c,d,e,f
            //[uid=12312,name=shili]
            var arr = url.substr(1).split("&");
            for (var i = 0;i < arr.length;i ++){
                //使用=分割参数键值对的key、value
                //[uid,12312]
                var keyValue = arr[i].split("=");
                // params[uid] = 12312
                // params.uid = 12312
                params[keyValue[0]] = keyValue[1];
            }
        }
        return params;
    }

    var vv = new Vue({
        el:"#app",
        data:{
            users:{
                hobby:[]
            }
        },
        methods:{
            submitF:function () {
                //表单异步提交
                //ajaxForm     将表单转换为异步表单,不提交
                //ajaxSubmit  将表单转换为异步表单,并提交
                $("#formId").ajaxSubmit({
                    url:"http://localhost:8888/update",
                    type:"POST",
                    success:function (data) {
                        if (data.success){
                           window.location.href="/vuetest/views/_01hello/hello.html";
                        }
                    }
                });
            }
        },
        mounted:function () {
            if (getParam().uid){   //编辑操作才发请求,添加操作时id为null,接口会报错
                //异步请求获取参数,用于初始化
                $.get("http://localhost:8888/get",
                      {userId:getParam().uid},function (data) {
                    vv.users = data;
                })
            }
        }
    });
</script>

</body>
</html>

MyController

package com.controller;

import com.IUserService;
import com.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @Autowired
    private IUserService service;

    //注意:项目开发中,一般不会用标准的 RESTful 风格定义路径
    @GetMapping("/list")
    public Object list(){
        return service.list();
    }

    @PostMapping("/update")
    public Object update(User user){
        //id 是String类型,判空使用StringUtils.hasLength()
        if (StringUtils.hasLength(user.getId())){
            service.update(user);
        }else {
            service.save(user);
        }
        return new JsonResult();
    }

    @GetMapping("/get")
    public Object getuser(String userId){
        return service.get(userId);
    }
}

UserServiceImpl

package com;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

// spring封装操作模板,MongodbTemplate 类,直接使用即可
@Service
public class UserServiceImpl implements IUserService{
    //直接使用,容器已经创建好了
    @Autowired
    private MongoTemplate template;

    @Override
    public void save(User user) {
        template.insert(user);   
        //insert: 若新增数据的主键已经存在,则会报错 DuplicateKeyException
    }
    @Override
    public void delete(String id) {
        template.remove(id);
    }
    @Override
    public void update(User user) {
        template.save(user);   //save: 若新增数据的主键已经存在,则会进行修改
    }
    @Override
    public User get(String id) {
        return template.findById(id, User.class);
    }
    @Override
    public List<User> list() {
        return template.findAll(User.class);
    }
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值