Vue 自提项目 --小益回收 遇到的问题(二)

@[TOC]小益回收

Vue报错

vue-router.esm.js?8c4f:2089 Uncaught (in promise) NavigationDuplicated {_name: “NavigationDuplicated”, name: “NavigationDuplicated”, message: “Navigating to current location (”/Orderfinish") is not allowed", stack: “Error↵ at new NavigationDuplicated (webpack-int…node_modules/vue/dist/vue.runtime.esm.js:2178:14)”}
大致意思就是不允许使用this.$router.push
解决方法
1. 安装最新的router
npm i [email protected] -S
2.在 main.js里添加一段代码。

代码如下:

import Router from ‘vue-router’
const routerPush = Router.prototype.push
Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(error=> error)
}   

如何使用php给前端返回数据 且保证json格式


header('Content-Type:application/json');  //此声明非常重要
/*链接数据库 */
$pdo = new PDO('mysql:host=localhost;dbname=xiaoyi', 'root', '');

try {
    /*query 执行的是select语句,返回值是PDOStatement对象*/
     $result=$pdo->query("select * from orderList")->fetchAll(PDO::FETCH_ASSOC);

    if(count($result)>0){
        echo json_encode($result);

    }else{
        echo '当前没有订单';
    }
 $db = null; //关闭数据库

} catch (PDOException $e) {
    die("数据库连接失败".$e->getMessage());
}

加上这句代码即可!!一定要记住

php接口返回数据 用echo 还是return?

return 作为函数返回值或结束语句,是返回的数据的指针,也就是数据存放的地址,而接口需要返回的是真实的数据
在tp框架中,return关键字的确是可以给返回数据的,也就是可以作为接口返回数据关键字的,但是用原生的php是不行的,这应该是tp框架内部做过处理了吧!

js判断数组是否为空 以及 是否含有某个值

1.arr.length判断
2. arr.indexOf( ) 找不到返回-1
for循环
arr.find(val=>{ if (val ===2) { console.log(‘有2’)}})
arr.includes 返回结果为布尔类型

最后项目还是选择以thinkphp写接口

vue实现上传头像和预览头像

<template>
  <div>
    <div class="header">
      <router-link tag="i" to="/my" class="iconfont  icon-fanhui1"></router-link>
      <span class="title">个人档案</span>
     <div class="photo" >
      <img class="photo-area" @click="selecttouxiang"  :src="src">
       <i class="iconfont icon-tubiaosvg-"></i>
    </div>
  </div>
    <input type="file" ref="file" hidden @change="fileChange">
    <div class="infos">
          <div class="item" @click="showUpdateName">
            <span class="username">昵称</span>
            <span>{{username}}<i class="iconfont icon-fanhui"></i></span>
          </div>
      <div class="item">
        <span class="username">邮箱</span>
        <span>{{email}}<i class="iconfont icon-fanhui"></i></span>
      </div>
      <div class="item">
        <span class="username">密码</span>
        <span>...<i class="iconfont icon-fanhui"></i></span>
      </div>
        <!--修改昵称-->
        <mt-popup
          v-model="popupVisible"
          position="bottom"
        >
          <div style="display: flex;justify-content: space-between;color: #0a6999;">
          <span @click="popupVisible=false" >取消</span>
            <span style="color: black ">昵称</span>
          <span @click="updateName">确定</span>
          </div>
          <div class="textarea">
          <van-field
            v-model="newName"
            rows="1"
            autosize
            type="textarea"
            maxlength="20"
            placeholder="请输入昵称"
            show-word-limit
          ></van-field>
          </div>
        </mt-popup>
      <!--/修改昵称-->
    </div>

<!--预览头像-->
    <van-image-preview class="imgPreview" v-model="isShow" :images="images">
      <van-nav-bar
        slot="cover"
        left-text="取消"
        right-text="确定"
        left-arrow
        @click-left="isShow=false"
        @click-right="onClickRight"
      ></van-nav-bar>
    </van-image-preview>
    <!--/预览头像-->
  </div>
