微信小程序
小程序的钩子函数,页面不同的跳转方式,触发的钩子并不一样。
小程序,会在 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方法去更新
微信小程序
创建:在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
}
})
父组件:
<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就是传过来的值
}
父级
<名 :任意名 = 需要传入子级的数据对象名>名>
子级
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
},
},
安装路由
地址: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 协议被提供服务。
创建一个 hash 历史记录。对于没有主机的 web 应用程序 (例如 file://
),或当配置服务器不能处理任意 URL 时这非常有用。注意:如果 SEO 对你很重要,你应该使用 createWebHistory
。
RouteRecordRaw
当用户通过 routes
option 或者 router.addRoute()
来添加路由时,可以得到路由记录。 有三种不同的路由记录:
component
配置components
配置component
或 components
配置,因为重定向记录永远不会到达。里面含有属性
path:string
路由地址:例如/users/:id
name
string | symbol
(可选)redirect
RouteLocationRaw | (to: RouteLocationNormalized) => RouteLocationRaw
(可选)重定向:例如redirect:"/index",
类型: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"),
},
],
})
})
类型:Ref
详细内容:
当前路由地址。只读的。
安装:官网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的值
},
1
13
区别
params:不放在url上
例如:http://192.168.3.224:3000/#/oms/orderDetail
query:放在url上
例如:http://192.168.3.224:3000/#/oms/orderDetail?id=15
用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 )
带参数用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}`)
微信小程序
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,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
用于vue2
https://element.eleme.cn/#/zh-CN
Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
用于vue3
https://element-plus.gitee.io/zh-CN/
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/](
用于vue3
https://vitejs.cn/
用于vue2
https://cli.vuejs.org/zh/
https://react.docschina.org/
//存入:
localStorage.setItem("token", res["x-auth-token"]);
localStorage.setItem(key名, value值);
//获取数据
const token = localStorage.getItem('token')
//清除(删除)
localStorage.removeItem("token");
//清除所有
localStorage.clear()
sessionStorage 也是一样的
使用Cookies
import Cookies from 'js-cookie'
//存储
Cookies.set('token', 值)
//获取数据
const token = Cookies.get('token')