我正在尝试开发一个在后端使用谷歌表格的谷歌网络应用程序。
我想在 vscode 中进行本地开发,因为 google Apps Scripts 中的编辑器相当有限。 我也想用vue3。
为了设置我的开发环境,我遵循了我在网上找到的唯一教程。本教程使用 Parcel。
一切都很顺利,除了没有考虑放入每个视图组件的 style 标签中的 css 之外。
我找到了使用内联样式的解决方法,但这相当挑剔且令人沮丧。
浏览器中的控制台告诉我:
拒绝应用来自 'https://n-7y7vlmirjfpoibpjjmpw7rb4z2lf2rvl3foebnq-0lu-script.googleusercontent.com/index.7692ac92.css' 因为它的 MIME 类型('text/html')不是受支持的样式表 MIME 类型,并启用严格的 MIME 检查。
css 文件是由我的 package.json 中定义的构建脚本生成的,如下所示:
{
"name": "newcompta",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "nodemon --watch ./src -e html,js,vue --exec \"npm run build\"",
"build": "parcel build ./src/index.html --dist-dir ./appsscript",
"glogin": "clasp login",
"glogout": "clasp logout",
"gpull": "clasp pull",
"gpush": "clasp push",
"gcreate": "clasp create --title \"NEWCOMPTA\" --rootDir ./appsscript",
"gstart" :"clasp push --watch "
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@google/clasp": "^2.4.2",
"@parcel/transformer-vue": "^2.10.2",
"@types/google-apps-script": "^1.0.77",
"parcel": "^2.10.2"
},
"dependencies": {
"nodemon": "^3.0.1",
"vue": "^3.3.8"
}
}
我从头开始重新启动一个项目,看看问题是否从一开始就存在,事实确实如此。
以下是一些极简项目的文件示例。
index.html
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="module">
import "./index.js";
</script>
</body>
</html>
应用程序.vue
<template>
<Tabs>
<Tab active="true" title="First Tab">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce gravida purus vitae vulputate commodo.
</Tab>
<Tab title="Second Tab">
Cras scelerisque, dolor vitae suscipit efficitur, risus orci sagittis velit, ac molestie nulla tortor id augue.
</Tab>
<Tab title="Third Tab">
Morbi posuere, mauris eu vehicula tempor, nibh orci consectetur tortor, id eleifend dolor sapien ut augue.
</Tab>
<Tab title="Fourth Tab">
Aenean varius dui eget ante finibus, sit amet finibus nisi facilisis. Nunc pellentesque, risus et pretium hendrerit.
</Tab>
</Tabs>
</template>
<script setup>
import {ref } from 'vue'
import Tabs from './components/Tabs.vue'
import Tab from './components/Tab.vue'
const name =ref('Vue')
</script>
index.js
import {createApp} from "vue";
import App from "./App.vue";
const app = createApp(App);
app.mount("#app");
**Tab.vue**
<script setup>
import { ref, onMounted } from 'vue';
const props = defineProps([ 'active' ]);
</script>
<template>
<div class="tab" :class="(active == 'true') ? 'active' : ''" ref="tabs">
<slot></slot>
</div>
</template>
<style>
.tab {
display: none;
}
.tab.active {
display: block;
}
</style>
Tabs.vue
<script setup>
import { ref, onMounted, reactive } from 'vue';
const props = defineProps([ 'customClass' ]);
let tabContainer = ref(null);
let tabHeaders = ref(null);
let tabs = ref(null);
let activeTabIndex = ref(0);
onMounted(() => {
tabs.value = [ ...tabContainer.value.querySelectorAll('.tab') ];
for(let x of tabs.value) {
if(x.classList.contains('active')) {
activeTabIndex = tabs.value.indexOf(x);
}
}
})
const changeTab = (index) => {
activeTabIndex = index;
for(let x of [...tabs.value, ...tabHeaders.value]) {
x.classList.remove('active')
}
tabs.value[activeTabIndex].classList.add('active')
tabHeaders.value[activeTabIndex].classList.add('active')
}
</script>
<template>
<div id="tabs-container" :class="customClass" ref="tabContainer">
<div id="tab-headers">
<ul>
<!-- this shows all of the titles -->
<li v-for="(tab, index) in tabs" :key="index" :class="activeTabIndex == index ? 'active' : ''" @click="changeTab(index)" ref="tabHeaders">{{ tab.title }}</li>
</ul>
</div>
<!-- this is where the tabs go, in this slot -->
<div id="active-tab">
<slot></slot>
</div>
</div>
</template>
<style>
#tab-headers ul {
margin: 0;
padding: 0;
display: flex;
border-bottom: 2px solid #ddd;
}
#tab-headers ul li {
list-style: none;
padding: 1rem 1.25rem;
position: relative;
cursor: pointer;
}
#tab-headers ul li.active {
color: #008438;
font-weight: bold;
}
#tab-headers ul li.active:after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
height: 2px;
width: 100%;
background: #008438;
}
#active-tab, #tab-headers {
width: 100%;
}
#active-tab {
padding: 0.75rem;
}
</style>
这就是渲染的内容
在 youtube 上观看本教程我最终理解了解决方案。 您必须将构建的 .js 和 .css 文件转换为 .js.html 和 .css.html ,而不是直接推送构建结果,不仅要更改它们的扩展名,还要将它们的内容包含在脚本或样式标记中。本教程提供了执行此转换的gas.js。
此外,您还应该将index.html替换为该固定内容
<!DOCTYPE html>
<html>
<head>
<!-- <base target="_top"> -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>vuejs-gas-template</title>
<?!= include('vue/app.css') ?>
</head>
<body>
<div id="app"></div>
<?!= include('vue/manifest.js') ?>
<?!= include('vue/vendor.js') ?>
<?!= include('vue/app.js') ?>
</body>
</html>
当然,文件和文件夹的名称取决于您的应用程序使用的内容。 就我而言,我不再使用由包裹制成的样板,而是根据上面引用的教程使用另一种样板。