vue和微信小程序的基本使用区别

微信小程序双向数据绑定和vue的异同?

微信小程序

生命周期的钩子函数

小程序的钩子函数,页面不同的跳转方式,触发的钩子并不一样。

请求数据

小程序,会在 onLoad或者 onShow中请求数据。

数据绑定

动态绑定某个变量的值,用两个大括号括起来 { { } }

列表渲染

wx:for ="{{}}"   //每个循环都会自带 item 与 index

wx:key="*this"  //不写会报错

显示与隐藏元素

小程序中,使用 wx-if和 hidden控制元素的显示和隐藏。

wx:if hidden
用法: wx:if="{{true}}" hidden="{{ifShow}}"
渲染条件 在条件第一次变成真的时候才开始局部渲染。 组件始终会被渲染,只是简单的控制显示与隐藏。
特点: 更高的切换消耗 更高的初始渲染消耗
使用场景: 频繁切换 切换较少

事件处理

小程序中,全用 bindtap(bind+event),或者 catchtap(catch+event)绑定事件

 bindtap="tapFn"
 
 在js文件中:
 
 Page({
  data: {
    ...
  },
  tapFn(){
    // do something...
  }
})

数据双向绑定

this.setData

this。setData({ })里面时对象

//在wxml文件中,绑定点击事件和值
<input value="{{msg}}" bindinput="iptFn"></input>
<view>{{msg}}</view>
//在js中文件
Page({
  data: {
    msg: '你好,世界'
  },
  // input值被修改时触发的函数
  iptFn(e){
    this.setData({
      msg: e.detail.value
    })
  }
})

vue

生命周期的钩子函数

vue的钩子函数在跳转新页面时,钩子函数都会触发。

请求数据

vue一般会在 created或者 mounted中请求数据

数据绑定

动态绑定某个变量的值,会在变量前面加上冒号:

列表渲染

v-for="(item,index) in arr" :key="index"

显示与隐藏元素

vue中,使用 v-if 和 v-show控制元素的显示和隐藏。

v-if v-show
用法: v-if=“status == 1” v-lese v-show=“status == 1”
渲染条件 根据条件渲染或者销毁元素 只会控制元素的显示和隐藏,相当于改变display值
特点: 更高的初始渲染消耗 更高的切换消耗
使用场景: 切换较少 频繁切换

事件处理

vue:使用 v-on:event绑定事件,或者使用 @event绑定事件

双向数据绑定

原理:是通过 数据劫持 结合 发布订阅模式 的方式来实现的;

利用其中的 gette( ) 和 setter() 方法,当读取属性值时,会触发gette( ) 方法,view中数据发生了变化,会通过Object.defineProperty()对属性设置一个setter函数,当数据改变了就会来触发这个函数;

也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变

        let num = 0;
        // 定义p对象上age属性; get和set方法分别对age属性的获取和赋值进行拦截,get方		法的返回值就是age属性对应的值
        Object.defineProperty(p, 'age', {
            // value: 20,
            get() {//监听读取操作
            获取数据的时候 本身是没有值的 值是有另外一个函数 return 出来的
            get就是在读取name属性这个值触发的函数
                console.log('age上的get方法')
                // document.getElementById()
                return num;
            },
            set(val) {//监听写入操作
            改变数据的时候 进入的set 里面
            set就是在设置name属性这个值触发的函数
                num += (val + 100)
                console.log('age上的set方法', val)
            }
        })
        p.age = 30;
        console.log(p.age);

具体用法:this.XXX = XX(必须是data里面的键值名)

为什么?Vue 组件 data 为什么必须是函数?

data是一个函数的话,这样每复用一次组件,就会返回一份新的data,等于给每个组件实例创建了一个私有的数据空间,让各自组件实例维护各自的数据;写成对象就会使得所有组件实例公用了一份data,造成了一变全变的结果。

export default {
  data() {
    return {
      selectAll:false
    };
  },
    
  add(){
      this.selectAll = true
  }
}

两种情况下不会触发视图更新

1.在实例创建之后添加新的属性到实例上(给响应式对象新增属性)

2.直接更改数组下标来修改数组的值

vuex2.0中,数据发生变化,界面没有更新,需要用$set方法解决

Vue.set(obj, key, value);
// or
this.$set(obj, key, value);

使用方法:
接收三个参数
this.$set(原数组或者原对象,索引值或者键值对名,需要赋的值)


//具体用法:
this.$set(this.cartData[idx], "checked", !this.cartData[idx].checked);

原理:增加__ob__属性,,当出现新属性时,会触发__ob__的dep收集到watcher去更新;数组的话就会调用splice方法去更新

组件化开发(vue2、vue3和微信小程序的区别)

新建、声明、调用组件

微信小程序

创建:在app.json 中的 pages 进行创建:

