taro
taro copied to clipboard
Template `tmpl_0_View` not found.
相关平台
微信小程序
复现仓库
https://github.com/ccqgithub/taro-bug-repo.git 小程序基础库: 2.12.3 使用框架: Vue 3
复现步骤
使用vue3 setup导入组件
<script setup lang="ts">
import { View } from '@tarojs/components'
import './index.scss'
import Counter from '../../components/Counter.vue'
</script>
<template>
<View class="index">
<Counter />
</View>
</template>
报错:
[WXML Runtime warning] ./base.wxml
Template `tmpl_0_View` not found.
83 |
84 | <template name="tmpl_0_container">
> 85 | <template is="{{xs.a(0, i.nn, l)}}" data="{{i:i,cid:0,l:xs.f(l,i.nn)}}" />
| ^
86 | </template>
87 |
88 | <template name="tmpl_1_catch-view">
如果直接使用模版,element类型不正确,view被当成svg元素了

期望结果
- setup模式,import的组件能在template中使用
- 非setup模式,view元素类型提示正确
实际结果
报错
环境信息
Taro CLI 3.4.13 environment info:
System:
OS: macOS 12.4
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.1 - /usr/local/bin/node
npm: 8.11.0 - /usr/local/bin/npm
npmPackages:
@tarojs/components: 3.4.13 => 3.4.13
@tarojs/mini-runner: 3.4.13 => 3.4.13
@tarojs/runtime: 3.4.13 => 3.4.13
@tarojs/taro: 3.4.13 => 3.4.13
@tarojs/webpack-runner: 3.4.13 => 3.4.13
babel-preset-taro: 3.4.13 => 3.4.13
eslint-config-taro: 3.4.13 => 3.4.13
@ccqgithub Vue 中 Taro 内置组件需要小写:<view>
,Demo 对 <View>
的使用里是 Taro React 的用法,是不对的。
另外类型提示是怎么出现的?
@ccqgithub Vue 中 Taro 内置组件需要小写:
<view>
,Demo 对<View>
的使用里是 Taro React 的用法,是不对的。
vue3 setup 是可以用<View>
的,以后基本上都是用这种写法,最好能支持这种写法哦:https://vuejs.org/api/sfc-script-setup.html#using-components
另外类型提示是怎么出现的?
直接用小写<view>
就有这个类型提示,因为view
在vue本身的定义里是svg的子元素。除了<view>
之外,小写的标签很多类型提示都不正确,比如<scroll-view>
下面我的解决方案,现在是每个组件自己封装了一层使用,对taro的代码不是很熟,无法提PR,供参考
import { FunctionalComponent, CSSProperties, h } from 'vue';
import {
View,
ViewProps,
ScrollView,
ScrollViewProps,
Image,
ImageProps,
Text,
TextProps,
Button,
ButtonProps,
Input,
InputProps,
WebView,
WebViewProps,
Textarea,
TextareaProps,
BaseEventOrig,
StandardProps
} from '@tarojs/components';
export type {
ViewProps,
ScrollViewProps,
ImageProps,
TextProps,
StandardProps,
ButtonProps,
InputProps,
TextareaProps,
WebViewProps,
BaseEventOrig
};
type LowercaseKeys<O extends Record<string, any>> = {
[K in keyof O as Lowercase<string & K>]: O[string & K];
};
// get event keys from props
// { onClick: FN } => ['click']
type EventKeys<T> = NonNullable<
{
[K in keyof T]: K extends `on${infer E}` ? Uncapitalize<E> : never;
}[keyof T]
>;
// filter event properties
// { onClick: FN, other: any } => { click: FN }
type Events<T extends Record<string, any>> = {
[Key in EventKeys<T>]: Required<T>[`on${Capitalize<Key>}`];
};
// props => emits
// { onClick: FN } => { click: FN, tap: FN }
type PropsToEmits<P extends Record<string, any>> = Required<Events<P>>;
// https://github.com/NervJS/taro/blob/next/packages/taro-components/types/index.vue3.d.ts
// 联合类型不能用omit(比如picker)
type DistributiveOmit<T, K extends keyof T> = T extends unknown
? Omit<T, K>
: never;
type SlimProps = {
class?: any;
style?: CSSProperties;
innerHTML?: string;
// setRef?: (el: Element | null) => void;
};
/** 转换react的类型到vue */
type RemoveReactAttribute =
| 'className'
| 'style'
| 'key'
| 'ref'
| 'dangerouslySetInnerHTML';
export type TransformReact2VueType<
P extends Record<string, any> = Record<string, any>
> = DistributiveOmit<P, RemoveReactAttribute> & {
onTap?: P['onClick'];
} & SlimProps;
const createComponent = <
P extends Record<string, any>,
T = TransformReact2VueType<P>
>(
tag: any
) => {
return ((props, ctx) => {
return h(tag, { ...props, ...ctx.attrs }, ctx.slots);
}) as FunctionalComponent<T, LowercaseKeys<PropsToEmits<P>>>;
};
export * from './NPageMeta';
export const NView = createComponent<ViewProps>(View);
export const NImage = createComponent<ImageProps>(Image);
export const NText = createComponent<TextProps>(Text);
export const NScrollView = createComponent<ScrollViewProps>(ScrollView);
export const NButton = createComponent<ButtonProps>(Button);
export const NInput = createComponent<InputProps>(Input);
export const NTextArea = createComponent<TextareaProps>(Textarea);
export const NWebView = createComponent<WebViewProps>(WebView);
未使用ts的demo没发现这个问题
@ccqgithub
vue3 setup 是可以用<View>的,以后基本上都是用这种写法,最好能支持这种写法哦:https://vuejs.org/api/sfc-script-setup.html#using-components
Vue 组件才可以大写,<view>
相当于 H5 的 <div>
,属于原生标签是不可以的。
直接用小写
就有这个类型提示,因为view在vue本身的定义里是svg的子元素。除了 之外,小写的标签很多类型提示都不正确,比如
感觉是不是装了什么 VSCode 插件后提供的类型提示,你可以点进去类型跟踪是哪个文件导出的类型。目测是一个全局类型,那么你可以通过 TS 的模块补全去修改这个全局类型来解决。
@ccqgithub
vue3 setup 是可以用的,以后基本上都是用这种写法,最好能支持这种写法哦:https://vuejs.org/api/sfc-script-setup.html#using-components
Vue 组件才可以大写,
<view>
相当于 H5 的<div>
,属于原生标签是不可以的。直接用小写就有这个类型提示,因为view在vue本身的定义里是svg的子元素。除了之外,小写的标签很多类型提示都不正确,比如
感觉是不是装了什么 VSCode 插件后提供的类型提示,你可以点进去类型跟踪是哪个文件导出的类型。目测是一个全局类型,那么你可以通过 TS 的模块补全去修改这个全局类型来解决。
不是插件的问题,这是vue 的类型提示,原因是vue是针对web标准开发的,所以它内置的类型都是正当html标签的。当小程序的标签跟html的标签重叠但是功能不一样时,就会有问题。
react如果直接使用标签不使用组件的话应该也会有类似的问题。
重新定义vue的类型提示可是可以就是比较麻烦,react可以用组件的方式解决,是不是vue也可以呢?
遇到一样的问题,很糟心
遇到类似错误,我是
<template>
<Navbar hideBack />
<view :class="styles.container">
<text>{{ greeting }}</text>
<Button type="primary" >nutui</Button>
</view>
</template>
<script lang="ts" setup>
import Navbar from '@/components/navbar';
import { Button } from "@nutui/nutui-taro";
import styles from './styles.scss';
const greeting = 'Hello world';
</script>
button 渲染不出来,控制台警告错误:
[WXML Runtime warning] ./base.wxml
Template `tmpl_0_Button` not found.
<template name="tmpl_1_container">
@yijinc Button 是内置组件,改为 NutButton 吧:import { Button as NutButton } from "@nutui/nutui-taro"
在开启了 Volar 等开发者工具插件后,Vue SFC template 能够得到类型提示。原问题修改全局的 IntrinsicElements
可以解决, @ZakaryCode 有空可以看看
import {
ViewProps
} from '@tarojs/components'
declare global {
namespace JSX {
interface IntrinsicElements {
view: ViewProps
}
}
}
@ZakaryCode 解决了? 我这边 windows 3.5.4版本还是有这个问题
@ZakaryCode 解决了? 我这边 windows 3.5.4版本还是有这个问题
PR 还没有合入,等下一个版本咯
3.6.5 版本开启 webpack5 的 cache 功能稳定复现,关了就好了
看了半天 没看懂咋解决啊