</template>>


<script>
  import { Toast } from 'mint-ui'
    export default {
        name: "PersonMaterial",
        data(){
            return{
                isShow: false,
                popupVisible: false,
                newName: '',
                src: '',
                username: '',
                email: '',
                images: []
            }
        },
        methods: {
            showUpdateName(){
                this.popupVisible=true
            },
            updateName(){

            },
            /*input 默认不显示 点击图片触发input 为file的点击*/
            selecttouxiang() {
                this.$refs.file.click()
            },
            /*input 输入框发生改变自动触发事件*/
            fileChange() {
                //1.获取file 类型的input 选择的文件对象
                // console.log(this.$refs.file)
                const fileObj = this.$refs.file.files[0]
               //2. 使用window.URL.createObjectURL(fileObj)
                // const fileData=window.URL.createObjectURL(fileObj)
                /*本来没有确认取消 自定义模板类容 要用插槽*/
                //图片转化成base64格式
                var reader = new FileReader()
                reader.onload = (fileObj) => {
                    let res = fileObj.target
                    this.src = res.result
                    this.images = [this.src]
                }
                reader.readAsDataURL(fileObj)
                this.isShow=true
            },
            onClickRight() {
                const fd = new FormData
                fd.append('photo', this.images[0])
                //将图片路径存进数据库里面
                this.$axios.post('/api/Order/upDatePhoto.html', fd)
                    .then(res => {
                        if (res.data.code > 0) {
                            Toast('更新成功')
                            this.src = this.images[0]
                        } else {
                            Toast('更新失败')
                        }
                        this.isShow = false
                    })
                    .catch(function (err) {
                        console.log(err)
                    })
            },

        },
        /*获取当前页面的用户信息*/
        mounted () {
           this.$axios.get('/api/Order/selectPhoto.html')
               .then(
                   res=> {
                       console.log(res.data)
                    if(res.data.code>0) {
                        this.username=res.data.data.username
                        this.email=res.data.data.email
                        this.src=res.data.data.photo
                    }
                   }
               )
               .catch(function (err) {
                   console.log(err)
               })
        }
    }
</script>

<style lang="stylus" scoped>
  .textarea >>> .van-field__word-limit
     width 10%
     float right
  .imgPreview >>> .van-image__img
      width 100%
      height 100%
      margin-top 150px
  .imgPreview >>> .van-nav-bar__left  .van-nav-bar__text
      position absolute
      left 10px
      bottom 10px
      color #fff
      font-size 15px
  .imgPreview >>> .van-nav-bar__right  .van-nav-bar__text
      position absolute
      right 10px
      bottom 10px
      color #fff
      font-size 15px
  .imgPreview >>>.van-image-preview__index
      margin-top 20px
      text-align center
      color #fff

  div.mint-popup.mint-popup-bottom
    width 100%
.header
   height 4rem
   background-color #37D164
   text-align center
   color #fff
  .imgPreview
       background-color black
       position absolute
       top 0
       bottom 0
       left 0
       right 0
       width 100%
   .title
     display: block;
     padding-top .4rem
     font-size .4rem
   .icon-fanhui1
     font-size: .45rem;
     position absolute
     top .4rem
     left .4rem
   .photo-area
      width 2rem
      height 2rem
      border-radius 50%
      z-index 999
      margin .4rem auto
  .icon-tubiaosvg-
    font-size: .5rem;
    position: absolute;
    top: 2.5rem;
    right: 2.8rem;
    border-radius: 50%;
    background: #18323b78;
  .item
    height: .8rem;
    line-height: .8rem;
    display flex
    justify-content space-around
    font-size .35rem
    border-bottom .01rem solid #cacaca
    .username
      width: 65%;
    .icon-fanhui
      padding-left: .2rem;
     .updatePassword
       width 75%