{
  "pages": [
    ...,
    "components/product/product"
  ],
}

组件文件的js文件,需要把Page()方法改成了Component()方法、方法调用用 methods: { }

//wxml和wxss文件按照正常的写

//在js文件中,把Page()方法改成了Component()方法
Component({
  data: {
    showArr: [
      {imgSrc: "/images/home/newPro1.jpg", imgTxt: "卡布奇诺"},
    ]
  },
})

//方法的调用
methods: {
    //事件
    getFn(){
        
    }
}

声明组件

//在组件的json文件中 加入"component": true 声明为组件
{
  "usingComponents": {},
  "component": true
}

调用组件

//在调用的组件的页面中的json文件中,使用组件usingComponents,并写入组件的位置

{
  "usingComponents": {
    //调用组件
    "product-block": "/components/product/product"
  },
  "navigationStyle": "custom"
}

//在wxml文件中就可以直接使用(单标签或者双标签都可以)
<product-block />
或:
<product-block></product-block>

Vue2

vue3

新建组件

直接在components文件中,新建vue文件

声明组件(组件注册)

局部注册(或者组件内注册)

在使用组件的的XX.vue的文件中,写入

//引入组件
import MyCom from './components/Mycom.vue'

//直接使用
<template>
<!-- 局部组件 -->
  <MyCom></MyCom>
</template>

全局组件

在main.ts文件中,引入

import MyCom1 from './components/Mycom.vue'
//导出
createApp(App).component('my-com',MyCom1).mount('#app')

在使用组件的XXX.vue文件中直接使用

<template>
  <!-- 全局组件 -->
  <my-com></my-com>
</template>

组件之间传值

微信小程序

父传子
父组件:
<list-box listArr="{{listArr}}" bind:getListcell="getListcell"></list-box>

传入子组件的数据名 = 父组件的数据名

子组件:
在properties里面接收
    properties: {
        listArr: {
            type: Array,
            value: []
        }
    },
子传父

自定义事件

//使用事件来进行传递
//在子组件中写入事件 ,然后通过 triggerEvent 进行传递
//子组件的js文件
// components/product/product.js
Component({
  ...,
  // 如果是组件,不是页面,就必须写methods
  methods: {
    productTap(){
  		// 小程序中子传父通过triggerEvent来实现
      this.triggerEvent('fatherEvent', 100);
                     传入父组件的自定义事件名,参数
    }
  }
})

//父组件中通过bind:自定义事件名
//
<product-block showArr="{{showArr}}" bind:fatherEvent="fatherEventFn" />
                                   子组件的自定义事件名  ,父组件的事件名
                                   
Page({
  ...,
  // 页面无需写methods
  fatherEventFn(data){
    console.log(data.detail); // 100
  }
})

vue3

父传子
  父组件:
  <Dialog :Visible="Visible" @close="visibleFn" :dialogData="dialogData" :isShow="isShow"></Dialog>
    
   父组件向子组件传值
   用自定义属性
   :子组件值名 = '父组件值名'
   
   
   子组件接收 用props接收
   let props = defineProps<{
    Visible: Boolean
    dialogData: AdminObjInfo
    isShow: Boolean
}>();

然后在dom元素上直接用 {{Visible}}

在script里面
要用props.Visible才可以拿到值

const { newdialogData, innerVisible } = toRefs(state)
watch(() => props.dialogData, () => {
    newdialogData.value = { ...props.dialogData }
})
子传父

自定义事件—用emit 第一个值是自定义事件名,第一个参数是值

子组件:
const emit = defineEmits<{
    (event: 'close', r: number): void
}>()
//事件点击调用
const close = (r: number) => {
    emit('close', r)
}


父组件:
<Dialog :Visible="Visible" @close="visibleFn" :dialogData="dialogData" :isShow="isShow"></Dialog>
		子组件命名的自定义事件类型 = 事件名

const visibleFn = (e: number) => {
    console.log(e);
    //e就是传过来的值
}

vue

父传子
父级
<名 :任意名 = 需要传入子级的数据对象名>

