1. 前言
Shiny在构建UI界面时,默认使用内置的Bootstrap v3.0框架,配合shinyjs
R包和 javascript
脚本可以满足绝大多数APP项目的构建。但基于这种方式开发的shiny APP, 往往给人一种千篇一律的感觉,UI界面不够引人入胜,不适用构建大型复杂的项目。现如今,React
、Vue
等前端框架被广泛应用在各种大型APP的开发中。使用这些先进的前端框架有着诸多优势,且目前针对这些前端框架有很多现成可用的成熟组件(比如 element-ui
, iView
),方便快速的开发漂亮的we b APP。这篇文章旨在整合前端框架与Shiny 开发,通过简单的案例,管窥更加现代化的Shiny APP的开发过程。
关键词:
- Shiny
- Vue
- element-ui
- packer
- leprechaun
2. 开发环境
# OS
MacOS Monterey Version 12.2.1
# IDE
Rstudio
# 依赖的软件
最新版Node.js
vue
elememt-ui
# 依赖的R包
shiny
pakcer
leprechaun
...
3. 搭建项目目录
3.1 创建项目
usethis::create_package("shinyApps/vueShiny")
leprechaun::scaffold()
# leprechaun shiny框架更加简洁轻便
# 也可选用golem框架 packer::scaffold_golem(vue = TRUE)
packer::scaffold_leprechaun(vue = TRUE)
3.2 修改根目录package.json
"devDependencies": {
"@babel/core": "^7.17.4",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.2.3",
"css-loader": "^6.6.0",
//添加style-loader
"style-loader": "^2.0.0",
//降低vue版本
"vue": "^2.6.0",
//降低vue-loader版本
"vue-loader": "^15.0.0",
"vue-template-compiler": "^2.6.14",
//添加vue-style-loader
"vue-style-loader": "^4.1.2",
"webpack": "^5.69.0",
"webpack-cli": "^4.9.2",
"webpack-merge": "^5.8.0"
},
更新软件版本
system("npm install")
3.3修改srcjs/config/loaders.json
[
{
"test": "\\.(js|jsx)$",
"use": [
"babel-loader"
],
"exclude": "/node_modules/"
},
{
"test": "\\.vue$",
"use": [
"vue-loader"
],
"exclude": "/node_modules/"
},
{
"test": "\\.css$",
"use": [
"vue-style-loader",
"style-loader",
"css-loader"
]
}
]
3.4 运行vue 模版
# packer::bundle()
# 修改R/ui.R
ui <- function(req){
fluidPage(
h1("vueShiny Demo"),
tagList(
vueCDN(),
div(id = "app"),
tags$script(src = "vueShiny-0.0.0.9000/assets/index.js")
)
)
}
运行vue模版
leprechaun::build()
devtools::document()
devtools::load_all()
run()
4. 应用element-ui 组建开发shiny APP
4.1 安装element-ui
packer::npm_install("element-ui", scope = "prod")
4.2 使用element-ui开发UI界面
修改srcjs/index.js
// srcjs/index.js
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './Home.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
修改srcjs/Home.vue
// srcjs/Home.vue
<template>
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker type="date" placeholder="Pick a date" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="Pick a time" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type"></el-checkbox>
<el-checkbox label="Promotion activities" name="type"></el-checkbox>
<el-checkbox label="Offline activities" name="type"></el-checkbox>
<el-checkbox label="Simple brand exposure" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor"></el-radio>
<el-radio label="Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
methods: {
onSubmit() {
console.log('submit!');
}
}
}
</script>
<style scoped>
</style>
运行之后,如下图所示:
到此,在shiny项目中使用element-ui已经有了一个雏形,接下来,还需要整合shiny与vue。
5. 整合Shiny与Vue开发
- 待实现
https://shiny.rstudio.com/gallery/kmeans-example.html