官方文档:https://hhyang.cn/v2/start/quickstart.html
// 针对uniapp HBuilder创建的项目,非cli构建
// 1⃣ NPM 安装
npm install uni-simple-router
// 2⃣ 初始化
npm install uni-read-pages // 配合vue.config.js自动读取pages.json作为路由表的方式,源码例如下:扩二
// 配置vue.config.js
const TransformPages = require('uni-read-pages')
const tfPages = new TransformPages()
module.exports = {
configureWebpack: {
plugins: [
new tfPages.webpack.DefinePlugin({
// 1⃣ 配置全局变量
// ROUTES: JSON.stringify(tfPages.routes)
// 2⃣ includes 可自定义,解析pages.json路由配字段的配置, 默认 ['path', 'name', 'aliasPath']
ROUTES: tfPages.webpack.DefinePlugin.runtimeValue(()=>{
const tf = new TransformPages({
includes: ['path', 'name', 'aliasPath']
})
return JSON.stringify(tfPages.routes)
},true)
})
]
}
}
// /Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/webpack 我的webpack包路径,在软件contents包文件里软件自带的webpack
// 1⃣ 用法:每个传进DefinePlugin的键值都是一个标志或者多个用.连接起来的标识符
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
BROWSER_SUPPRTS_HTML5: true,
VERSION: JSON.stringify('abcde'),
TWO: '1+1',
'typeof window': JSON.stringify('object')
})
// 使用方式
console.log('Running App version', VERSION)
if(!BROWSER_SUPPRTS_HTML5) require("html5shiv")
// 2⃣ 功能标记 来作为一个flag标识启用和禁用构建中的功能
new webpack.DefinePlugin({
'SHOW_PRESSION': JOSN.string(true)
})
// 3⃣ 服务:可以配置不同环境下的url
new webpack.DefinePlugin({
'DEV_URL': JSON.stringify(url_dev),
'PRO_URL': JSON.stringify(url_pro)
})
// 依赖的源码 - 通过node的path模块获取pages.json文件中的任何信息 (部分是个人注释)
const path = require('path')
const CONFIG = { includes: ['path', 'aliasPath', 'name'] } // 默认获取路由参数属性
// process.cwd() 返回Node.js进程的当前工作目录
// path.resolve(url1, 'abc') => url1/abc
const rootPath = path.resolve(process.cwd(), 'node_modules'); // 获取根路径
/** 解析绝对路径
* @param {Object} dir
*/
function resolvePath(dir) {
return path.resolve(rootPath, dir);
}
// 类
class TransformPages {
constructor(config) {
// 组合 自定义获取配置属性
config = { ...CONFIG, ...config };
this.CONFIG = config;
// ↓本机文件路径(HBuilderX包文件里自带的webpack模块路径) /Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli/node_modules/webpack
this.webpack = require(resolvePath('webpack'));
this.uniPagesJSON = require(resolvePath('@dcloudio/uni-cli-shared/lib/pages.js'));
// TODO: 根据CONFIG解析pages.json中的路由信息 和 小程序 分包下的路由
this.routes = this.getPagesRoutes().concat(this.getNotMpRoutes());
}
// 获取所有pages.json下的内容 返回json
get pagesJson() {
return this.uniPagesJSON.getPagesJson();
}
// 通过读取pages.json文件 生成直接可用的routes
getPagesRoutes(pages = this.pagesJson.pages, rootPath = null) {
const routes = [];
for (let i = 0; i < pages.length; i++) {
const item = pages[i];
const route = {};
for (let j = 0; j < this.CONFIG.includes.length; j++) {
const key = this.CONFIG.includes[j];
let value = item[key];
if (key === 'path') {
value = rootPath ? `/${rootPath}/${value}` : `/${value}`
}
if (key === 'aliasPath' && i == 0 && rootPath == null) {
route[key] = route[key] || '/'
} else if (value !== undefined) {
route[key] = value;
}
}
routes.push(route);
}
return routes;
}
// 解析小程序分包路径
getNotMpRoutes() {
const { subPackages } = this.pagesJson;
let routes = [];
if (subPackages == null || subPackages.length == 0) {
return [];
}
for (let i = 0; i < subPackages.length; i++) {
const subPages = subPackages[i].pages;
const root = subPackages[i].root;
const subRoutes = this.getPagesRoutes(subPages, root);
routes = routes.concat(subRoutes)
}
return routes
}
/**
* 单条page对象解析
* @param {Object} pageCallback
* @param {Object} subPageCallback
*/
parsePages(pageCallback, subPageCallback) {
this.uniPagesJSON.parsePages(this.pagesJson, pageCallback, subPageCallback)
}
}
module.exports = TransformPages
import {RouterMount,createRouter} from 'uni-simple-router';
const router = createRouter({
// 路由配置
routes: [
{
path: '/pages/index/index', // 必须和pages.json中相同
extra: {
pageStyle: { color: '#f00' }// 及其它自定义参数
}
}
]
})
// 组件中可以通过 this.$Route 查看路由元信息
// 使用 vue-router开发将会失去uniapp的生命周期
const router = createRouter({
h5: {
vueRouterDev: true, // 完全使用vue-router开发 默认是false
},
// 路由配置
routes: [
{
path: '/',
name: 'home',
component: () => import('@/common/router/home.vue'),
// 嵌套路由(仅H5端),小程序端会重新页面打开
children: [
{
path: 'home/children1',
name: 'children1',
component: () => import('@/common/router/children1.vue')
},
{
path: 'home/children2',
name: 'children2',
component: () => import('@/common/router/children2.vue')
}
]
}
]
})
// 除vue-router外,美化url可以在基础配置时,定义aliasPath变量,设置路由别名(浏览器地址栏展示名称)
// 别名的设置,如果设置了别名,通过push路径的方式,必须使用aliasPath的路径才能生效
const router = createRouter({
routes:[{
name:'router1',
//为了兼容其他端,此时的path不能少,必须和 pages.json中的页面路径匹配
path: "/pages/tabbar/tabbar-1/tabbar-1",
aliasPath: '/tabbar-1',
},]
});
// uni-simple-router路由跳转
// aliasPath命名的路由 => name传递参数需 params
this.$Router.push({ name: 'detail', params: { id: 1 } })
// 带查询参数,变成 /home/id=1 => path 对应query,params失效
this.$Router.push({ path: '/pages/index/detail', query: { id: 1 }})
path:'*' // 通常用于客户端404错误,如果是history模式,需要正确配置服务器
path: '/detail-*'
// 路由的优先级根据 定义的先后
打包构建应用时,Javascript包会变得非常大,影响页面加载,把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件。
const Foo = () => import('./Foo.vue')
// 把组件按组分块 使用 命名 chunk
const Foo = () => import(/*webpackChunkName:"group-foo"*/ './Foo.vue')
const Bar = () => import(/*webpackChunkName:"group-foo"*/ './Bar.vue')
注:小程序系列无法拦截原生tabbar及原生导航返回,如需拦截使用自定义tabbar、header
通过api进行切换时,像uni.switchTab()和this.$Router.pushTab()方法会触发拦截的;仅底部原生tabbar进行切换时不触发拦截
强制触发守卫:forceGuardEach(replaceAll, false) 每次调用api都会重新按流程触发已经声明的所有守卫
跳转路由锁:animationDuration保留给redirection\push足够时间,等切换完成页面后才放行下次跳转
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
// ① 路由锁
applet: {
animationDuration: 300 // 默认300ms
// animationDuration: 0 // 不精准 只捕捉跳转api下的complete函数
},
// ②优雅解锁 error.type: 0 表示 next(false)、1表示next(unknownType)、2表示加锁状态,禁止跳转、3表示在获取页面栈时,页面栈不够level获取
routerErrorEach:(error, router) => {
if (error.type === 3) {
router.$lockStatus = false
}
},
routes: [...ROUTES]
})
vue-router中可以通过router-link组件进行页面跳转,uni-simple-router也提供了类似的组件,需要手动注册
// main.js
import Link from './node_modules/uni-simple-router/dist/link.vue'
Vue.component('Link', Link)
// 通过path直接跳转 并指定跳转类型
<Link to="/tabbar1" navType="pushTab">
<button type="primary">使用path对象跳转</button>
</Link>
uniapp由于只用onLoad接受options参数、onShow不接受;传递深度对象参数时,需要先编码再传递解码
// 动态改变参数 使 onLoad和onShow支持options
const router = createRouter({
platform: process.env.VUE_APP_PLATFORM,
routes: [...ROUTES],
beforeProxyHooks: {
onLoad(options, next){
next([router.currentRoute.query]);
},
onShow([options], next){
console.log(this);
const args=options||router.currentRoute.query;
next([args]);
},
},
});
全局前置守卫
/**
* to: Route 即将进入的目标
* from: Route 当前导航正要离开的路由
* next: Function 该方法的resolve钩子函数必须调用,执行效果依赖next方法的调用参数
* -- next()调用参数:管道中的下个钩子; next(false)中断当前导航;
* -- next('/')/({path: '/'})跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
* -- next({delta: 2, NAVTYPE: 'back'}) 中断当前导航,调用新的跳转类型,同时返回两层页面
**/
router.beforeEach((to, from, next) => {
// ...
// 1⃣ next()
// 2⃣ NAVTYPE定义跳转方式,两者相同非必填
if (to.name == 'tabbar-5') {
next({
name: 'router4',
params: {
msg: '我拦截了tab5并重定向到了路由4页面上',
},
NAVTYPE: 'push'
});
} else{
next();
}
})
全局后置守卫
// 不接受next函数也不改变导航本身
router.afterEach((to,from) => {})
路由独享守卫
// 路由配置上直接定义beforeEnter守卫
const router = createRouter({
routes: [{
path: '/pages/home/index',
beforeEnter:(to,from,next) => {
// 参数同上全局前置守卫
next()
}
}]
})
组件内的守卫
// 组件内配置beforeRouteLeave守卫 - 直接调用beforeRouteLeave方法
export default {
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例this
next()
}
}
// 1⃣ 创建 router文件夹,模块化配置 文件结构
|+------------------------+|
| router |
| |+--------------------+| |
| | modules | |
| | |+----------------+| | |
| | | home.js | | |
| | | index.js | | |
| | |+----------------+| | |
| |+--------------------+| |
| index.js |
|+------------------------+|
// home.js
const home = [
{
path: '/pages/home/index',
name: 'home'
}
]
export default home
// modules下的index.js是一个模块读取
// ① require.context(directory, useSubdirectories, regExp) 具体详情:如下扩三
const files = require.context('.',false,/.js$/)
const modules = []
files.keys().forEach(key => {
if (key === './index.js') return
const item = files(key).default
modules.push(...item)
})
export default modules // 将所有模块的路由模块整合到一起, routes Array
// router下的index.js 路由守卫
import modules from './modules/index.js'
import Vue from 'vue'
import CreateRouter from 'uni-simple-router'
import store from '@/store/store.js'
Vue.use(CreateRouter)
//初始化
const router = new CreateRouter({
APP: {
holdTabbar: false //默认true
},
h5: {
vueRouterDev: true, //完全使用vue-router开发 默认 false
},
// 也可以 通过uni-read-pages来读取pages.json文件的路由表,配合vue.config.js
// router: [...ROUTES] // ROUTES是通过webpack的defaultPlugin编译成全局变量,具体操作上文
routes: [...modules] //路由表
});
//全局路由前置守卫
router.beforeEach((to, from, next) => {
// 首先判断是否存在路由信息
//不存在就先调用接口得到数据
})
// 全局路由后置守卫
router.afterEach((to, from) => {})
export default router;
// require.context(directory, useSubdirectories, regExp)
// directory: 表示检索的目录
// useSubdirectories: 表示是否检索子文件夹
// regExp: 匹配文件的正则表达式
// 返回值: resolve是一个函数,返回已解析请求的模块ID; keys是一个函数,它返回上下文模块可以处理的所有可能请求的数组;
// 使用场景:①用来组件内引入多个组件;②在main.js内引入大量公共组件;
// ①组件内引入多个组件 - webpack
const path = require('path')
const files = require.context('@/components/home', false, /\.vue$/) //值类型 ['./home.js', 'detail.js',...]
const modules = {}
files.keys().forEach(key => {
const name = paths.basename(key, '.vue') // 去掉文件名的 .vue后缀
modules[name] = files(key).default || files(key)
})
// modules { home: '{module样式路径}', detail: '{}', ... }
export default {
...,
data() { return {}},
components: modules
}
// ②在main.js内引入大量公共组件
import Vue from 'vue'
// 引入自定义组件
const requireComponents = require.context('../views/components',true,'/\.vue/')
// 遍历出每个数组的路径
requireComponents.keys().forEach(fileName => {
const reqCom = requireComponents(fileName)
// 获取组件名
const reqComName = reqCom.name || fileName.replace(/\.\/(.*)\.vue/, '$1')
// 组件挂载
Vue.components(reqComName, reqCom.default || reqCom)
})
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visitthehelpcenter.关闭9年前。我需要从基于ruby的应用程序使用AmazonSimpleNotificationService,但不知道从哪里开始。您对从哪里开始有什么建议吗?
我在RoR应用程序中有一个提交表单,是使用simple_form构建的。当字段为空白时,应用程序仍会继续下一步,而不会提示错误或警告。默认情况下,这些字段应该是required:true;但即使手动编写也行不通。该应用有3个步骤:NewPost(新View)->Preview(创建View)->Post。我的Controller和View的摘录会更清楚:defnew@post=Post.newenddefcreate@post=Post.new(params.require(:post).permit(:title,:category_id))ifparams[:previewButt
我正在使用PostgreSQL、Rails3.1.3和Ruby1.9.3。我正在努力使用db:migrate概述here.这是我在终端中看到的:funkdified@funkdified-laptop:~/railsprojects/hartl$bundleexecrakedb:migrate--trace**Invokedb:migrate(first_time)**Invokeenvironment(first_time)**Executeenvironment**Invokedb:load_config(first_time)**Invokerails_env(first_tim
我正在使用simple_formgem。我想自定义在用户验证失败时显示的错误消息。我怎样才能做到这一点? 最佳答案 你可以声明的内容模型中的错误消息:validates_length_of:name,:minimum=>5,:message=>"blahblahblah"您可以为您的设备设置id或class错误标记:{:id=>"name_error"}%>然后您可以使用CSS进行样式设置。你可以使用"name_error"%>你会得到istooshort(minimumis5characters)
随着我学习Ruby语言,我离实际编程越来越近了。我正在考虑创建一个简单的纸牌游戏。我的问题不是面向Ruby的,但我确实想学习如何使用真正的OOP方法解决这个问题。在我的纸牌游戏中,我想有四名玩家,使用一副有52张牌的标准牌组,没有王牌/万能牌。在游戏中,我不会把A当成双牌,它永远是最高的牌。所以,我想知道的编程问题如下:如何对一副纸牌进行排序/随机化?有四种类型,每种类型有13个值。最终只能有唯一值,因此随机选择值可能会产生重复值。如何实现简单的AI?由于有大量的纸牌游戏,有人应该已经弄清楚了这部分,所以引用会很好。我是一个真正的Rubynuby,我的目标是学习解决问题,所以伪代码会很
这是我的第一个ruby应用程序。我是一个堆栈溢出处女......当我运行以下程序时:classNameAppdefintialize(name)@names=[]enddefname_questionprint"Whatisyourname?"answer=gets.chomp@names+=answer.to_sputs"Thenumberofcharactersinyournameis"+names.lengthenddefname_lengthif@names.length>25thenprint"Yournameislongerthan25characters."elsepri
例如,运行H5页面,请求一个地址资源,如果不是本站地址,浏览器就会报跨域错误,这样访问受限问题呈现例如,项目代码里是这样写的,运行H5测试uni.request({ url:'https://gitcode.net/zs1028/stat...ouces_2023/-/...', success(res){ console.log(res) }, fail(err){ console.error(err) }})因为https://gitcode.net不是本站地址,根据浏览器同源策略,是会报跨域错误,解决步骤打开项目的manifest.json文件,以源码视图查看,添加以下代码{ //.
如何使simple_format不将返回值包装在p标签中?simple_format"*" 最佳答案 您可以指定wrapper_tag选项。simple_format'Hello',{},wrapper_tag:'span'此代码将是:Hello 关于ruby-on-rails-Rails3.simple_format不要将结果包装在段落标签中,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/ques
我正在使用simple_form,我想知道在处理关联选择时是否可以跳过任何包装div。谢谢 最佳答案 如果您使用类似f.association:product的东西,您可以像这样删除生成的标签和包装器:f.association:product,label:false,wrapper:false 关于ruby-on-rails-跳过与simple_form关联的包装器,我们在StackOverflow上找到一个类似的问题: https://stackoverf
我正在尝试使用以下模型创建一个简单的应用程序:类别--[has_many]-->问题--[has_many]-->答案我有以下用于创建类别+问题的代码(categories/_form.haml.html):=simple_form_for(@category)do|f|=f.error_notification=f.input:title,label:"Categorytitle:"=f.simple_fields_for:questions,@category.questions.builddo|q|=q.input:content,label:"Questioncontent:"