子级
  props: {
    需要传入子级的数据对象名(wrapperDate): {
      type: Object,
      default: {},//默认值
      required:false/true  //必填,一定要传值
    }
    
    
   三种写法,另外另种
   一、
   props: {
           num: Number,
           }
           
  二、
  props :['num']

 然后子级就可以直接调用
 {{wrapperDate.cancelTxt}}
子传父
子级
methods: { cancelFn(参数) { this.$emit("canceler自定义事件名" 参数); }, }, 父级 methods:{ fn(){ this.clickResult = this.textObj.cancelTxt }, },

路由设置router

vue3

安装路由

地址:https://router.vuejs.org/installation.html

npm i vue-router@next -S
//next代表最新版本
//或者直接官网npm具体版本
npm install vue-router@4

yarn下载
yarn add vue-router@4

在src目录下,新建router/index.ts文件进行路由配置

//引入路由
import {
  createRouter,
  createWebHashHistory,
  RouteRecordRaw,
  Router,
} from "vue-router";

const routes: Array<RouteRecordRaw> = [
  {
    path: "/login",
    name: "Login",
    component: () =>
      import(/* webpackChunkName: "About" */ "../views/login/Login.vue"),
  },
];

const router: Router = createRouter({
  history: createWebHashHistory(),
  routes,
});

export default router;

createRouter

创建一个可以被 Vue 应用程序使用的路由实例。查看 RouterOptions 中的所有可以传递的属性列表。

createWebHashHistory

创建一个 HTML5 历史,即单页面应用程序中最常见的历史记录。应用程序必须通过 http 协议被提供服务。

createWebHashHistory

创建一个 hash 历史记录。对于没有主机的 web 应用程序 (例如 file://),或当配置服务器不能处理任意 URL 时这非常有用。注意:如果 SEO 对你很重要,你应该使用 createWebHistory

RouteRecordRaw

当用户通过 routes option 或者 router.addRoute() 来添加路由时,可以得到路由记录。 有三种不同的路由记录:

  • 单一视图记录:有一个 component 配置
  • 多视图记录 (命名视图) :有一个 components 配置
  • 重定向记录:没有 componentcomponents 配置,因为重定向记录永远不会到达。

里面含有属性

path:string

路由地址:例如/users/:id

name

  • 类型string | symbol (可选)
  • 路由记录独一无二的名称。

redirect

  • 类型RouteLocationRaw | (to: RouteLocationNormalized) => RouteLocationRaw (可选)
重定向:例如redirect:"/index",

children

  • 类型RouteRecordRaw 数组 (可选)

  • 详细内容

    当前记录的嵌套路由。

      children: [
        {
          path: "index",
          name: "Index",
          component: () => import(/* webpackChunkName: "cart" */ "../views/index/index.vue"),
        },
      ],

路由前置导航

在router/index.ts文件夹里面

在export default router; 导出路由的前面写路由前置导航

判断是否含有token等等登录信息

// 前置导航守卫
router.beforeEach((to, from, next) => {
  const token = Cookies.get('token')
  if (token && store.state.menus.length === 0) {
    // console.log('menus为空');
    getAdminInfoApi().then(res => {
      // console.log(res);
      // store.commit('updataments', res.data.menus)
      getRouter()

      next(to.path)
    })

  }else if(token && store.state.menus.length !== 0 && from.path ==='/login' && to.path==='/home'){
    getRouter();
    next('/index')
  }else if(token && to.path==='/login'){
    ElMessage.error('你已经登录了')
    next(from)
  } else if(!token && to.path !=='/login'){
    ElMessage.error('你还没有登录哦,正在跳转登录页')
    next('/login')
  } else {
    next()
  }

vue3使用路由

由于vue3不能用$router或者this.router,所以要创建实例

//使用useRouter,返回 router 实例。相当于在模板中使用 $router。必须在 setup() 中调用。

//引入
import { useRouter } from 'vue-router'
let router = useRouter()

//然后就直接使用push方法,跳转页面
router.push('/home')

//获取当前路由地址 currentRoute方法
console.log(router.currentRoute.value);
//得到当前路由的对象,里面包含了 路由地址herf name 等诸多信息
//一般用fullPath属性拿到当前路由地址
{
fullPath: "/oms/order"
hash: ""
href: "/oms/order"
matched: Array(2)
0: {path: '/oms', redirect: '/oms/order', name: 'oms', meta: {}, aliasOf: undefined,}
1: {path: '/oms/order', redirect: undefined, name: 'order', meta: {}, aliasOf: undefined,}
length: 2
[[Prototype]]: Array(0)
meta:
[[Prototype]]: Object
name: "order"
params: {}
path: "/oms/order"
query:
[[Prototype]]: Object
redirectedFrom: {fullPath: '/oms/order', path: '/oms/order', query: {}, hash: '', name: undefined,}
[[Prototype]]: Object
}

//addRoute  添加一条新的路由记录作为现有路由的子路由。如果路由有一个 name,并且已经有一个与之名字相同的路由,它会先删除之前的路由。
//一般写在router/index.ts里面

    router.addRoute({
      path: "/",
      name: "homepage",
      component: () =>import("../views/index/homepage.vue"),
      redirect:"/index",
      children: [
        {
          path: "index",
          name: "Index",
          component: () => import(/* webpackChunkName: "cart" */ "../views/index/index.vue"),
        },
      ],
    })
  })

currentRoute

  • 类型Ref

  • 详细内容

    当前路由地址。只读的。

vue2

安装:官网https://router.vuejs.org/zh/installation.html

npm install vue-router@4

在src目录下新建router/index.js文件

import Vue from 'vue'
import VueRouter from 'vue-router'


Vue.use(VueRouter)

const routes = [
  {
    path: '/login',
    component: () => import(/* webpackChunkName: "about" */'../views/login/login.vue')
  },
  {
    path: '/',
    component: () => import('../views/good/index.vue'),
    children:[
      {
        path: 'good',
        name:"good",
        component: () => import('../views/good/good.vue'),
      },
      {
      path: 'brand',
      component: () => import('../views/good/brand.vue'),
    }
  ]
  },
  // {
  //   path: '/about',
  //   name: 'About',
  //   // route level code-splitting
  //   // this generates a separate chunk (about.[hash].js) for this route
  //   // which is lazy-loaded when the route is visited.
  //   component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  // }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

然后全局创建并挂载根实例,在main.js文件中引入并创建

import Vue from 'vue'
import App from './App.vue'
//引入路由
import router from './router'


Vue.config.productionTip = false
Vue.use(ElementUI);

//创建实例,并挂载在全局APP上
new Vue({
  router,//路由
  store,//vuex的
  render: h => h(App)
}).$mount('#app')


访问路由或者拿到当前页面的路由

//跳转页面
this.$router.push('/dashboard')

//动态路由或者路由上带参数
this.$router.push("/detail/" + pid);     获取参数方法:this.$route.params.pid   
URL /search?q=vue 将传递 {query: 'vue'} 作为 props 传给组件。


this.$router.push("/detail/" + pid);

微信小程序

页面跳转

//关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
       wx.navigateTo({
          url: '/pages/brand/brand?id='+brandId(参数),
        })
       
//跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
            wx.switchTab({
                url: this.data.list[event.detail].url,
              })


//获取路由(URL)参数 通过生命周期 onLoad
     * 生命周期函数--监听页面加载
    onLoad: function (options) {
        console.log(options.id);
      //获取当前路由的参数id的值
    },

路由跳转router

vue

通过router-link进行跳转
 1 
13 

区别

params:不放在url上
例如:http://192.168.3.224:3000/#/oms/orderDetail

query:放在url上
例如:http://192.168.3.224:3000/#/oms/orderDetail?id=15

发送请求

vue2

用qs

import qs from 'qs';
// 获取商品详情
export const getProducts = (id) => request.get('/cms/products/'+id)

// 加入购物车
export const addCart = (data) => request.post('/cms/shop/carts/add', qs.stringify(data))

// 删除购物车
export const getcartproductIds = (id) => request.delete('/cms/shop/carts?productIds='+id )
vue3

带参数用params

  // 查询订单
  export const getIOrderListData = (params:{}): PromiseRes<AdminOrBarandRes> => request.get('/order/list',{params});
  // 批量关闭订单
  export const getOrderUpdateApi = (params: {ids: string, note: string}): PromiseRes => request.post('/order/update/close', null, {params: params})

// 修改帐号状态
export const AdminupdateStatusApi = (id:number,status:number):ProminseRes<number> => request.post(`/admin/updateStatus/${id}/?status=${status}`)

微信小程序

开发使用的ui框架

微信小程序

vant

Vant 是一个轻量、可靠的移动端组件库,于 2017 年开源。

目前 Vant 官方提供了 Vue 2 版本、Vue 3 版本和微信小程序版本,并由社区团队维护 React 版本和支付宝小程序版本。

地址:Vant Weapp官网地址:https://vant-contrib.gitee.io/vant-weapp/#/home

安装依赖:

# npm初始化
npm init -y

# 通过 npm 安装
npm i @vant/weapp -S --production

# 或者通过 yarn 安装
yarn add @vant/weapp --production

element

Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库

用于vue2

https://element.eleme.cn/#/zh-CN

element-plus

Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库

用于vue3

https://element-plus.gitee.io/zh-CN/

Bootstrap

Bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目。

地址:https://v3.bootcss.com/

字体图库

阿里iconfont 字体图标

​ 链接:http://www.iconfont.cn/

其他一些字体图标

  • icommon字体图标 http://www.iconfont.cn/

  • Font-Awesome [http://fortawesome.github.io/Font-Awesome/](

前端开发与构建工具

vite

用于vue3

https://vitejs.cn/

Vue CLI

用于vue2

https://cli.vuejs.org/zh/

React

https://react.docschina.org/

本地存储

vue2

//存入:
localStorage.setItem("token", res["x-auth-token"]);
localStorage.setItem(key名, value值);

//获取数据
  const token = localStorage.getItem('token')
  
//清除(删除)
  localStorage.removeItem("token");
//清除所有
 localStorage.clear()

sessionStorage 也是一样的

vue3

使用Cookies

import Cookies from 'js-cookie'

//存储
Cookies.set('token',)

//获取数据
const token = Cookies.get('token')

你可能感兴趣的:(前端,vue,微信小程序)