</style>

图示:
Vue 自提项目 --小益回收 遇到的问题(二)_第1张图片Vue 自提项目 --小益回收 遇到的问题(二)_第2张图片
!!!注意 图片转成base64之后数据库的类型必须存为longtext不然不够长 图片显示不出来

给按钮绑定点击事件不生效

再移动端项目中 如果使用了betterscroll默认会阻止touch行为

       mounted () {
            this.scroll=new BScroll(this.$refs.wrapper,{ click: true})
        },

此时点击按钮就生效了!

thinkphp实现搜索功能


    public function useradmin(){
    判断关键字是否存在
        $keywords=input('keywords');
        if($keywords){
            $map['username|email'] = array('like','%'.$keywords .'%');
            $users =Db::name('tb_user')->where($map )->select();
            $this->assign('users',$users);
            return $this->fetch();
        }else{
            $users=Db::name('tb_user')->paginate(5);
            $this->assign('users',$users);
            return $this->fetch();
        }

    }

这个搜索是将关键字通过form表单传到后台进行判断 在和数据库中的某个字段进行比较返回给前端

<div class="layui-body">
    <!-- 内容主体区域 -->
    <div style="padding: 15px;">
        <form method="post" action="{:url('xiaoyi/userAdmin')}">
        <div class="demoTable">
            搜索关键字:
            <div class="layui-inline">
                <input class="layui-input" id="search"  name="keywords" autocomplete="off">
            </div>
            <button type="submit" class="layui-btn" data-type="reload">搜索</button>

        </div>
        </form>
        <table class="layui-table">
            <thead>
            <tr>
                <th>ID</th>
                <th>姓名</th>
                <th>密码</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            <ul>
                {volist id="v" name="users"}
                <tr>
                    <td>{$v.id}</td>
                    <td >{$v.username}</td>
                    <td>{$v.password}</td>
                    <td>{$v.email}</td>
                    <td>
                        <a href="{:url('xiaoyi/useredit',['id'=>$v.id])}" class="layui-btn layui-btn-xs">编辑</a>
                        <button   onclick="showdel('{$v.id}','{$v.username}')" class="layui-btn layui-btn-danger layui-btn-xs">删除</button>
                    </td>
                </tr>
                {/volist}
            </ul>
            </tbody>
        </table>

    </div>
</div>

图片上传

如果图片如果不传base64,而是直接用form上传文件的话,一定要设置这个属性:enctype=“multipart/form-data”
思路大概是 一个type='file’的input输入框 默认不显示,点击一个东西触发input的点击 弹出选择文件

 function  fileChange() {
        //1.获取file 类型的input 选择的文件对象
        const fileObj =   document.getElementById('input').files[0]
        var reader = new FileReader()
        reader.onload = (fileObj) => {
            let res = fileObj.target
            document.getElementById('img').src= res.result  //实现预览
            document.getElementById('photo').value=res.result //将base64格式的数据传给一个默认不显示的输入框用表单提交给后台

        }
        reader.readAsDataURL(fileObj)
    }
  <form method="post" action="{:url('product/addProduct')}" enctype="multipart/form-data">

                <input id="input"  onchange="fileChange()" type="file"  style="display: none">
                <input type="hidden" id="photo" name="photo" value="">



                    <div class="product">商品图片
                        <i onclick="addImg()" id="icon" style="font-size:60px ;color: grey" class="iconfont icon-web-icon-"></i>
                        //点击图标触发文件选择显示
                        <img class="img" id="img">
                    </div>
                </div>
            </form>

swiper组件轮播的时候如果写相对路径 必须
require不能省

        <img class="swiper-img"  :src="item.imgUrl">
     swiperList: [
                    {id: 1, imgUrl:  require('../../../assets/img/w.png')},
                    {id: 2, imgUrl: require('../../../assets/img/s.png')}
                ]

你可能感兴趣的:(vue)